C语言高频面试题及详细答案(企业真实版)_第1页
C语言高频面试题及详细答案(企业真实版)_第2页
C语言高频面试题及详细答案(企业真实版)_第3页
C语言高频面试题及详细答案(企业真实版)_第4页
C语言高频面试题及详细答案(企业真实版)_第5页
已阅读5页,还剩1页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言高频面试题及详细答案(企业真实版)一、C语言基础概念题1、简述C语言变量的作用域和生命周期答案:变量作用域指变量可以被访问的代码范围,生命周期指变量在内存中存在的时间。1.局部变量:定义在函数或代码块内部,作用域仅限当前代码块,程序执行到代码块时开辟内存,执行结束立即释放,生命周期随代码块结束终止,未初始化时是随机脏值。2.全局变量:定义在所有函数外部,作用域覆盖整个源文件,可通过extern跨文件访问,程序启动分配内存,程序退出才释放,默认初始值为0。3.静态局部变量(static修饰):作用域仍为局部,但是生命周期和全局变量一致,程序运行期间一直存在,只会初始化一次,保留上一次的值。2、const关键字的用法和作用答案:const用来修饰只读变量,禁止修改变量的值,主要四种常用场景:1.constinta;修饰普通变量,变量a只读,不能赋值修改。2.constint*p;指针指向的值不可改,指针本身的地址可以改,常用于函数参数,保护数据不被篡改。3.int*constp;指针地址不可改,指向的数据可以修改。4.constint*constp;指针地址和指向的数据都不可修改。额外作用:编译器会对const变量做优化,节省内存,同时代码可读性更高,明确常量不可修改的特性。3、#define和const的区别答案:1.处理阶段不同:#define是预处理指令,预处理阶段直接文本替换,不做类型检查;const是变量定义,编译阶段处理,有严格的数据类型校验。2.类型区别:#define无数据类型,只是纯文本替换;const是有固定类型的常量。3.内存占用:#define不占用内存,只是替换文本;const常量会占用内存空间。4.作用域:#define作用域从定义处到文件结尾,可通过#undef取消;const遵循变量作用域规则。5.调试性:const变量可调试查看值,#define无法调试。二、指针核心高频题(面试重点)1、指针和数组的区别,为什么数组名可以当指针用答案:数组名本质是数组首元素的常量指针,指向数组第一个元素的地址,所以可以直接用数组名做指针运算。核心区别:1.存储空间:数组是连续的内存空间,存放具体数据;指针是一个变量,仅存放地址,占用4字节(32位)/8字节(64位)内存。2.可修改性:数组名是常量,不能赋值、不能自增自减;指针变量可以随意修改指向。3.sizeof结果:sizeof(数组名)得到数组总字节数;sizeof(指针)永远是指针本身大小。4.传参区别:数组作为函数参数会退化为指针,丢失数组长度信息;独立指针传参始终是地址传递。2、*p++、(*p)++、*++p的区别答案:核心看运算符优先级:自增优先级高于解引用,括号优先级最高。1.*p++:先取p指向的值,再让指针p向后偏移一位。日常遍历数组最常用。2.(*p)++:取p指向的值,然后该数据本身自增1,指针地址不变。3.*++p:指针p先向后偏移一位,再取新地址对应的值。3、野指针是什么?如何避免野指针答案:野指针就是指向未知、非法、未授权内存的指针,没有明确指向地址,也不是空指针。产生原因:指针未初始化、指针指向的内存释放后未置空、指针越界访问。危害:程序崩溃、段错误、内存踩踏、随机异常bug,极难排查。避免方法:1.指针定义时直接初始化为NULL;2.动态内存free后,立即将指针置为NULL;3.使用指针前先判断指针是否为NULL;4.严格控制指针访问范围,避免数组、内存越界。三、内存管理专题(笔试必考)1、C语言四大内存分区及特点答案:1.代码段:存放程序编译后的二进制指令,只读,程序运行期间固定不变。2.数据段:分为初始化数据段、未初始化数据段。存放全局变量、static静态变量,程序启动分配内存,退出释放。3.栈区:存放局部变量、函数参数、函数返回地址。系统自动分配、自动释放,空间小、速度快,栈溢出会导致程序崩溃。4.堆区:由程序员手动管理,通过malloc、calloc、realloc申请,free释放。空间大、灵活,生命周期由程序员决定,不手动释放会造成内存泄漏。2、malloc、calloc、realloc的区别答案:1.malloc:申请指定大小的堆内存,不初始化,内存是随机脏值,参数为单个内存总字节数。2.calloc:申请n个大小为size的内存,自动初始化为0,参数是个数+单块大小,适合数组内存申请。3.realloc:重新调整已申请堆内存的大小,可扩容、可缩容。扩容时若原内存后有空闲空间,直接追加;若无,会重新开辟新内存、拷贝数据、释放旧内存。注意:动态内存使用完必须free,否则内存泄漏;free后的内存不能重复释放,会造成双重释放错误。3、什么是内存泄漏?如何排查和避免答案:内存泄漏指堆区动态申请的内存,使用完毕后没有手动free,程序结束前一直占用内存,导致系统可用内存越来越少。常见场景:函数内申请堆内存,没有返回释放入口、异常分支跳过free、指针覆盖丢失内存地址。避免方式:谁申请谁释放、成对使用malloc和free、异常场景也要保证内存释放、不用的指针及时置空。排查方式:Linux下可使用valgrind工具检测内存泄漏、越界访问问题。四、字符串与数组面试题1、char*str和charstr[]的区别答案:1.存储位置:charstr[]是局部数组,内存开辟在栈区;char*str是指针,指向字符串常量区的只读字符串。2.修改权限:charstr[]内容可修改;char*str指向的常量字符串不可修改,修改会触发段错误。3.sizeof大小:charstr[]大小为字符串长度+1(包含结束符\0);char*str大小为指针本身大小。4.可重赋值:char*str可以修改指向;数组名str是常量,不能整体赋值。2、C语言字符串结束符\0的作用答案:C语言没有专门的字符串类型,字符串本质是字符数组,依靠\0(ASCII值0)标记字符串结束。所有字符串函数(printf、strlen、strcpy)都会以\0作为终止依据,没有\0会导致函数一直向后读取内存,造成内存越界、乱码、程序崩溃。strlen计算长度不包含\0,sizeof计算数组长度包含\0。五、结构体、枚举、联合体1、结构体结构体对齐规则,什么是内存对齐答案:内存对齐是编译器为了提高CPU读取效率,对结构体成员内存地址做对齐填充的机制,CPU一次性读取对齐内存数据更快。对齐规则:1.每个成员的偏移地址,必须是自身大小的整数倍;2.结构体整体大小,必须是最大成员大小的整数倍;3.不足的位置编译器自动填充空字节。可以通过#pragmapack(n)手动修改对齐模数,减少结构体内存占用,嵌入式开发常用。2、结构体和联合体的区别答案:1.内存存储:结构体成员独立占用内存,总大小是所有成员大小+对齐填充;联合体成员共用同一块内存,同一时间只能存储一个成员数据。2.大小区别:结构体整体空间更大;联合体大小为最大成员的大小。3.使用场景:结构体用于存储一组关联的不同类型数据;联合体用于节省内存、数据类型转换(嵌入式寄存器读写常用)。六、函数与易错编程题1、形参和实参的区别,值传递和地址传递答案:实参:调用函数时传入的真实数据,存在于主调函数;形参:函数定义时的参数,是实参的临时副本,存在于被调函数。值传递:传递变量本身的值,形参修改不会影响实参,适合简单数据;地址传递(指针传递):传递变量地址,通过指针可以修改原变量数据,适合大数、数组、结构体传参,节省内存。2、递归函数的优缺点,递归必备条件答案:递归必备两个条件:递归终止条件、递归递推公式,缺少终止条件会无限递归,栈溢出崩溃。优点:代码简洁,逻辑清晰,适合树、链表、分治算法场景。缺点:递归每次调用都会开辟栈帧,占用栈内存,效率低于循环,层数过多容易栈溢出。七、经典错题解析1、局部变量能否用static修饰?有什么变化答案:可以修饰。普通局部变量在栈区,函数结束释放;static局部变量存放在数据段,程序运行期间常驻内存,只初始化一次,下次调用函数会保留上一次的值。作用域不变,仍然只能在当前函数内访问。2、全局变量和静态全局变量的区别

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论