当前位置: 首页 > article >正文

【C语言软开面经】

C语言软开面经

  • malloc calloc realloc free动态分配内存
    • malloc
    • calloc函数:
    • realloc 函数:
    • free函数:
  • 堆栈-内存分区
    • 栈区(Stack):
    • 堆区(Heap):
    • 全局(静态)区:
    • 常量区:
    • 代码区:
  • void* 大小
  • float精度
  • 虚函数和纯虚函数
  • socket编程
  • 阻塞、非阻塞、同步、异步
  • 多线程
  • 编写一个strcpy函数

malloc calloc realloc free动态分配内存

头文件:
#include<stdlib.h>

malloc

头文件:
#include<stdlib.h> 或者 #include<malloc.h>

malloc函数:
void * malloc(unsigned int num_byte);
功能:分配长度为num_byte字节的内存块
入参:需要分配的内存字节数
返回值:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
注意事项:
1、申请了内存空间后,必须检查是否分配成功。
2、当不需要再使用申请的内存时,记得free,否则会内存泄露;
3、虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。
4、malloc只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。如果需要都初始化为0可以用calloc
5、一般参数传递的形式为(sizeof(要开辟的类型如int)*要开辟的个数).也可以直接写字节数
malloc申请内存有8字节对齐不一定申请多少就分配多少是 分配>=申请

calloc函数:

void* calloc (size_t num, size_t size);

第一个参数的类型是无符号整型(size_t),它表示需要动态开辟的元素的个数.
第二个参数的类型是无符号整型(size_t),它表示需要开辟的每个元素的大小(以字节为单位).
返回值:与malloc相同,如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

realloc 函数:

函数原型:
void* realloc(void* memblock, size_t size)
memblock 需要进行扩容的指针
size 扩容后的大小,字节单位
返回与malloc相同,如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

realloc如何让扩容:
realloc可以扩大或缩小原来已经malloc的内存空间,realloc是从堆上分配内存的.当扩大一块内存空间时,realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,原地扩容 这样扩容后指针首地址不变;
如果数据后面的字节不够,异地扩容,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.这句话传递的一个重要的信息就是数据可能被移动.

关于free释放:内存经过malloc,再realloc后,如果是扩大内存,只需释放realloc的内存,不用再释放malloc的了。如果是缩小内存,则释放malloc的,不释放realloc的,

使用realloc进行缩容:
缩的仅仅只是使用权限,空间还是没有减少的
在这里插入图片描述

free函数:

void free( void * pointer);
功能:释放内存
参数:free函数的参数要么是NULL,要么是一个先前从malloc、calloc或realloc返回的值。向free传递一个NULL参数不会产生任何效果。所以一般释放malloc分配的指针后会将指针指向NULL,因为释放两次或出现错误释放空指针等于啥都没做。
返回值:无

堆栈-内存分区

堆和栈的区别-内存分区

栈区(Stack):

1.由编译器自动分配和释放
2.利用栈存储一些临时变量,包括函数形参、函数内部局部变量、返回值等
3.栈的操作遵循“后进先出”(LIFO)的原则

堆区(Heap):

1.由程序员手动分配和释放的储存区
2.堆在内存中位于bss区和栈区之间
3.通过调用函数如malloc()、calloc()或realloc()来从堆中分配内存
4.必须手动调用free()函数来释放堆内存,否则可能导致内存泄漏

全局(静态)区:

1.内存分配在程序编译之前完成,且在程序的整个运行期间都存在
2.存储全局变量和静态变量
3.静态内存区细分还可以分成:.data段和.bss段
data段:初始化的全局变量、静态变量和只读数据都存放在这个域。
bss段:未初始化的全局变量和静态变量。
未初始化的变量,是在程序中说明,在运行的初始化阶段,才会真正占用存储空间,它的大小不会影响目标文件的大小。总结,一些变量放在bss段,可以减小目标文件的占用空间。

常量区:

1.常量存储区用于存储常量数据,如字符串常量,const修饰的变量
2.常量存储区通常位于静态存储区内

代码区:

1.通常是用来存放程序执行代码的一块内存区域
2.该区域的大小在程序运行前就已经确定,并且内存区域通常属于只读

void* 大小

不管什么类型的指针都是
sizeof(int*)=sizeof(char*)=sizeof(void*)=8
32 位编译环境下,是4 字节
64 位编译环境下,是8 字节

float精度

Float的存储结构
一个浮点数(Floating Point Number)由三个基本成分构成:

符号位(Sign)(占1位)

偏移指数位(阶码、指数)(Exponent)(占8位)
尾数位(Mantissa)(占23位):就是小数点后面的那些小数

float只能保证至少7位(包括整数部分和小数部分)有效数字准确
C语言中的float(单精度浮点数)

float的精度和取值范围

虚函数和纯虚函数

C++相关 不过多阐述
定义一个函数为虚函数,不代表函数为不被实现的函数。

定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。

定义一个函数为纯虚函数,才代表函数没有被实现。

定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

socket编程

套接字(socket) 是 Linux 下的一种进程间通信机制(socket IPC),使用 socket IPC 可以使得在不同主机上的应用程序之间进行通信(网络通信),也可以是同一台主机上的不同应用程序。socket IPC 通常使用客户端<—>服务器这种模式完成通信,多个客户端可以同时连接到服务器中,与服务器之间完成数据交互。

Socket 编程基础

阻塞、非阻塞、同步、异步

同步:
所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件做完了才能做下一件事。
例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事

异步:
异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
例如 ajax请求(异步): 请求通过事件触发->服务器处理(这时浏览器仍然可以做其他事情)->处理完毕

阻塞:
阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。

有人也许会把阻塞调用和同步调用等同起来,实际上它们是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。 例如,我们在socket中调用recv函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息。

非阻塞:
非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

多线程

多线程

编写一个strcpy函数

函数原型:char* strcpy( char* destination , const char* source) //将source复制到destination
头文件:#include<string.h>
返回值:返回的是第一个目的数字的首地址,类型为char*

注意:
1.strcpy遇到 ‘\0’ 时停止,会将 ‘\0’ 复制到目的数组中,所以源数组里面要有 ‘\0’
2.目的数组的大小>=源数组,否则可能会造成缓冲溢出的错误情况

#include<assert.h>
#include<stdio.h>

char* my_strcpy(char* dest, const char* src)//const在* 前面,使不再有 *src被改变的风险
{
	assert(dest != NULL);
	assert(src != NULL);

	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[] = "***************";
	char arr2[] = "abcdefg";
	my_strcpy(NULL, arr2);
	printf("%s", arr1);
	return 0;
}


http://www.kler.cn/news/326519.html

相关文章:

  • pdf提取文字:分享3款pdf文字提取软件,赶快收藏起来!
  • Unity开发绘画板——03.简单的实现绘制功能
  • 配置ssh后又报错git@github.com: Permission denied (publickey)
  • Linux【基础指令汇总】
  • 论文翻译 | LLaMA-Adapter :具有零初始化注意的语言模型的有效微调
  • SpringBoot+Thymeleaf发票系统
  • 【2025】springboot基于微信小程序记账本的设计与实现(源码+文档+调试+答疑)
  • kafka集群跨双网段及多网段通信问题解决(避免踩坑)
  • 享元(轻量级)模式
  • Spring Boot 进阶- Spring Boot入门程序详解
  • 初始docker以及docker的基本使用!!!
  • Cannon-es.js之Distance Constrait模拟布料
  • 【hot100-java】【合并两个有序链表】
  • MySQL数据库备份详解
  • Ubuntu下安装向日葵:闪退
  • SpirngBoot核心思想之一IOC
  • Leetcode 46 Permutation Leetcode 78 Subsets
  • AndroidStudio依赖报错
  • 力扣(leetcode)每日一题 1014 最佳观光组合
  • Android 开启相机一键拍照,一键录制
  • VirtualService和destinationRule
  • 大数据毕业设计选题推荐-国潮男装微博评论数据分析系统-Hive-Hadoop-Spark
  • Ranger集成CDH6.3.1详细步骤
  • 『功能项目』下载Mongodb【81】
  • C++中string的使用
  • ​​乐​​牛一​面​​​游​​卡​​一​二​​​​面​
  • 什么是IPv6
  • vue中使用jsencrypt加密
  • 超声波清洗机哪家好用又实惠?2024热门超声波清洗机选择推荐!
  • 工作笔记20240927——vscode + jlink调试