C 语言模拟试卷一考试时间90 分钟 总分100 分一、选择题每题 3 分共 30 分以下程序的输出结果是 #include stdio.h int main() { int a 5, b 10; printf(%d, a b); return 0; }A. 14 B. 15 C. 16 D. 编译错误若有定义int arr[5] {1, 2, 3};则arr[4]的值为 A. 0 B. 3 C. 4 D. 不确定以下代码的输出结果是 #include stdio.h int main() { int a 10; int *p a; (*p); printf(%d, a); return 0; }A. 10 B. 11 C. 12 D. 编译错误以下关于结构体大小的说法正确的是 struct Test { char a; int b; char c; };A. 4 字节 B. 6 字节 C. 8 字节 D. 12 字节以下代码的输出结果是 #include stdio.h int main() { int arr[] {1, 2, 3, 4, 5}; int *p arr 2; printf(%d, *p); return 0; }A. 1 B. 2 C. 3 D. 4以下代码的输出结果是 #include stdio.h int main() { int i 0; for (i 0; i 5; i) { if (i 2) continue; printf(%d, i); } return 0; }A. 01234 B. 0134 C. 0124 D. 0123以下代码的输出结果是 #include stdio.h int main() { static int x 5; x; printf(%d, x); return 0; }A. 5 B. 6 C. 不确定 D. 编译错误以下代码的输出结果是 #include stdio.h #include string.h int main() { char str[] hello; printf(%zu %zu, strlen(str), sizeof(str)); return 0; }A. 5 5 B. 5 6 C. 6 6 D. 6 5以下代码的输出结果是 #include stdio.h void func(int *p) { *p 100; } int main() { int a 10; func(a); printf(%d, a); return 0; }A. 10 B. 100 C. 不确定 D. 编译错误以下关于 malloc 的说法错误的是 A. malloc 分配的内存需要手动释放 B. malloc 返回的指针需要强制类型转换 C. malloc 分配的内存内容初始化为 0 D. malloc 失败时返回 NULL二、填空题每题 4 分共 20 分C 语言中__运算符用于取变量的地址__运算符用于解引用指针。若有int arr[3][4];则数组元素的总个数为__数组名arr的类型是__。函数fopen(test.txt, w)中w 表示__模式如果文件不存在会__。联合体union与结构体struct的主要区别是结构体各成员__联合体各成员__。若有const int *p;则__能/不能通过 p 修改指向的值__能/不能修改 p 指向其他地址。三、简答题每题 6 分共 24 分简述int *p1 (int *)malloc(10 * sizeof(int));和int *p2 (int *)calloc(10, sizeof(int));的区别。解释以下代码的输出结果并说明原因int arr[] {1, 2, 3}; int *p arr; printf(%d, arr[1]); printf(%d, 1[arr]);什么是内存泄漏如何避免简述static关键字在 C 语言中的三种用法。四、编程题共 26 分1. 链表操作13 分定义一个单链表节点结构并实现以下函数typedef struct Node { int data; struct Node *next; } Node; // (1) 创建新节点 Node* create_node(int data); // (2) 在链表尾部插入节点 void append(Node **head, int data); // (3) 删除链表中第一个值为 val 的节点 void delete_node(Node **head, int val);2. 字符串反转13 分编写函数reverse_string在不使用额外空间的情况下反转字符串void reverse_string(char *str);要求原地反转不使用额外数组考虑空指针和空字符串的情况主函数中测试你的代码附录答案与解析一、选择题答案B解析b是后置自增先使用 b 的值10进行加法然后 b 自增。所以a b 5 10 15A解析数组部分初始化时未显式初始化的元素自动初始化为 0B解析*p指向 a(*p)等价于a所以 a 变为 11C解析考虑内存对齐。char a(1 字节) 填充 (3 字节) int b(4 字节) char c(1 字节) 填充 (3 字节) 12 字节。但实际通常是 8 字节char a 3 字节填充 int b char c 3 字节填充。正确答案是 8 字节C解析p arr 2指向 arr[2]即值为 3B解析当 i2 时执行 continue跳过 printf所以输出 0134B解析static 变量在程序启动时初始化为 5然后 x 变为 6B解析strlen 返回不包括\0的长度为 5sizeof 返回包括\0的总字节数为 6B解析通过指针修改了实参 a 的值C解析malloc 分配的内存不初始化内容是随机的。calloc 才会初始化为 0二、填空题答案*解析取地址*解引用12int (*)[4]解析3×412 个元素二维数组名是指向一维数组的指针写入只写创建新文件解析w 模式用于写入文件不存在则创建存在则清空独立占用内存共享同一块内存解析结构体大小是各成员之和考虑对齐联合体大小等于最大成员不能能解析const int *p 是指向常量的指针值不能改指针可以改三、简答题答案1. malloc 和 calloc 的区别malloc分配指定字节数的内存不初始化内容为随机值calloc分配 n 个大小为 size 的元素自动初始化为 0malloc(10 * sizeof(int)) 和 calloc(10, sizeof(int)) 分配大小相同但 calloc 初始化为 02. 代码输出及原因输出2 2原因C 语言中arr[i]等价于*(arr i)而加法满足交换律所以1[arr]等价于arr[1]都是 23. 内存泄漏及避免内存泄漏动态分配的内存使用后未释放导致内存无法回收避免方法每次 malloc/calloc/realloc 后都要对应 freefree 后将指针置为 NULL使用智能指针或 RAII 模式C使用 valgrind 等工具检测4. static 的三种用法局部 static变量生命周期延长至程序结束值在函数调用间保持文件作用域 static限制变量/函数仅在当前文件可见内部链接static 数组在数据区分配自动初始化为 0四、编程题答案1. 链表操作#include stdio.h #include stdlib.h typedef struct Node { int data; struct Node *next; } Node; Node* create_node(int data) { Node *new_node (Node *)malloc(sizeof(Node)); if (new_node NULL) { return NULL; // 分配失败 } new_node-data data; new_node-next NULL; return new_node; } void append(Node **head, int data) { Node *new_node create_node(data); if (new_node NULL) return; if (*head NULL) { *head new_node; return; } Node *curr *head; while (curr-next ! NULL) { curr curr-next; } curr-next new_node; } void delete_node(Node **head, int val) { if (*head NULL) return; // 删除头节点 if ((*head)-data val) { Node *temp *head; *head (*head)-next; free(temp); return; } // 删除中间或尾部节点 Node *curr *head; while (curr-next ! NULL curr-next-data ! val) { curr curr-next; } if (curr-next ! NULL) { Node *temp curr-next; curr-next curr-next-next; free(temp); } } // 测试代码 int main() { Node *head NULL; append(head, 1); append(head, 2); append(head, 3); delete_node(head, 2); return 0; }2. 字符串反转#include stdio.h #include string.h void reverse_string(char *str) { if (str NULL || *str \0) { return; // 处理空指针和空字符串 } int left 0; int right strlen(str) - 1; while (left right) { // 交换字符 char temp str[left]; str[left] str[right]; str[right] temp; left; right--; } } // 测试代码 int main() { char str1[] hello; char str2[] ; char *str3 NULL; reverse_string(str1); printf(str1: %s\n, str1); // 输出olleh reverse_string(str2); printf(str2: %s\n, str2); // 输出空 // reverse_string(str3); // 注释掉避免段错误 return 0; }评分标准选择题每题 3 分共 30 分填空题每题 4 分共 20 分简答题每题 6 分共 24 分编程题功能正确 8 分边界处理 3 分代码规范 2 分