--- title: "02-记忆(全是原题)" created: 2026-01-05 tags: - 博客 --- # 记忆(全是原题) ## 题型分布 一、选择题(共20小题,每小题1分,共20分) 二、填空题(共10空,每空1分,共10分) 三、判断题(共10小题,每小题1分,共10分) 四、程序阅读题(共5小题,每小题4分,共20分) 五、算法设计题(共2小题,每小题8分,共16分) 六、程序设计题(共2小题,每小题12分,共24分) ## **一、选择题(共20小题,每小题1分,共20分)** ### 1、考察格式化输出与 ASCII 码 **题目**:已知字符 `a` 的 ASCII 码为 97,执行语句 `printf("%c%d", 'b', 'b'+1);` 后输出结果是\_\_\_\_\_\_\_\_ **A、b99** B、98c C、9899 D、bc - **解析**: - `'b'` 的 ASCII 码是 98(因为 `'a'` 是 97,`'b'` 紧随其后)。 - 第一个格式符 `%c` 对应参数 `'b'`:输出字符形式 **b**。 - 第二个格式符 `%d` 对应参数 `'b'+1`:即 `98 + 1 = 99`。`%d` 要求输出整数形式,所以输出 **99**。 - 拼接起来就是 `b99`。 ### 2、考察 if 语句的作用范围与逗号表达式 **题目**:定义 `int x=4,y=3,z=5;`,下列四个程序段中有 3 个程序段的执行结果相同,另一个执行结果不同的是\_\_\_\_\_\_\_\_ A、if(x>y) z=x,x=y,y=z; B、if(x>y) { z=x,x=y,y=z;} **C、if(x>y) z=x;x=y;y=z;** D、if(x>y) {z=x;x=y;y=z;} - **解析**: - `x > y` 即 `4 > 3`,条件为真。 - **A**: `if(x>y) z=x,x=y,y=z;` —— 逗号表达式 `z=x,x=y,y=z` 被视为一条语句。因为条件为真,这三个赋值都会执行。 - **B**: `if(x>y) { z=x,x=y,y=z;}` —— 花括号内包含一条逗号表达式语句,效果同 A,全部执行。 - **D**: `if(x>y) {z=x;x=y;y=z;}` —— 花括号内包含三条独立语句,因为有花括号包裹,全部受 `if` 控制,全部执行。 - **C**: `if(x>y) z=x; x=y; y=z;` —— **陷阱!** `if` 只能控制紧跟其后的第一条语句(即 `z=x;`)。后面的 `x=y;` 和 `y=z;` 与 `if` 无关,无论条件真假都会执行。 - 虽然在本题具体数值下,条件为真,看起来大家都执行了。但从**程序逻辑结构**来看,C 的控制范围与其他三项不同(如果 `x>y` 为假,A/B/D 什么都不做,而 C 依然会执行后两句赋值)。 ``` 变量不为0 就是true int n; if (n) { …… } 区分赋值和判等 int x; if (x=1) { …… } if (x==1) { …… } 注意区分 看准括号和分号的位置 if (条件) { a = 1; b = 2; } if (条件) a = 1; b = 2; if (条件) a = 1, b =2; if (条件); a = 1; b = 2; ``` ### 3、考察do-while 循环 **题目**:程序段 `int n=3; do{ printf("%d",n--);}while(!n);` 的执行结果是\_\_\_\_\_\_\_\_ A、3 2 1 B、死循环 C、2 **D、3** - **解析**: 1. **第一次执行循环体**:打印 `n` (3),然后 `n` 自减变为 2。 2. **判断条件**:`while(!n)` 即 `while(!2)`。在 C 语言中,2 是真,`!2` 就是假 (0)。 3. **结果**:条件为假,循环终止。 4. 所以屏幕上只输出了一个 **3**。 ### 4、考察无符号数 **题目**:设 `int i,a=1; unsigned j;`,则下列语句执行会出现无限循环的语句是\_\_\_\_\_\_\_\_ **A、for(j=15;j>0;j-=2) a++;** B、for(j=0;j>15;j+=2) a++; C、for(i=0;i>15;i+=2) a++; D、for(i=15;i>0;i-=2) a++; - **解析**: - **A**: `for(j=15; j>0; j-=2)`。注意 `j` 是 **unsigned (无符号整数)**。 - 序列变化:15, 13, ..., 3, 1。 - 下一步:`1 - 2`。在数学上是 -1,但在计算机无符号数运算中,它会变成一个巨大的正整数(通常是 `2^32 - 1`)。 - 结果:这个巨大的数依然 `> 0`,循环条件永远成立,导致死循环。 - **B/C**: 初始条件 `0 > 15` 不成立,一次都不执行。 - **D**: `i` 是 `int` (有符号)。`1 - 2` 变成 `-1`。`-1 > 0` 为假,循环正常结束。 ### 5、考察循环语句的特性 **题目**:下列关于循环语句 for、while、do-while 的叙述中正确的是\_\_\_\_\_\_\_\_ **A、三种循环语句都可能出现无穷循环** B、三种循环语句中都可以缺省循环终止条件表达式 C、三种循环语句的循环体都至少被无条件地执行一次 D、三种循环语句的循环体都必须放入一对花括号中 - **解析**: - **A**: 正确。只要条件设置不当(如 `while(1)`),三种循环都可能死循环。 - **B**: 错误。`for(;;)` 可以缺省条件,但 `while()` 和 `do-while()` 的括号内必须有表达式(哪怕是常数 1)。 - **C**: 错误。`for` 和 `while` 是“先判断后执行”,可能一次都不执行。只有 `do-while` 至少执行一次。 - **D**: 错误。如果循环体只有一条语句,花括号 `{}` 可以省略。 ### 6、考察函数形参(数组)声明 **题目**:下列关于函数形参的声明中正确的是\_\_\_\_\_\_\_\_ A、int a[][] **B、int a[]** C、int a[]={0} D、int a[2][] - **解析**: - **B**: `int a[]` —— 正确。作为函数参数时,一维数组可以不写长度(本质是退化为指针 `int *a`)。 - **A/D**: `int a[][]` 和 `int a[2][]` —— 错误。多维数组作为参数,**第一维可以省略,但后面的维度必须写明**(例如 `int a[][5]` 是对的)。编译器需要知道列宽来计算地址。 - **C**: `int a[]={0}` —— 错误。函数形参只是声明,**不能在参数列表中进行初始化赋值**。 ### 7、考察文件 **题目**:下列函数中,可以把整型数据以二进制形式写入文件中的函数是\_\_\_\_\_\_\_\_ A、fputc() **B、fwrite()** C、fread() D、fgetc() - **解析**: - **B**: `fwrite()` —— 专门用于二进制块读写的函数。 - **A**: `fputc()` —— 写入单个字符(文本模式)。 - **C/D**: `fread()` / `fgetc()` —— 都是读取函数,不是写入。 ### 8、考察文件 **题目**:当文件被正常关闭时,fclose()函数的返回值是\_\_\_\_\_\_\_\_ A、-1 B、true **C、0** D、1 - **解析**: - `fclose` 关闭成功返回 **0**。 - 关闭失败返回 **EOF**(通常定义为 -1)。 ### 9、考察宏定义 **题目**:在宏定义语句 `#define PI 3.1415926` 中,宏名 PI 的是\_\_\_\_\_\_\_\_ A、一个字符串 B、一个单精度数 **C、一个常量** D、一个双精度数 - **解析**: - 在 C 语言术语中,用 `#define` 定义的标识符被称为**符号常量**(Symbolic Constant)。 - 它不是字符串(没有双引号),也不是变量。虽然它代表一个双精度数,但“符号常量”是更准确的定义分类。 ![[image-ac0a0a00.png]] ### 10、考察宏替换 **题目**:设有定义 `#define d 2` 等,以下表达式中有语法错误的是\_\_\_\_\_\_\_ A、x++ B、y++ C、c++ **D、d++** - **解析**: - 宏定义是**纯文本替换**。预处理阶段会将代码中所有的 `d` 替换为 `2`。 - **A**: `x++` -> `5++`(变量自增,正确)。 - **B**: `y++` -> `3.83++`(变量自增,正确)。 - **C**: `c++` -> `c` 是变量,可以自增。 - **D**: `d++` -> 被替换为 `2++`。 - **错误原因**:自增运算符 `++` 只能用于**变量**(左值),不能用于**常量**或表达式。你不能强迫数字 2 变成 3。 ![[image-30abfe31.png]] > 注:上面的内容是原题,接下来的内容为推测必考点: ### 11、考察标识符 ![[image-617c0155.png]] ### 12、考察数组 在C语言中,数组下标是从( )开始的。 **A. 0** B. 1 C. 2 D. 任意整数 若有定义 int arr[5];,则数组arr的最后一个元素是( )。 A. arr[0] **B. arr[4]** C. arr[5] D. arr[6] 以下关于二维数组的描述,正确的是( ) A. 二维数组在内存中是按列存储的 **B. 二维数组可以看作是一维数组的数组** C. 二维数组的行数和列数必须在编译时确定 D. 二维数组的所有元素必须具有相同的值 ### 13、考察函数 Q1:什么是形参,什么是实参? - **形参 (Formal Parameter):** - **定义时**括号里的变量。 - 它是“占位符”,函数未被调用时不占内存,只有调用时才分配内存。 - *例子:* `void fun(int a)` 里的 `a`。 - **实参 (Actual Parameter):** - **调用时**括号里传递的具体数值或变量。 - 它是“实际的数据”,必须有确定的值。 - *例子:* `fun(2)` 里的 `2`。 - **关系:** 发生函数调用时,**实参的值会单向复制给形参**(值传递)。 Q2:函数调用之前是否需要先声明? - **原则上需要。** 编译器必须先认识这个函数(知道它的名字、参数类型、返回值类型),才能检查调用是否合法。 - **特例:** 如果函数的**定义**(完整代码)写在调用它的位置**之前**,那么定义本身就充当了声明,不需要额外写声明语句。 Q3:是否可以调用 main 函数? - **在 C 语言中:可以。** `main` 函数本质上也是一个函数,可以在程序中递归调用自己(虽然在实际开发中极少这样做,容易死循环)。 - *(注:在 C++ 中是禁止调用 main 函数的,但 C 语言考试通常认为可以)*。 Q4:什么是外部函数和内部函数,分别使用哪个关键字? - **内部函数 (静态函数):** - 只能被**当前文件**中的其他函数调用,不能被其他文件使用。 - 关键字:`static` - 格式:`static int fun(...)` - **外部函数:** - 可以被其他文件调用。C 语言中函数默认都是外部的。 - 关键字:`extern` (定义时通常省略,声明时可加上) Q5:当哪条语句被执行时,程序的执行流程无条件地从一个函数跳转到另一个函数? - 答案:**函数调用语句**。 - 当程序执行到 `fun();` 这种调用语句时,控制权会立即从当前函数(如 main)转移到被调用的函数(如 fun)。 - 而 `return` 语句则是将控制权**跳回**。 ### 14、考察自增自减 ``` int a=5; int b,c; b=++a; c=a++; a, b, c的值最终是多少? ``` ``` ++a a=6 b=a=6 c=a=6 a++ a=7 a=7 b=6 c=6 ``` ### 15、考察printf ``` printf函数调用时,格式说明符数量与实际提供的参数数量不一致时会发生什么? printf("%d", a, b); // 只输出 a,b 被忽略 具体来说 1. 格式说明符多于参数 int a = 10; printf("%d %d", a); %d 有两个,但只提供了一个参数 第二个 %d 没有对应参数 结果: 输出第一个数字正确(10) 第二个数字随机、可能乱码、甚至导致段错误 本质原因:printf 依赖栈访问参数,如果没提供就读取随机栈值 2. 格式说明符少于参数 int a = 10, b = 20; printf("%d", a, b); %d 只有一个说明符,但提供了两个参数 结果: 只使用第一个参数 a b 被忽略 不会报错,也不会打印 b 3. 参数类型与格式符不匹配 double x = 3.14; printf("%d", x); %d 期望 int,实际传入 double 结果: 输出不可预测 可能出现乱码或错误值 这是 典型未定义行为(Undefined Behavior) ``` ### 16、考察格式化输出 ``` 格式修饰符都有哪些? %d, %3d, %u, %x, %#x, %ld, %f, %lf, %4.2f, %c, %s的含义分别是什么? printf(“%c,%d”, ‘A’,’A’); ``` ``` %d 含义:输出十进制有符号整数(int) %3d 含义:输出宽度至少为 3 的十进制整数,右对齐 若数字不足 3 位,左边补空格 若超过 3 位,直接原样输出 %u 含义:输出无符号十进制整数(unsigned int) 同一块内存,按“无符号”方式解释 %x 含义:以十六进制输出整数(小写字母 a–f) 仅影响显示,不改变变量的值 %#x 含义:以十六进制输出,并自动加前缀 0x 字母仍为小写 %ld 含义:输出 long int 类型的十进制整数 用于 long 型整数 %f 含义:输出浮点数(float / double) 默认 保留 6 位小数 %lf 含义: printf 中:等价于 %f scanf 中:表示读入 double %4.2f 含义: 总宽度至少为 4 小数点后保留 2 位 默认右对齐 %c 含义:输出一个字符 对应 char 类型或字符常量 %s 含义:输出字符串(以 \0 结尾的字符数组) 不输出 \0 printf("%c,%d", 'A', 'A'); %c 'A' 作为字符输出 输出字符:A %d 'A' 实际是字符常量 在 C 语言中,字符本质是整数(ASCII 码) 'A' 的 ASCII 值是 65 实际输出结果: A,65 ``` ### 17、考察数学库 要调用数学函数时,在#include命令行应该包含 **math.h** ### 18、考察表达式运算结果 ``` 问题:int k = a > b; k = ? ``` ``` 若a>b -> true -> 1 k=1 若a>b -> false -> 0 k=0 ``` ### 19、考察switch case ![[image-c37af5b2.png]] ![[image-bd62b477.png]] ### 20、考察字符串比较函数strcmp() ``` 如何通过strcmp函数比较两个字符串? ``` ``` strcmp 函数定义在 头文件中,用于 比较两个字符串。 函数原型: int strcmp(const char *str1, const char *str2); 返回值说明: 返回 0:两个字符串 完全相同 返回 < 0:str1 小于 str2(按 ASCII 码顺序比较) 返回 > 0:str1 大于 str2(按 ASCII 码顺序比较) 注意:strcmp 是区分大小写的。例如 "abc" 和 "ABC" 不相等。 ``` ![[image-fae0ef71.png]] ![[image-2e6d0882.png]] ![[image-03e82a37.png]] ## **二、填空题(共10空,每空1分,共10分)** ### 1、考察三目运算符 **题目**:若定义 `int a=5;` 则表达式 `(a>0 ? a : -a)` 的值为 **5** **考点**: - **语法**:`表达式1 ? 表达式2 : 表达式3` - **解析**: 1. 先判断 `表达式1` (即 `a>0`) 是否为真。 2. 因为 `a=5`,所以 `5>0` 成立(为真)。 3. 取 `表达式2` (即 `a`) 的值作为整个表达式的结果。 4. 如果是假,则取 `表达式3` (`-a`)。 - *注:这其实就是求绝对值的逻辑。* ### 2、考察输入输出 **题目**:scanf()函数的输入项必须是 **地址** ,不能是变量名。 **考点**: - **scanf 原理**:`scanf` 需要修改变量的值,在 C 语言中,要修改一个变量,必须知道它在内存中的位置。 - **解析**: - 错误写法:`scanf("%d", a);` (只传了值,scanf 找不到屋子在哪,没法把东西放进去)。 - 正确写法:`scanf("%d", &a);` (`&` 取地址符,告诉 scanf 变量 `a` 的门牌号)。 - *特例:如果是字符数组(字符串)* `char str[10]`*, 写* `scanf("%s", str)` *是对的,因为数组名本身就是地址。* ### 3、考察字符输入输出 **题目**:getchar()和putchar()函数只能用于 **单个** 字符的输入和输出。 **考点**: - **函数功能差异**: - `printf/scanf`:格式化,可以处理各种类型,可以处理多个。 - `puts/gets`:专门处理字符串(一串字符)。 - `putchar/getchar`:专门处理**单个字符** (char)。 - **解析**:`getchar` 一次只读一个字,`putchar` 一次只打一个字。 ### 4、考察逻辑运算与算术运算 **题目**:若定义“int m=23,n=5;”,则表达式 `!m+m%n` 的值是 **3** **考点**: - **运算符优先级**:`!` (逻辑非) > `%` (取余) > `+` (加法)。 - **逻辑值的数值化**:真为 1,假为 0。 - **解析**: 1. **先算** `!m`:`m` 是 23 (非 0 即为真)。对“真”取反就是“假”。在 C 语言中,**假的值是 0**。所以 `!m` 变成了 `0`。 2. **再算** `m%n`:`23 除以 5`,商 4 余 3。所以 `m%n` 是 `3`。 3. **最后算加法**:`0 + 3 = 3`。 ### 5、考察结构体 **题目**:结构体的每个成员的数据类型可以是基本数据类型,也可以是 **构造** 类型。 **考点**: - **数据类型分类**: - 基本类型:int, float, char 等。 - 构造类型:数组、结构体 (struct)、共用体 (union)。 - **解析**:结构体里可以套娃。比如“学生”结构体里,可以有一个成员是“生日”,而“生日”本身又是一个包含年月日的小结构体。 ### 6、考察sizeof **题目**:使用sizeof()函数计算结构体List的长度的表达式是 **sizeof(struct List)** **考点**: - **sizeof 用法**:`sizeof` 是运算符,不是函数(虽然长得像)。 - **语法**:`sizeof(类型名)` 或 `sizeof(变量名)`。 - **解析**: - 题目说“结构体 List”,通常指的是 `struct List { ... };`。 - 在 C 语言中,引用这个类型时必须带上 `struct` 关键字,即 `struct List`。 - 所以计算大小时写 `sizeof(struct List)`。 > 注:上面的内容是原题,接下来的内容为推测必考点: ### 7、考察基础知识 C语言中, **语句** 是程序最基本的执行单位,以分号结尾。 ### 8、考察基础知识 字符(char)是 **1**,短整(short)是 **2**。 整型(int)、单浮点(float) 都是 **4**。 双浮点(double) 是 **8**。 ### 9、考察字符数组 以下代码段的输出结果是 **China** 。 char ch[20] = {"China\0Beijing"}; printf("%s", ch); ``` sizeof(“hello”)=? ``` ``` 6 末尾有\0 ``` ### 10、考察逻辑运算符和逻辑表达式 ``` int x=33,y=4; !x+x/y=? ``` ``` !33 → 0 0 + x / y 33 / 4 → 8 0 + 8 0 + 8 = 8 结果为 8 ``` ## **三、判断题(共10小题,每小题1分,共10分)** > 注:这部分没明确暗示,把一些没归类好的但90%考的整理进来: switch语句中,各个case和default的出现次序影响执行结果吗? **不影响** long long 占8字节 使用%lld格式化输出 unsigned long long 使用%ull格式化输出 任何程序的结构都可以通过3种基本结构进行组合来实现,分别是 **顺序结构**、**选择结构**和**循环结构**。 c语言本身提供输入输出语句吗? C 语言的“语言本身”不提供输入输出语句;输入输出是由标准库提供的。 - **C 语言核心语法**(如变量、表达式、控制结构、函数定义等)中**没有内建的 I/O 功能**。 也就是说,像 `printf`、`scanf` 这样的函数不是语言内置语句。 - **I/O 由 C 标准库提供** 标准库 `` 中定义了常用的输入输出函数,例如: - `printf()`:格式化输出到标准输出 - `scanf()`:从标准输入读取格式化数据 - `putchar()`、`getchar()`:字符输入输出 - `fopen()`、`fread()`、`fwrite()` 等:文件操作 - **所以:C 语言的 I/O 是“库函数”,而不是“语言关键字或语句”**。 这与一些语言(如 Python 的 `print` 是关键字或内建函数)不同。 ## **四、程序阅读题(共5小题,每小题4分,共20分)** ### 1、考察字符型变量(ASCII码 大小写转换) 非真题:(但由书上两道可能是真题的题目合成) ``` #include int main() { char c1, c2; // 步骤 1:初始化 c1 = 65; // 考点 A:直接赋整数值 c2 = 'b'; // 考点 A:赋字符形式 // 步骤 2:运算(大小写转换) c1 = c1 + 32; // 考点 B:大写转小写 c2 = c2 - 32; // 考点 B:小写转大写 // 步骤 3:输出 printf("%c, %d\n", c1, c1); printf("%c, %d\n", c2, c2); return 0; } ``` 初始化的本质(考点 A) - `c1 = 65;` - **内存视角:** 计算机在 `c1` 里存入二进制的 **65**。 - **理解:** 虽然赋值的是整数,但在 ASCII 码表中,65 对应的就是大写字母 **'A'**。 - `c2 = 'b';` - **内存视角:** 计算机查表找到 'b' 的 ASCII 码是 **98**,存入二进制的 98。 运算逻辑(考点 B) - `c1 = c1 + 32;` - 即 `65 + 32 = 97`。 - 在 ASCII 码性质中,**大写字母 + 32 = 对应的小写字母**。 - 此时 `c1` 变成了 **97**(即字符 **'a'**)。 - `c2 = c2 - 32;` - 即 `98 - 32 = 66`。 - 在 ASCII 码性质中,**小写字母 - 32 = 对应的大写字母**。 - 此时 `c2` 变成了 **66**(即字符 **'B'**)。 输出格式 - **第一行** `printf("%c, %d", c1, c1)`**:** - `%c` 输出 `c1` (97) 对应的字符 \(\rightarrow\) **a** - `%d` 输出 `c1` (97) 对应的数值 \(\rightarrow\) **97** - **第二行** `printf("%c, %d", c2, c2)`**:** - `%c` 输出 `c2` (66) 对应的字符 \(\rightarrow\) **B** - `%d` 输出 `c2` (66) 对应的数值 \(\rightarrow\) **66** **答案:** ``` a, 97 B, 66 ``` ### 2、考察 Sizeof 与 运算符优先级 非真题:(但由书上两道可能是真题的题目合成) ``` #include int main() { int a, b; // 考点 A:混合运算的类型提升(括号内) // 3(int) + 5.0(double) -> 结果类型为 double a = sizeof(3 + 5.0); // 考点 B:优先级与隐式转换(无括号) // sizeof 3 先算,结果再加 5.0,最后赋值给 int b b = sizeof 3 + 5.0; // 考点 C:基本数据类型与字符串(\0) // sizeof(short) vs sizeof("China") printf("%d, %d, %d, %d\n", sizeof(short), a, b, sizeof("China")); return 0; } ``` 1. 基本类型的长度 `sizeof(short)` - **分析**:这是最基础的死记硬背考点。 - **规则**:`short`(短整型)在标准环境下通常占用 **2** 个字节。 - **结果**:输出 **2**。 2. 类型提升陷阱 `a = sizeof(3 + 5.0)` - **分析**:`sizeof` 计算的是**括号内表达式运算结果的数据类型**长度。 - **过程**: - `3` 是整数 (`int`)。 - `5.0` 默认是双精度浮点数 (`double`)。 - **规则**:C 语言运算时,"小类型"往"大类型"靠。`int` + `double` \(\rightarrow\) `double`。 - `double` 类型占用 8 个字节。 - **结果**:输出 **8**。 3. 优先级陷阱 `b = sizeof 3 + 5.0` - **分析**:这里没有括号,拼的是优先级。 - **过程**: 1. **优先级**:`sizeof` 运算符的优先级 **高于** `+` 号。 2. **第一步**:先算 `sizeof 3`。因为 3 是 `int`,所以 `sizeof 3` 等于 **4**。 3. **第二步**:表达式变成了 `4 + 5.0`。结果是 `9.0` (double)。 4. **第三步**:赋值给 `int b`。浮点数 `9.0` 被强制截断为整数 `9`。 - **结果**:输出 **9**。 4. 字符串陷阱 `sizeof("China")` - **分析**:肉眼看到的字符数 vs 实际内存占用。 - **过程**: - 可见字符:C-h-i-n-a (5个)。 - **规则**:字符串常量在内存结束处必须有一个隐形的结束标记 `\0`。 - 计算:5 + 1 = 6。 - **结果**:输出 **6**。 **答案:** ``` 2, 8, 9, 6 ``` ### 3、考察嵌套循环与 Continue 可能是真题 ``` #include int main() { int i, j, n = 0; for(i = 0; i < 2; i++) { n++; for(j = 0; j <= 3; j++) { if(j % 2) continue; n++; } n++; } printf("n = %d\n", n); return 0; } ``` - **考点**:逻辑流程控制,`continue` 跳过谁,`n++` 执行了几次。 - **解析**: - 外层 `i=0`: `n`变成1。进入内层。 - 内层 `j=0`: 偶数不continue,`n`变成2。 - 内层 `j=1`: 奇数continue (跳过n++)。 - 内层 `j=2`: 偶数不continue,`n`变成3。 - 内层 `j=3`: 奇数continue。 - 内层结束。`n`变成4 (外层最后还有个n++)。 - 外层 `i=1`: `n`变成5。重复一遍内层逻辑,`n`加3,变成8。 - **答案**: ``` n= 8 ``` ### 4、考察函数递归 ``` #include void fun(int a,int b) { if(a >= b) printf("%d",a); // 【位置 A】 else fun(a+1, b); // 【位置 B】递归调用 printf("%d",a); // 【位置 C】这是公用的代码!无论 if 还是 else,最后都会执行这一句! } int main() { fun(1,2); return 0; } ``` 第一层:`main` 调用 `fun(1, 2)` - **参数**:`a=1`, `b=2`。 - **判断**:`if(1 >= 2)` 不成立。 - **执行 else**:进入 【位置 B】,调用下一层递归 `fun(2, 2)`。 - *(注意:此时第一层函数**暂停**在这里,等待第二层运行结束,它手里还捏着最后的 【位置 C】 没执行)* 第二层:递归调用 `fun(2, 2)` - **参数**:`a=2`, `b=2`。 - **判断**:`if(2 >= 2)` 成立! - **执行 if**:进入 【位置 A】,**打印** `2`。 - **当前屏幕:**`2` - **继续执行**:`if` 语句结束,程序继续向下走。 - **执行末尾**:到达 【位置 C】,**打印** `2`。 - **当前屏幕:**`22` - **结束**:第二层函数运行完毕,返回上一层。 回到第一层:`fun(1, 2)` - **继续**:刚才在 【位置 B】 等待的递归调用结束了。 - **继续向下**:程序走到最后的 【位置 C】。 - **此时的 a**:在这一层,`a` 仍然是 **1**。 - **执行末尾**:**打印** `1`。 - **当前屏幕:**`221` ![[diagram-1767590037591-b91b5d69.png]] **答案:** ``` 221 ``` ``` #include void fun(int a) { if(!a) printf("%d",a); else fun(a-1); printf("%d",a); } int main() { fun(2); return 0; } ``` ``` 0012 ``` ### 5、考察共用体Union 可能是真题 ``` #include int main() { union { char c; int i; } s; s.c = 'A'; // 内存里写入 65 (0x41) s.i = 2; // 内存里写入 2。因为共用地址,'A' 被覆盖成了 2。 printf("%d%d", s.c, s.i); return 0; } ``` - **共用起始地址**: - `char c` 和 `int i` 并不是分开存放的,而是**从同一个内存地址开始存放**。 - 可以把共用体想象成一个屋子,同一时间只能住一个人。 - **覆盖过程(Timeline)**: - `s.c = 'A'`:内存的第 1 个字节被写入了 65('A'的ASCII码)。 - `s.i = 2`:这里是关键!`int` 占用 4 个字节(包含第 1 个字节)。当你写入整数 `2` 时,系统会将这 4 个字节全部重写(通常是 `00000010 00000000...` 二进制)。 - **结果**:原本那个位置的 'A' (65) 瞬间被整数 `2` 的低位数据覆盖掉了。 - **输出读取**: - `s.c`:去读第 1 个字节 \(\rightarrow\) 发现是 **2**。 - `s.i`:去读整个 4 字节 \(\rightarrow\) 发现是 **2**。 - 所以输出 `2` 和 `2`,即 `22`。 **答案:** ``` 22 ``` ### 6、考察宏定义 可能是真题 ``` #include #define LAB1 0 #define LAB2 2 #include void main() { int temp; #ifdef LAB1 temp=LAB1; #else temp=LAB2; #endif printf("%d",temp); } ``` - **区分** `#ifdef` **和** `#if`: - `#if LAB1`:这是在判断 **真假**。如果代码写的是这个,因为 `LAB1` 是 0(假),确实会跳到 `else`。 - `#ifdef LAB1`:这是在判断 **存在性**(Is Defined?)。它完全不关心 `LAB1` 的值是 0、1 还是 100,它只关心:**“你在前面通过** `#define` **提到过** `LAB1` **这个名字吗?”** - **执行逻辑**: - 第一行 `#define LAB1 0` 已经“注册”了 `LAB1` 这个名字。 - 所以在 `#ifdef LAB1` 时,判定结果为 **“存在”**(真)。 - 编译器会保留 `temp = LAB1;` 这一行代码。 - 即 `temp = 0;`。 - **总结**: - 只要 `#define` 出现过,`#ifdef` 就成立。哪怕你定义的是 `#define LAB1` (后面什么都不写),它也是成立的。 **答案:** ``` 0 ``` ## **五、算法设计题(共2小题,每小题8分,共16分)** ### **1、考察二维数组与循环** 可能是真题: **编程计算n×n的矩阵的两条对角线上所有元素(各元素数值任意)之和** ``` #include #define N 5 // 【改这里】定义矩阵大小,如果是5就是5x5,如果是3就是3*3 int main() { int a[N][N] = { {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 5, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1} }; // int a[N][N] = { // {9, 4, 7}, // {5, 6, 1}, // {8, 3, 2} // }; int sum = 0, i, j; printf("%d x %d 数组:\n", N, N); // 输出矩阵部分 for(i = 0; i < N; i++) { for(j = 0; j < N; j++) printf("%3d", a[i][j]); printf("\n"); } // 计算求和部分 for(i = 0; i < N; i++) { for(j = 0; j < N; j++) { // 核心公式 // 1. i == j 是主对角线 // 2. i + j == N - 1 是副对角线 (3x3时是2, 5x5时是4) if(i == j || i + j == N - 1) { sum = sum + a[i][j]; } } } printf("对角线元素之和为:%d\n", sum); return 0; } ``` ### **2、考察字符串与指针** 可能是真题 编程使用字符指针将26个英文字母以每行10个的形式输出 ``` #include int main() { char *str1, *str2; str1 = "abcdefghijklmnopqrstuvwxyz"; // 遍历字符 for(str2 = str1; str2 < str1 + 26; str2++) { printf("%c ", *str2); // 判断是否换行 // str2-str1 得到的是当前字符的下标(0-25) // +1 是为了变成第几个字符(1-26) if((str2 - str1 + 1) % 10 == 0) printf("\n"); } return 0; } ``` ## **六、程序设计题(共2小题,每小题12分,共24分)** ### **1、考察流程图(循环)** **画出完成如下要求的程序对应的流程图:求两个自然数的最大公约数和最小公倍数** ``` /* 【例 5.17】求两个自然数的最大公约数和最小公倍数 */ #include int main() { int a, b, r, n, m; printf("请输入两个整数:"); scanf("%d%d", &a, &b); m = a; n = b; /* 保存原始数值,因为后面 a 和 b 会变 */ /* 核心算法:辗转相除法 */ do { r = a % b; /* 求余数 */ a = b; /* 把除数 b 变成下一轮的被除数 a */ b = r; /* 把余数 r 变成下一轮的除数 b */ } while (r != 0); /* 当余数不为0时,继续循环;余数为0,结束 */ printf("%d和%d的最大公约数是:%d\n", m, n, a); printf("最小公倍数是:%d\n", m * n / a); return 0; } ``` ![[image-31f8f99d.png]] ### 2、可能还是考察画图(分支) 也可能考察程序 没有明确的暗示 自己掌握好相关知识点