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

下载本文档

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

文档简介

C语言面试试题及详细答案(企业真实版)一、基础概念简答题(8题)1、简述C语言中局部变量和全局变量的区别?参考答案:1.定义位置:局部变量定义在函数、代码块内部;全局变量定义在所有函数外部。2.作用域:局部变量仅在当前函数/代码块内有效;全局变量整个源文件甚至跨文件(可通过extern声明)有效。3.存储位置:局部变量存储在栈区;全局变量存储在全局静态区。4.生命周期:局部变量函数调用结束后立即释放;全局变量程序运行全程存在,程序结束才释放。5.初始值:局部变量默认随机垃圾值;全局变量默认自动初始化为0。2、static关键字在C语言中有哪些用法?参考答案:static主要有三种核心用法:1.修饰局部变量:改变变量存储区域,从栈区变为静态区,生命周期延长至程序结束,仅初始化一次,保留上一次调用的值。2.修饰全局变量:限制作用域,该变量仅能在当前源文件中使用,无法跨文件访问。3.修饰函数:限制函数作用域,该函数仅当前文件可调用,外部文件无法引用。3、const关键字的作用是什么?常用场景有哪些?参考答案:const用于修饰只读变量,禁止修改变量值,提升代码安全性,同时可辅助编译器优化代码。常用场景:1.修饰普通变量:定义只读常量,替代宏定义,可进行类型检查。2.修饰指针变量:const在*前,表示指针指向的数据不可改;const在*后,表示指针地址不可改。3.修饰函数形参:防止函数内部意外修改传入的参数数据,常用于数组、字符串、结构体传参。4、#define和const定义常量的区别?参考答案:1.处理阶段:#define是预处理阶段简单文本替换,无类型检查;const是编译阶段处理,有严格数据类型检查。2.作用域:#define默认全局有效,可通过#undef取消定义;const常量遵循变量作用域规则。3.内存占用:#define不占用内存,仅文本替换;const常量会分配内存空间。4.调试性:define无法调试,无变量符号;const可正常调试,可读性更强。5、结构体和联合体的区别?参考答案:1.内存分配:结构体成员独立分配内存,总大小为所有成员大小之和(内存对齐后);联合体所有成员共用同一块内存。2.存储特点:结构体所有成员可同时赋值、访问;联合体同一时间仅能存储一个成员数据,赋值新数据会覆盖旧数据。3.内存大小:结构体大小≥所有成员大小总和;联合体大小等于最大成员的内存大小。4.适用场景:结构体用于存储一组关联的不同类型数据;联合体用于节省内存、数据类型转换。6、内存四区分别是什么?各自存储什么数据?参考答案:1.栈区:存储局部变量、函数形参、函数返回地址,由系统自动分配释放,空间小、速度快。2.堆区:存储动态内存(malloc、calloc、realloc申请的内存),由程序员手动申请和释放,全程可控,空间大。3.全局/静态区:存储全局变量、static修饰的静态变量,程序启动分配、程序结束释放。4.常量区:存储字符串常量、const修饰的只读常量,数据只读,不可修改。7、数组和指针的区别?参考答案:1.本质不同:数组是连续的内存空间,是数据集合;指针是存储内存地址的变量。2.大小不同:sizeof(数组)得到数组总内存大小;sizeof(指针)固定为4字节(32位)/8字节(64位)。3.地址特性:数组名是常量地址,不可赋值修改;指针是变量,可随意更改指向的地址。4.存储内容:数组存储具体数据;指针存储内存地址。8、简述sizeof和strlen的区别?参考答案:1.本质:sizeof是运算符,可计算所有数据类型内存大小;strlen是库函数,仅用于计算字符串长度。2.计算规则:sizeof包含字符串结束符\0;strlen仅统计有效字符,不包含\0。3.处理时机:sizeof编译阶段计算结果;strlen程序运行时计算。4.适用范围:sizeof支持数组、结构体、指针、基本数据类型;strlen仅支持字符指针、字符串数组。二、指针与易错知识点(6题)1、野指针是什么?如何避免野指针?参考答案:野指针是指向未知、非法内存地址的指针,无明确指向,无法正常使用,会造成程序崩溃、内存越界。产生原因:指针未初始化、指针指向的内存已释放、指针越界访问。避免方法:1.指针定义时初始化为NULL;2.内存释放后立即将指针置空;3.使用指针前先判断是否为NULL;4.严格控制指针访问范围,避免越界。2、空指针和悬空指针的区别?参考答案:1.空指针:赋值为NULL的指针,指向地址0,是合法指针,可判断、可赋值,不会造成程序崩溃。2.悬空指针:指针原本指向合法内存,内存被释放后,指针未置空,依旧指向已回收的非法内存,属于野指针的一种,访问会引发内存错误。3、指针数组和数组指针的区别?参考答案:1.指针数组:int*p[5],是数组,数组的每个元素都是int类型指针,优先级:[]高于*。2.数组指针:int(*p)[5],是指针,专门指向一个包含5个int元素的数组,()提升*优先级。简单记忆:看括号,带括号是数组指针(指向数组),不带括号是指针数组(存放指针)。4、函数指针的作用和使用场景?参考答案:函数指针是指向函数的指针,存储函数的入口地址,可通过指针调用函数。核心作用:解耦代码、实现回调函数、多态逻辑、动态调用函数。常用场景:回调函数、排序规则自定义(qsort)、状态机编程、硬件驱动回调。示例:void(*p)(int)=test;5、malloc、calloc、realloc的区别?参考答案:1.malloc:动态申请指定大小堆内存,不初始化,内存为随机垃圾值,参数为内存总字节数。2.calloc:申请n个指定大小的内存,自动初始化为0,参数为元素个数+单个元素大小。3.realloc:重新调整已分配堆内存的大小,可扩容、缩容,保留原内存数据,扩容失败返回NULL。注意:动态内存使用完必须free释放,避免内存泄漏。6、什么是内存泄漏?产生原因及解决办法?参考答案:内存泄漏是堆区动态内存申请后,未手动释放,且程序丢失该内存的指针,导致内存无法回收,长期运行会占用大量内存,造成程序卡顿、崩溃。产生原因:malloc/calloc/realloc后未free、指针覆盖丢失内存地址、异常分支跳过释放代码。解决办法:成对使用申请和释放函数、内存使用完毕立即释放、异常场景统一释放内存、养成编码规范。三、程序判断题(含解析)1、判断:全局变量比局部变量优先级高,同名变量全局生效。(错)解析:局部变量作用域内,局部变量优先,会屏蔽同名全局变量。2、判断:char*str="abc";str[0]='d';代码合法。(错)解析:"abc"是字符串常量,存储在常量区,只读不可修改,修改会触发段错误。3、判断:static修饰的局部变量,只会初始化一次。(对)解析:静态局部变量首次调用初始化,后续调用沿用上次的值,不再重复初始化。4、判断:free指针后,指针变量会自动变为NULL。(错)解析:free仅释放内存,指针地址不变,会变成悬空指针,需手动置NULL。四、代码填空题+输出题(带答案)1、写出以下代码输出结果c

#include<stdio.h>

intmain()

{

charstr[]="hello";

printf("%d\n",sizeof(str));

printf("%d\n",strlen(str));

return0;

}答案:6、5解析:sizeof包含末尾\0,共6字节;strlen只统计有效字符,为5。2、写出以下代码输出结果c

#include<stdio.h>

voidtest()

{

staticinta=1;

a++;

printf("%d",a);

}

intmain()

{

test();

test();

return0;

}答案:23解析:a为静态局部变量,仅初始化一次,两次调用累加保留数值。五、编程实操面试题(高频必考)1、实现字符串反转函数(不调用库函数)参考答案代码:c

#include<stdio.h>

voidstr_reverse(char*str)

{

if(str==NULL)

return;

//计算字符串长度

intlen=0;

while(str[len]!='\0')

{

len++;

}

//首尾交换反转

inti,j;

chartemp;

for(i=0,j=len-1;i<j;i++,j--)

{

temp=str[i];

str[i]=str[j];

str[j]=temp;

}

}

intmain()

{

charbuf[]="123456";

str_reverse(buf);

printf("%s\n",buf);

return0;

}输出结果:6543212、实现冒泡排序(整型数组升序排序)参考答案代码:c

#include<stdio.h>

voidbubble_sort(intarr[],intn)

{

inti,j;

inttemp;

//外层控制排序轮数

for(i=0;i<n-1;i++)

{

//内层两两比较交换

for(j=0;j<n-1-i;j++)

{

if(arr[j]>arr[j+1])

{

temp=arr[j];

arr[j]=arr[j+1];

arr[j+1]=temp;

}

}

}

}

intmain()

{

intarr[5]={3,1,4,2,5};

intlen=sizeof(arr)/sizeof(arr[0]);

bubble_sort(arr,len);

for(inti=0;i<len;i++)

{

printf("%d",arr[i]);

}

return0;

}输出结果:123453、查找数组最大值最小值参考答案代码:c

#include<stdio.h>

voidget_max_min(intarr[],intn,int*max,int*min)

{

*max=arr[0];

*min=arr[0];

for(inti=1;i<n;i++)

{

if(arr[i]>*max)

*max=arr[i];

if(arr[i]<*min)

*min=arr[i];

}

}

intmain()

{

intarr[6]={12,45,7,89,23,5};

intmax,min;

get_max_min(arr,6,&max,&min);

printf("最大值:%d\n最小值:%d\n",max,min);

return0;

}输出结果:最大值89,最小值5六、面试综合高频问答1、头文件#include<>和#include""的区别?参考答案:<>:优先从系统库目录查找头文件,用于引入系统自带头文件(stdio.h、string

温馨提示

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

评论

0/150

提交评论