C语言经典面试题及答案100道

C语言经典面试题及答案100道

基础概念部分

  1. **什么是C语言?**
  • 答:C语言是一种通用的、过程式的计算机编程语言,由Dennis Ritchie于1972年在贝尔实验室开发,主要用于系统软件开发。
  1. **C语言的特点是什么?**
  • 答:特点包括:结构化语言、高效性、可移植性、丰富的运算符、内存管理、指针操作等。
  1. **解释C语言中的关键字和标识符的区别**
  • 答:关键字是C语言预定义的保留字,有特殊含义;标识符是用户定义的变量、函数等名称,不能与关键字冲突。
  1. **C语言中的基本数据类型有哪些?**
  • 答:基本数据类型包括:int、char、float、double和void。
  1. **什么是变量?如何声明变量?**
  • 答:变量是存储数据的命名内存位置。声明语法:`数据类型 变量名;` 如 `int age;`

运算符与表达式

  1. **解释C语言中的算术运算符**
  • 答:+ (加)、- (减)、* (乘)、/ (除)、% (取模)、++ (自增)、-- (自减)
  1. **什么是运算符优先级?**
  • 答:决定表达式求值顺序的规则,如 * / % 优先级高于 + -
  1. **++i和i++有什么区别?**
  • 答:++i是先自增再使用,i++是先使用再自增
  1. **什么是三元运算符?**
  • 答:条件运算符 `?:`,语法:`条件 ? 表达式1 : 表达式2`
  1. **sizeof运算符的作用是什么?**
  • 答:返回变量或数据类型的字节大小

控制结构

  1. **C语言中有哪些控制语句?**
  • 答:if-else、switch、for、while、do-while、break、continue、goto
  1. **if和switch的区别是什么?**
  • 答:if适用于范围判断和条件组合,switch适用于离散值匹配
  1. **break和continue的区别?**
  • 答:break终止整个循环,continue跳过当前迭代继续下一次循环
  1. **如何实现无限循环?**
  • 答:`while(1)` 或 `for(;;)`
  1. **goto语句的优缺点是什么?**
  • 答:优点:灵活跳转;缺点:破坏程序结构,难以维护

函数

  1. **什么是函数?如何定义函数?**
  • 答:函数是完成特定任务的代码块。定义:`返回类型 函数名(参数列表) { 函数体 }`
  1. **函数声明和函数定义的区别?**
  • 答:声明告诉编译器函数签名,定义提供函数实现
  1. **什么是递归函数?**
  • 答:直接或间接调用自身的函数
  1. **什么是内联函数?**
  • 答:用inline声明的函数,编译器尝试在调用处展开代码以减少函数调用开销
  1. **main函数的返回值有什么意义?**
  • 答:返回0表示成功,非0表示错误代码

数组与字符串

  1. **如何声明和初始化数组?**
  • 答:`int arr[5];` 或 `int arr[] = {1,2,3};`
  1. **数组和指针的关系是什么?**
  • 答:数组名是指向数组首元素的常量指针
  1. **如何传递数组给函数?**
  • 答:传递数组名(指针)和大小,如 `void func(int arr[], int size)`
  1. **什么是二维数组?**
  • 答:数组的数组,如 `int matrix[3][3];`
  1. **字符串和字符数组的区别?**
  • 答:字符串是以'\0'结尾的字符数组

指针

  1. **什么是指针?**
  • 答:存储内存地址的变量
  1. **如何声明指针变量?**
  • 答:`数据类型 *指针名;` 如 `int *ptr;`
  1. **&和*运算符的作用是什么?**
  • 答:&取地址,*解引用
  1. **什么是空指针?**
  • 答:值为NULL的指针,不指向任何有效内存
  1. **什么是野指针?**
  • 答:指向无效内存或已释放内存的指针

结构体与联合体

  1. **什么是结构体?如何定义?**
  • 答:用户自定义的复合数据类型。定义:

```c

struct Student {

char name[50];

int age;

};

```

  1. **结构体和数组的区别?**
  • 答:数组存储同类型元素,结构体可存储不同类型元素
  1. **如何访问结构体成员?**
  • 答:使用点运算符(.)或箭头运算符(->)
  1. **什么是联合体?**
  • 答:所有成员共享同一内存空间的数据结构
  1. **结构体和联合体的区别?**
  • 答:结构体成员有独立内存空间,联合体成员共享内存

动态内存管理

  1. **malloc和calloc的区别?**
  • 答:malloc分配未初始化的内存,calloc分配并初始化为0
  1. **什么是内存泄漏?**
  • 答:分配的内存未释放导致内存浪费
  1. **free函数的作用是什么?**
  • 答:释放动态分配的内存
  1. **realloc函数的作用?**
  • 答:调整已分配内存块的大小
  1. **动态内存分配失败怎么处理?**
  • 答:检查返回的指针是否为NULL,并采取适当措施

文件操作

  1. **文件打开模式有哪些?**
  • 答:"r"(读),"w"(写),"a"(追加),"r+"(读写),"w+"(读写),"a+"(读写追加)
  1. **fopen和fclose的作用?**
  • 答:fopen打开文件,fclose关闭文件
  1. **文件读写函数有哪些?**
  • 答:fgetc/fputc, fgets/fputs, fread/fwrite, fprintf/fscanf
  1. **什么是文件指针?**
  • 答:FILE类型的指针,指向文件流
  1. **如何检测文件结束?**
  • 答:feof函数或读取函数返回EOF

预处理器

  1. **#include的作用是什么?**
  • 答:包含头文件内容
  1. **#define的用途?**
  • 答:定义宏常量或宏函数
  1. **宏和函数的区别?**
  • 答:宏在预处理期展开,函数在运行时调用;宏无类型检查
  1. **条件编译指令有哪些?**
  • 答:#if, #ifdef, #ifndef, #else, #elif, #endif
  1. **#pragma的作用?**
  • 答:提供编译器特定指令

位操作

  1. **C语言中的位运算符有哪些?**
  • 答:&(与)、|(或)、^(异或)、~(取反)、<<(左移)、>>(右移)
  1. **如何设置特定位?**
  • 答:使用或操作 `var |= (1 << bit_position)`
  1. **如何清除特定位?**
  • 答:使用与操作 `var &= ~(1 << bit_position)`
  1. **如何检查特定位?**
  • 答:`if(var & (1 << bit_position))`
  1. **交换两个变量的值,不使用临时变量?**
  • 答:使用异或操作:

```c

a ^= b;

b ^= a;

a ^= b;

```

复杂指针

  1. **什么是指针的指针?**
  • 答:存储指针地址的指针,如 `int **pp;`
  1. **函数指针是什么?**
  • 答:指向函数的指针,如 `int (*funcPtr)(int, int);`
  1. **如何使用函数指针?**
  • 答:

```c

int add(int a, int b) { return a+b; }

int (*funcPtr)(int, int) = add;

funcPtr(2,3);

```

  1. **什么是void指针?**
  • 答:通用指针类型,可指向任何数据类型
  1. **如何对void指针进行算术运算?**
  • 答:必须先转换为具体类型的指针

存储类别

  1. **auto、static、register、extern的区别?**
  • 答:auto(默认,自动存储期)、static(静态存储期)、register(建议寄存器存储)、extern(外部链接)
  1. **局部变量和全局变量的区别?**
  • 答:局部变量在函数内定义,全局变量在函数外定义
  1. **static关键字的作用?**
  • 答:对变量:保持值不变;对函数:限制作用域到当前文件
  1. **extern关键字的作用?**
  • 答:声明变量或函数在其他文件中定义
  1. **volatile关键字的作用?**
  • 答:防止编译器优化,指示变量可能被意外修改

高级话题

  1. **typedef的作用是什么?**
  • 答:为现有类型创建别名
  1. **枚举类型是什么?**
  • 答:用户定义的整数常量集合
  1. **const关键字的作用?**
  • 答:定义常量,防止修改
  1. **什么是回调函数?**
  • 答:通过函数指针调用的函数
  1. **解释左值和右值**
  • 答:左值可出现在赋值左侧,有内存位置;右值是临时值

常见算法实现

  1. **实现冒泡排序**
  • 答:

```c

void bubbleSort(int arr[], int n) {

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

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

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

swap(&arr[j], &arr[j+1]);

}

```

  1. **实现二分查找**
  • 答:

```c

int binarySearch(int arr[], int l, int r, int x) {

while(l <= r) {

int mid = l + (r-l)/2;

if(arr[mid] == x) return mid;

if(arr[mid] < x) l = mid+1;

else r = mid-1;

}

return -1;

}

```

  1. **实现链表反转**
  • 答:

```c

struct Node* reverse(struct Node* head) {

struct Node *prev = NULL, *current = head, *next = NULL;

while(current != NULL) {

next = current->next;

current->next = prev;

prev = current;

current = next;

}

return prev;

}

```

  1. **实现斐波那契数列**
  • 答:

```c

int fibonacci(int n) {

if(n <= 1) return n;

return fibonacci(n-1) + fibonacci(n-2);

}

```

  1. **实现字符串反转**
  • 答:

```c

void reverseString(char* str) {

int l = 0, r = strlen(str)-1;

while(l < r) {

char temp = str[l];

str[l] = str[r];

str[r] = temp;

l++; r--;

}

}

```

常见问题

  1. **什么是段错误?**
  • 答:访问非法内存地址导致的错误
  1. **如何避免内存泄漏?**
  • 答:确保每个malloc/calloc都有对应的free
  1. **什么是缓冲区溢出?**
  • 答:向缓冲区写入超出其容量的数据
  1. **如何防止缓冲区溢出?**
  • 答:使用安全函数如strncpy代替strcpy,检查边界
  1. **什么是悬垂指针?**
  • 答:指向已释放内存的指针

代码分析题

  1. **以下代码输出什么?为什么?**

```c

int main() {

int i = 5;

printf("%d %d %d", i++, i++, i++);

return 0;

}

```

  • 答:输出不确定,因为参数求值顺序未定义
  1. **以下代码有什么问题?**

```c

char *str = "Hello";

str[0] = 'h';

```

  • 答:试图修改字符串常量,导致未定义行为
  1. **以下代码输出什么?**

```c

int main() {

int a = 10, b = 20;

if(a = b)

printf("Equal");

else

printf("Not equal");

return 0;

}

```

  • 答:输出"Equal",因为使用了赋值(=)而非比较(==)
  1. **以下宏定义有什么问题?**

```c

#define SQUARE(x) x*x

```

  • 答:当参数是表达式时会有问题,如SQUARE(2+3)展开为2+3*2+3=11而非25
  1. **以下代码输出什么?**

```c

int main() {

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

int *ptr = (int*)(&a+1);

printf("%d %d", *(a+1), *(ptr-1));

return 0;

}

```

  • 答:输出"2 5",因为&a+1跳过整个数组,ptr-1指向最后一个元素

编程题

  1. **编写程序检查素数**
  • 答:

```c

int isPrime(int n) {

if(n <= 1) return 0;

for(int i=2; i*i<=n; i++)

if(n%i == 0) return 0;

return 1;

}

```

  1. **编写程序实现strcpy**
  • 答:

```c

void my_strcpy(char *dest, const char *src) {

while((*dest++ = *src++) != '\0');

}

```

  1. **编写程序计算字符串长度**
  • 答:

```c

int my_strlen(const char *str) {

int len = 0;

while(*str++) len++;

return len;

}

```

  1. **编写程序交换两个数**
  • 答:

```c

void swap(int *a, int *b) {

int temp = *a;

*a = *b;

*b = temp;

}

```

  1. **编写程序计算阶乘**
  • 答:

```c

int factorial(int n) {

if(n == 0) return 1;

return n * factorial(n-1);

}

```

综合问题

  1. **大端和小端的区别?如何检测?**
  • 答:大端:高位在前;小端:低位在前。检测代码:

```c

int checkEndian() {

int i = 1;

char *c = (char*)&i;

return *c ? 1 : 0; // 1为小端,0为大端

}

```

  1. **解释栈和堆的区别**
  • 答:栈:自动管理,大小固定,存储局部变量;堆:手动管理,大小灵活,存储动态分配内存
  1. **什么是内存对齐?为什么重要?**
  • 答:数据在内存中的起始地址是其大小的整数倍。提高访问效率,某些硬件要求对齐
  1. **解释可变参数函数的实现**
  • 答:使用stdarg.h中的va_list、va_start、va_arg、va_end宏
  1. **什么是守护进程?如何创建?**
  • 答:在后台运行的进程。创建步骤:fork()、setsid()、改变工作目录、关闭文件描述符等

最新标准

  1. **C99和C11的主要新特性?**
  • 答:C99://注释、变长数组、bool类型、复合字面量等;C11:多线程、匿名结构体/联合体等
  1. **restrict关键字的作用?**
  • 答:指示指针是访问数据的唯一方式,帮助编译器优化
  1. **_Generic关键字的作用?**
  • 答:提供类似C++函数重载的功能
  1. **原子操作在C11中如何实现?**
  • 答:使用<stdatomic.h>头文件中的原子类型和操作
  1. **C语言未来的发展方向?**
  • 答:更好的并行支持、安全性增强、与现代硬件特性匹配等

这些题目涵盖了C语言面试中的主要知识点,包括基础概念、语法细节、内存管理、算法实现等。准备面试时,建议不仅要记住答案,还要理解背后的原理,并能实际编写代码演示。

相关推荐
忘了ʷºᵇₐ2 小时前
MapReduce-WordCount实现按照value降序排序、字符小写、识别不同标点
java·大数据·linux·intellij-idea·mapreduce
看到我,请让我去学习2 小时前
数据结构—排序(斐波那契数列,冒泡,选择,插入,快速,归并,图,广度优先算法)
c语言·开发语言·数据结构·后端
时时三省2 小时前
【时时三省】(C语言基础)数组习题
c语言
大大。2 小时前
Vue3 与 Vue2 区别
前端·面试·职场和发展
兔兔爱学习兔兔爱学习3 小时前
创建Workforce
人工智能·算法
NoneCoder3 小时前
JavaScript 性能优化:调优策略与工具使用
前端·javascript·面试·性能优化
海天胜景3 小时前
VSCode launch.json 配置参数详解
linux·vscode·json
2301_794461573 小时前
力扣-有效三角形的个数
数据结构·算法·leetcode
deepwater_zone3 小时前
Linux下 使用 SSH 完成 Git 绑定 GitHub
linux·git·ssh
Tiny番茄3 小时前
LeetCode 39. 组合总和 LeetCode 40.组合总和II LeetCode 131.分割回文串
算法·leetcode·职场和发展