面试题:
- 基础知识题
- 请解释C语言中的指针是什么以及它们如何工作?
- 描述C语言中的动态内存分配。
malloc
、calloc
、realloc
和free
这些函数有何区别? - C语言中的宏(macro)和函数之间有什么不同?
- 代码理解题
#include <stdio.h> void mysteryFunction(int *ptrA, int *ptrB) {int temp;temp = *ptrA;*ptrA = *ptrB * 2;*ptrB = temp / 2; } int main() {int a = 10, b = 20;mysteryFunction(&a, &b);printf("a = %d, b = %d\n", a, b);return 0; }
这段代码中,mysteryFunction函数接受两个整数的指针作为参数,然后将第一个指针指向的值替换为第二个指针指向的值的两倍,并将第二个指针指向的值替换为第一个指针指向的值的一半。
问: 当调用 `mysteryFunction(&a, &b);` 后,变量 `a` 和 `b` 的值将会是多少?
- 编程能力题
- 编写一个C语言函数,实现字符串反转。
- 实现一个C语言程序,检测链表是否有环。
- 给定一个整数数组和一个目标值,请编写函数找出数组中和为目标值的两个数的索引。
- 深入理解题
- 请描述C语言中的静态变量和全局变量的作用域和生命周期。
- 解释诸如段错误(segmentation fault)和内存泄漏(memory leak)等运行时错误。
- 优化与效率题
- 给定一个性能不佳的C语言函数,请分析可能的原因并提出改进措施。
- 如果一个C语言程序的大小和运行速度非常关键,请讨论你会如何优化代码。
- 学习能力和问题解决题
- 如果在编译时遇到一个你不熟悉的编译错误,你会如何定位并解决它?
- 如何确保你的C程序是可移植的,并且可以在不同的操作系统和硬件上编译和运行?
答案:
- 指针的解释:指针是C语言中的一种数据类型,它存储了变量的内存地址。指针通过间接引用变量的地址来访问和操作变量的值。
- 动态内存分配:
malloc
分配未初始化的内存块;calloc
分配并初始化内存块为零;realloc
用于已分配内存块的大小调整;free
释放先前分配的内存。 - 宏与函数的区别:宏是预处理指令,不做类型检查,而且在预处理阶段就展开;函数在编译运行时实现,有类型安全检查,且有运行时成本。
- 代码理解题的示例答案:在函数调用之前,变量
a
的值是10,变量b
的值是20。调用mysteryFunction
后,a
会被设置为b
的两倍,也就是40。b
会被设置为a
的一半,即5。因此,函数执行后,变量a
和变量b
的值将会是:a = 40, b = 5
- 编写字符串反转函数:
void reverse(char *str) {if (str) {char *end = str;while (*end) {++end;}--end;while (str < end) {char tmp = *str;*str++ = *end;*end-- = tmp;}} }
- 检测链表是否有环:
int hasCycle(struct ListNode *head) {struct ListNode *slow = head, *fast = head;while (fast && fast->next) {slow = slow->next;fast = fast->next->next;if (slow == fast) {return 1;}}return 0; }
- 找出和为目标值的两个数的索引:这个问题可以使用哈希表解决,通过一次遍历数组,存储每个数字和其索引的映射,然后在访问每个数字时检查目标值减去该数字的结果是否也在哈希表中。
- 静态变量和全局变量的解释:静态变量在声明它的函数或文件内保持其值的生命周期,而全局变量在程序的整个执行期间都是可用的。
- 运行时错误的解释:段错误指的是程序试图访问其内存空间外的区域;内存泄漏是指程序未能释放它先前分配的内存。
- 性能不佳的函数改进:优化可能包括减少函数调用次数、减少不必要的计算、使用更高效的算法或数据结构、或者减少内存访问。
- 处理不熟悉的编译错误:首先查看编译器给出的错误信息,搜索相关的文档和在线资源,或在开发者社区中寻求帮助。
- 确保程序可移植性:遵循标准C语言规范编写代码,避免使用特定平台依赖特性,使用条件编译处理不同平台的特定代码。