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

下载本文档

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

文档简介

C语言常见面试题及详细答案(实战版)一、C语言基础概念高频题1、简述C语言中static关键字的作用static是C语言核心关键字,主要有三个作用,分场景使用:第一,修饰局部变量。普通局部变量函数调用结束后会销毁,被static修饰后,变量内存会一直保留,程序运行期间不销毁,下次调用函数会沿用上次的值,只会初始化一次。第二,修饰全局变量。普通全局变量可以跨文件访问,static修饰后,该全局变量仅限当前源文件使用,其他文件无法引用,实现文件级别的私有化。第三,修饰函数。普通函数可以被外部文件调用,static修饰后,函数仅当前文件可见、可用,限制函数作用域,避免多文件函数名冲突。2、const关键字的作用是什么?常用场景有哪些const的核心作用是修饰变量为只读不可修改,编译阶段会校验修改行为,防止误改数据,同时可优化编译器编译效率。常见使用场景:1.修饰普通变量:constinta=10;变量a无法二次赋值修改。2.修饰指针:分两种核心情况,const修饰指针变量指向的数据,数据不可改、指针可偏移;const修饰指针本身,指针地址不可改、数据可修改。3.修饰函数参数:防止函数内部误修改传入的实参数据,常用在字符串、数组传参场景。4.修饰函数返回值:避免返回值被意外修改,提升代码安全性。3、#define和const的区别1.处理阶段不同:#define是预处理指令,预处理阶段直接文本替换,无类型检查;const是变量修饰符,编译阶段处理,有严格的数据类型校验。2.类型差异:宏定义无数据类型,const常量有明确数据类型(int、char等)。3.作用域不同:#define全局生效,无作用域限制;const常量遵循变量作用域规则,局部const仅函数/代码块内有效。4.调试性不同:宏定义无法调试,预处理后直接替换消失;const常量是真实变量,可断点查看数值。5.内存占用:宏定义不占用内存,只是文本替换;const常量会占用对应类型的内存空间。4、全局变量和局部变量的区别1.定义位置:全局变量定义在所有函数外部;局部变量定义在函数、代码块内部。2.作用域:全局变量整个程序所有文件、所有函数都可访问;局部变量仅当前函数/代码块内有效,出作用域失效。3.生命周期:全局变量程序启动分配内存,程序结束销毁;局部变量进入作用域分配内存,退出立即释放。4.初始化值:全局变量默认自动初始化为0;局部变量默认是随机垃圾值,必须手动初始化。5.内存分区:全局变量存放在全局数据区;局部变量存放在栈区。二、指针核心面试题(重中之重)1、指针的本质是什么?野指针和空指针的区别指针本质就是存放内存地址的变量,和普通变量的区别是存储的数据是内存地址,而非数值。空指针:赋值为NULL(0地址)的指针,指向系统禁止访问的地址。空指针是合法指针,目的是标识指针未指向有效内存,可通过if判断规避风险。野指针:未初始化、指向随机未知内存地址的指针。属于非法指针,没有固定指向,随意解引用会导致程序崩溃、内存越界,是代码bug主要来源之一。规避方式:指针定义时初始化为NULL,使用前判空,释放内存后及时置空。2、*p、**p、p++、(*p)++的区别1.*p:解引用指针p,取出p指向内存地址中存储的数据。2.**p:二级指针,p是指向一级指针的指针,用于存储一级指针的地址,常用在动态内存二级数组、函数修改一级指针场景。3.p++:指针地址自增,根据指针类型偏移对应字节数,比如int*指针+1偏移4字节,char*+1偏移1字节,指针指向位置后移。4.(*p)++:指针指向的数据自增,指针本身的地址不变,只是地址内的数值加1。3、数组名和指针的区别很多人误以为数组名就是指针,实际二者有本质区别:1.属性不同:数组名是数组首元素的地址常量,不可修改;指针是地址变量,可以修改指向。2.sizeof计算结果不同:sizeof(数组名)得到整个数组的总内存大小;sizeof(指针)固定得到4字节(32位系统)/8字节(64位系统)。3.取值特性:数组名每次使用都是固定首地址;指针可以自由赋值、偏移、修改指向。4.传参差异:数组作为函数参数时,会退化为指针,此时sizeof无法获取数组真实长度,只能得到指针大小。4、指针数组和数组指针的区别核心口诀:看括号,括号跟数组是数组指针,括号跟指针是指针数组1.指针数组:char*arr[5];本质是数组,数组的每个元素都是char类型指针,多用于存储多个字符串。2.数组指针:char(*p)[5];本质是指针,专门指向长度为5的字符数组,多用于操作二维数组。三、内存管理高频题1、C语言四大内存分区及各自特点C语言程序运行时内存主要分为栈区、堆区、全局/静态区、常量区:1.栈区:存放局部变量、函数形参、函数返回地址。由系统自动分配、自动释放,空间小、速度快,超出作用域立即释放,栈溢出会导致程序崩溃。2.堆区:存放malloc、calloc、realloc动态申请的内存。由程序员手动申请、手动free释放,空间极大、灵活度高,不主动释放会造成内存泄漏。3.全局/静态区:存放全局变量、static修饰的静态变量。程序启动分配内存,程序结束统一释放,生命周期贯穿整个程序运行过程。4.常量区:存放字符串常量、const修饰的只读常量。内存只读,不可修改,修改会触发程序报错。2、malloc、calloc、realloc的区别1.malloc:动态申请指定字节的堆内存,不会初始化内存,内存中是随机垃圾值,参数只需要内存大小。2.calloc:申请n个指定大小的内存块,自动初始化为0,需要两个参数:元素个数、单个元素大小,适合需要初始化的场景。3.realloc:重新调整已申请堆内存的大小,可扩容、可缩容。扩容时若原内存后方空间充足,直接原地扩容;空间不足会重新开辟新内存,拷贝旧数据,释放旧内存。通用注意点:动态内存使用完必须free,释放后需将指针置NULL,避免野指针和内存泄漏。3、什么是内存泄漏?如何避免内存泄漏指:动态申请的堆内存,程序运行结束前没有手动free释放,这块内存一直被程序占用,系统无法回收,长期累积会导致程序占用内存越来越大,最终卡顿、崩溃。避免方法:1.遵循谁申请、谁释放的原则,malloc和free成对出现;2.函数内申请的堆内存,需要返回给外部使用时,做好释放提醒;3.内存释放后立即将指针置空,避免二次释放、野指针问题;4.程序分支、异常退出场景,确保所有动态内存都能执行到free逻辑。四、函数与结构体面试题1、形参和实参的区别1.实参:调用函数时,传入的真实数据、变量、常量,是实际参与运算的值,定义在主调函数中。2.形参:函数定义时括号内的参数,是函数的形式参数,仅作占位符,定义在被调函数中。3.传递规则:C语言默认值传递,形参是实参的拷贝,函数内部修改形参的值,不会影响外部实参;如果需要修改实参,必须传递指针地址。2、结构体结构体对齐原则、为什么需要内存对齐结构体对齐核心规则:1.每个成员的偏移地址,必须是自身大小的整数倍;2.结构体整体大小,必须是结构体中最大基本数据类型的整数倍;3.可以通过#pragmapack(n)手动修改对齐模数。内存对齐原因:硬件读取内存时,是按固定字节块读取(4字节/8字节),未对齐的内存需要多次读取、拼接数据,效率极低。内存对齐可以提升CPU数据读取效率,适配硬件读写规则。3、结构体和联合体的区别1.内存存储:结构体成员独立占用内存,总大小是所有成员对齐后的总和;联合体所有成员共用同一块内存,总大小等于最大成员的大小。2.使用特性:结构体所有成员可同时赋值、访问;联合体同一时间只能使用一个成员,赋值新成员会覆盖旧成员数据。3.应用场景:结构体用于存储一组关联的不同类型数据;联合体多用于数据类型转换、节省内存的场景(硬件编程、协议解析常用)。五、易错语法与程序逻辑面试题1、if和else的匹配规则C语言中,else永远和离它最近、未配对的if匹配,和缩进无关。很多新手会被缩进误导导致逻辑错误,建议写代码时统一加花括号包裹代码块,避免匹配错乱。2、switch语句的break作用,不加break会怎样break的作用是跳出当前switch分支,结束switch判断。如果case后不加break,会发生case穿透:匹配到对应case执行代码后,不会跳出,会继续顺序执行后续所有case的代码,直到遇到break或switch结束。部分场景可利用穿透简化代码,常规场景必须加break。3、数组越界的危害C语言不会校验数组下标合法性,数组下标超出定义范围就是数组越界。危害:越界访问会读写未知内存空间,可能修改其他变量数据、破坏栈内存布局,导致程序随机崩溃、段错误、数据异常,且bug隐蔽,极难排查。4、return0和return-1的区别在主函数main中:return0表示程序正常结束、执行成功,系统默认接收成功状态码;return-1表示程序异常退出、执行失败,用于告知系统程序运行出错。自定义函数中:可自定义返回值含义,通常0代表成功,非0(-1、1等)代表失败、异常。六、字符串与预处理面试题1、strlen和sizeof的区别1.本质不同:strlen是库函数,需要引用string.h头文件;sizeof是C语言关键字,编译阶段执行,无需头文件。2.计算规则:strlen计算字符串有效字符长度,不包含结束符'\0',遇到'\0'停止计数;sizeof计算数据整体占用的内存字节数,包含结束符、冗余内存。3.适用场景:strlen仅用于字符串;sizeof可计算变量、数组、结构体、指针等所有数据类型的内存大小。2、#include<>和#include""的区别1.#include<>:优先从系统库头文件目录查找,用于引入系统标准头文件(stdio.h、string.h等),查找速度快。2.#include"":优先从当前项目源码目录查

温馨提示

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

评论

0/150

提交评论