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

下载本文档

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

文档简介

C语言高频面试题库及详细答案(企业真实面试版)一、C语言基础语法面试题1、简述C语言变量的作用域和生命周期答案:变量作用域指变量可以被访问的代码范围,生命周期指变量在内存中存在的时间,二者是完全不同的概念,C语言中变量主要分三类:1.局部变量(自动变量)作用域:仅定义所在的代码块(函数、大括号范围内),出大括号无法访问。生命周期:程序执行到代码块时开辟内存,代码块执行结束立即释放内存。特点:默认无初始值,值随机,存储在栈区。2.全局变量作用域:整个源文件,其他源文件可通过extern声明后访问。生命周期:程序启动开辟内存,程序结束才释放,全程常驻内存。特点:默认初始值为0,存储在全局/静态区。3.静态变量(static修饰)局部静态变量:作用域仅限当前代码块,生命周期和程序一致,只会初始化一次,下次调用沿用上次值。全局静态变量:作用域仅限当前源文件,无法被其他文件调用,生命周期同全局变量。2、const关键字的作用,分别修饰变量、指针的区别答案:const核心作用是只读修饰,被修饰的内容无法被修改,编译阶段会做校验,防止误修改数据。1.const修饰普通变量:变量变为只读,不能赋值修改,如constinta=10;后续无法修改a的值。2.const修饰指针(核心区分记忆)-constint*p:指针指向的值不可改,指针本身地址可以改(指向可变,值不变)-int*constp:指针本身地址不可改,指向的值可以改(地址不变,值可变)-constint*constp:地址和指向的值都不可修改,完全只读。3、#define和const的区别答案:1.处理阶段不同:#define是预编译阶段简单文本替换,无类型检查;const是编译阶段处理,有严格数据类型校验。2.类型差异:宏定义无数据类型,const变量有明确数据类型。3.作用域不同:宏定义默认从定义处到文件结尾,无作用域限制;const变量遵循变量作用域规则。4.内存占用:宏定义不占用内存,只是文本替换;const变量会占用对应内存空间。5.调试性:宏定义无法调试,const变量可正常断点调试。4、static关键字的三大作用答案:1.修饰局部变量:延长变量生命周期至程序结束,变量只初始化一次,保留上次运行结果。2.修饰全局变量:限制作用域,仅当前源文件可访问,杜绝跨文件调用,避免全局变量冲突。3.修饰函数:将函数变为内部函数,仅当前文件可调用,其他文件无法引用,实现函数私有化。二、指针核心面试题(必考)1、指针和数组的区别,数组名的本质是什么答案:数组名本质:数组名是数组首元素的地址常量,代表首元素地址,不可被赋值修改。指针与数组核心区别:1.存储内容不同:数组是连续内存空间,存储具体数据;指针是一个变量,仅存储内存地址。2.大小不同:sizeof(数组名)得到数组总字节数;sizeof(指针)固定为4字节(32位系统)/8字节(64位系统)。3.可修改性:数组名是地址常量,不能赋值;指针变量可随意修改指向的地址。4.访问方式:数组通过下标直接访问连续内存;指针通过地址偏移访问内存,用法互通但本质不同。补充:数组作为函数参数时,会退化为指针,此时sizeof获取的是指针大小,而非数组大小。2、野指针是什么?如何避免野指针答案:野指针定义:指向未知、非法、不受系统管控内存地址的指针,指针指向的地址不确定,不是空指针。野指针产生原因:1.指针未初始化,局部指针变量默认值随机;2.指针指向的内存释放后,未置空,指针变成野指针;3.指针操作越界,指向数组、变量内存之外的空间。规避方法:1.指针定义时主动初始化,不使用的指针置为NULL;2.动态内存free释放后,立即将指针置NULL;3.操作指针时严格控制边界,避免越界访问;4.使用指针前先判断是否为NULL。3、空指针和野指针的区别答案:1.定义不同:空指针是赋值为NULL的指针,指向地址为0;野指针指向随机非法地址。2.可控性不同:空指针可通过if判断规避,程序可控;野指针地址未知,无法预判,极易导致程序崩溃。3.危害不同:空指针解引用会直接报错,容易排查;野指针可能偶尔崩溃、偶尔正常,bug极难定位。4.处理方式:空指针只需判空即可避免错误;野指针只能提前规避,无法事后修复。4、二级指针的使用场景答案:二级指针即指向指针的指针,核心使用场景:1.修改一级指针本身的值:普通函数传参是值传递,想要在函数内部修改外部指针的指向,必须传入二级指针。2.存储二维数组、字符串数组:char**str可存储多个字符串,实现字符串数组管理。3.动态二维内存申请:通过二级指针循环申请一维内存,实现可变大小的二维数组。三、内存管理面试题(重点)1、C语言四大内存分区及各自特点答案:C语言程序运行时内存分为栈区、堆区、全局/静态区、常量区四个核心区域:1.栈区(stack)存放:局部变量、函数参数、函数返回地址。特点:系统自动分配、自动释放,内存空间固定较小,读写速度快,空间先进后出。2.堆区(heap)存放:malloc、calloc、realloc动态申请的内存。特点:手动申请、手动free释放,空间大、灵活,生命周期由开发者控制,不释放会造成内存泄漏。3.全局/静态区存放:全局变量、static修饰的静态变量。特点:程序启动分配内存,程序结束释放,常驻内存,未初始化默认值为0。4.常量区存放:字符串常量、const修饰的只读常量。特点:内容只读,不可修改,修改会触发程序崩溃,内存全程常驻。2、malloc、calloc、realloc的区别答案:三者都是堆区动态内存申请函数,核心差异在初始化和扩容功能:1.malloc:申请指定字节数的堆内存,不初始化,内存值随机,参数为单个总字节数。2.calloc:申请n个大小为size的内存,自动初始化为0,参数为个数+单块大小,适合需要初始化的场景。3.realloc:用于扩容/缩容已申请的堆内存,可基于原有内存调整大小,返回新的内存地址;缩容会截断尾部数据,扩容可能迁移内存。通用注意点:申请内存后必须判断是否申请成功,使用完毕必须free,避免内存泄漏。3、什么是内存泄漏?如何避免和排查答案:内存泄漏:堆区动态申请的内存,程序结束前没有手动free释放,且程序丢失该内存的指针,导致内存无法回收,系统内存被持续占用。泄漏原因:1.malloc申请内存后忘记free;2.指针重新赋值,丢失原有堆内存地址;3.函数内申请堆内存,未返回指针,外部无法释放。规避与排查:1.遵循谁申请谁释放原则,成对使用malloc和free;2.指针使用完毕及时置空,避免指针覆盖;3.使用内存检测工具(valgrind)排查泄漏点位;4.封装内存申请释放工具函数,统一管理。四、函数与预处理面试题1、形参和实参的区别,值传递和地址传递的差异答案:形参:函数定义括号内的参数,是形式占位符,函数调用时才分配内存,调用结束释放。实参:调用函数时传入的真实数据,可以是变量、常量、表达式。值传递:传递变量本身的值,函数内部修改的是形参副本,不会影响外部实参,适用于只读数据传递。地址传递(指针传递):传递变量的内存地址,函数内部通过地址修改原始数据,会直接改变外部实参值,适用于需要修改实参、传递大数据的场景。2、函数递归的条件和优缺点答案:递归必备条件:1.明确的递归终止条件,避免无限递归;2.每次递归调用,问题规模逐步缩小,趋近于终止条件。优点:代码简洁、逻辑清晰,适合树形结构、遍历、阶乘、斐波那契等迭代复杂的场景。缺点:每次递归都会开辟栈帧,消耗栈内存,递归深度过大会导致栈溢出;执行效率低于循环,存在重复计算。3、预处理指令#include<>和#include""的区别答案:1.#include<头文件>:优先从系统库目录查找头文件,用于引入系统标准头文件(stdio.h、stdlib.h等)。2.#include"头文件":优先从当前项目目录查找,找不到再去系统目录查找,用于引入自定义头文件。五、结构体、联合体、枚举面试题1、结构体和联合体的区别答案:1.内存存储不同:结构体成员独立占用内存,总大小为所有成员内存之和(包含内存对齐填充);联合体成员共享同一块内存,同一时间只有一个成员有效。2.空间利用率:结构体空间利用率低,占用内存大;联合体极大节省内存,适合多状态互斥的场景。3.使用场景:结构体用于描述一个事物的多个独立属性;联合体用于存储互斥数据、硬件寄存器、数据类型转换。2、结构体内存对齐规则(重点)答案:内存对齐是编译器为了提高CPU读取效率,自动填充空闲字节的机制,规则如下:1.结构体每个成员的偏移地址,必须是自身大小的整数倍,不足则填充字节;2.结构体整体大小,必须是最大成员字节数的整数倍,不足尾部填充;3.可通过#pragmapack(n)手动指定对齐模数,改变对齐规则。举例:structA{chara;intb;},char占1字节,填充3字节,int占4字节,总大小8字节。3、枚举的作用答案:1.代码可读性更高,用自定义标识符代替魔法数字;2.类型安全,枚举变量只能赋值枚举内的值,避免非法数值;3.便于统一管理常量,修改枚举值即可全局生效,维护性更强。六、高频易错编程面试题1、strlen和sizeof的区别答案:1.本质不同:strlen是库函数,运行时计算;sizeof是运算符,编译阶段计算。2.计算规则:strlen统计字符串有效字符个数,不包含'\0',遇到'\0'停止;sizeof统计整体内存占用字节数,包含结束符'\0'和填充字节。3.参数不同:strlen仅支持字符串;sizeof支持变量、数组、结构体、指针等所有数据类型。4.指针场景:strlen可计算指针指向的字符串长度;sizeof(指针)永远获取指针本身大小(4/8字节)。2、数组越界的危害答案:C语言不做数组边界检查,越界不会编译报错,只会运行时异常:1.越界读:读取未知内存数据,导致数据错乱、逻辑错误;2.越界写:篡改其他变量内存、栈内存,导致程序随机崩溃、栈溢出;3.越界bug隐蔽性极强,偶现性高,是项目中最难排查的问题之一。3、全局变量和局部变量哪个优先使用?为什么答案:优先使用局部变量,尽量少用全局变量。原因:1.局部变量随用随释放,节省内存,不会常驻;2.全局变量全程占用内存,生命周期太长;3.全局变量所有函数都可修改,耦合度高,极易出现值被意外篡改的bug;4.局部变量作用域封闭,独立性强,代码可复用性、可维护性更好。七、进阶面试题1、指针常量和常量指针的快速区分方法答案:口诀:const靠近谁,谁就不可变1.constint*p:const修饰*p,值不可变(常量指针);2.int*constp

温馨提示

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

最新文档

评论

0/150

提交评论