C语言基础面试问答
结构体相关
Q: 什么是结构体?它与数组有什么区别? A: 结构体是C语言中用户自定义的数据类型,可以将不同类型的数据组合在一起。与数组的区别在于:数组存储相同类型的数据,通过下标访问;结构体存储不同类型的数据,通过成员名访问。结构体更适合表示复杂的数据实体,如学生信息、员工记录等。
Q: 结构体内存对齐是什么?为什么需要内存对齐? A: 内存对齐是指结构体成员在内存中的存储位置按照特定规则排列。需要对齐的原因:1)提高CPU访问效率,减少内存访问次数;2)某些硬件平台要求特定数据类型必须存储在特定边界上。对齐规则通常是:成员的偏移量必须是该成员大小的整数倍,结构体总大小必须是最大成员大小的整数倍。
联合体相关
Q: 联合体和结构体有什么区别? A: 联合体的所有成员共享同一块内存空间,任何时候只能存储其中一个成员的值;而结构体的每个成员都有独立的内存空间。联合体的大小等于最大成员的大小,结构体的大小是所有成员大小之和(考虑对齐)。联合体主要用于节省内存空间或实现数据的不同解释方式。
Q: 联合体的典型应用场景有哪些? A: 1)节省内存:当多个变量不会同时使用时;2)数据类型转换:将同一数据按不同类型解释;3)位域操作:方便访问数据的不同部分;4)网络编程:处理大小端转换;5)嵌入式系统:寄存器的不同位域访问。
枚举相关
Q: 枚举类型的作用和优势是什么? A: 枚举提供了一种定义常量集合的方式,优势包括:1)增强代码可读性,用有意义的名称代替数字;2)便于维护,集中定义相关常量;3)编译时检查,避免使用无效值;4)自动赋值,减少手工错误;5)限定取值范围,提高程序安全性。
Q: 枚举变量的存储大小是多少? A: 枚举变量通常以int类型存储,占用4个字节(在大多数系统上)。但编译器可能会优化,根据枚举值的范围选择更小的存储类型。可以通过sizeof运算符获取具体大小。枚举值本质上是整数常量,可以与整数进行比较和运算。
链表相关
Q: 链表相比数组有什么优缺点? A: 优点:1)动态分配内存,大小可变;2)插入删除操作效率高,时间复杂度O(1);3)内存利用率高,按需分配。缺点:1)随机访问效率低,必须顺序查找;2)需要额外存储指针,内存开销大;3)缓存局部性差,访问性能相对较低;4)容易出现内存泄漏问题。
Q: 如何检测链表中是否有环? A: 使用快慢指针法(Floyd环检测算法):设置两个指针,慢指针每次移动一步,快指针每次移动两步。如果链表有环,快指针最终会追上慢指针;如果没有环,快指针会先到达链表末尾。这种方法时间复杂度O(n),空间复杂度O(1),是最优解法。
环形队列相关
Q: 环形队列的优势是什么?如何判断队列空和满? A: 优势:1)有效利用存储空间,避免假溢出;2)支持循环使用缓冲区;3)适合生产者-消费者模型。判断空满状态:通常有两种方法:1)牺牲一个存储单位,当(rear+1)%size == front时为满,rear == front时为空;2)增加计数器变量,通过计数判断空满状态。
Q: 环形队列适用于什么场景? A: 1)操作系统的进程调度队列;2)网络数据包缓冲;3)音视频流处理的缓冲区;4)嵌入式系统的数据采集;5)多线程编程的生产者消费者问题;6)实时系统的事件处理队列。这些场景都需要高效的FIFO数据结构和固定大小的缓冲区。
指针相关
Q: 函数指针和指针函数有什么区别? A: 函数指针是指向函数的指针变量,可以通过它调用不同的函数,语法为"返回类型 (指针名)(参数列表)"。指针函数是返回指针的函数,函数的返回值是指针类型,语法为"返回类型 函数名(参数列表)"。前者是变量,后者是函数;前者用于实现函数的动态调用,后者用于返回地址。
Q: 指针数组和数组指针的区别? A: 指针数组是数组的每个元素都是指针,如"int *arr[10]",表示10个int指针的数组。数组指针是指向数组的指针,如"int (*ptr)[10]",表示指向包含10个int元素数组的指针。区别在于:指针数组是多个指针的集合,数组指针是单个指向数组的指针;前者用于存储多个地址,后者用于指向整个数组。
Q: 野指针和空指针有什么区别?如何避免? A: 野指针是指向未知内存区域的指针,可能指向已释放的内存或未初始化的内存;空指针是值为NULL的指针,明确表示不指向任何有效内存。避免方法:1)指针定义时初始化为NULL;2)释放内存后将指针设为NULL;3)使用前检查指针是否为NULL;4)避免返回局部变量的地址;5)使用静态分析工具检查代码。
Q: 指针运算有哪些?需要注意什么? A: 指针运算包括:1)指针加减整数:移动指定个数的数据单位;2)指针相减:计算两指针间的元素个数;3)指针比较:比较地址大小;4)指针递增递减:移动到下一个或上一个元素。注意事项:1)只能对同类型或兼容类型指针运算;2)指针运算以数据类型大小为单位;3)越界访问会导致未定义行为;4)空指针不能进行算术运算。