记忆(全是原题)
题型分布
一、选择题(共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
- 解析:
- 第一次执行循环体:打印
n(3),然后n自减变为 2。 - 判断条件:
while(!n)即while(!2)。在 C 语言中,2 是真,!2就是假 (0)。 - 结果:条件为假,循环终止。
- 所以屏幕上只输出了一个 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为假,循环正常结束。
- A:
5、考察循环语句的特性
题目:下列关于循环语句 for、while、do-while 的叙述中正确的是________
A、三种循环语句都可能出现无穷循环
B、三种循环语句中都可以缺省循环终止条件表达式
C、三种循环语句的循环体都至少被无条件地执行一次
D、三种循环语句的循环体都必须放入一对花括号中
- 解析:
- A: 正确。只要条件设置不当(如
while(1)),三种循环都可能死循环。 - B: 错误。
for(;;)可以缺省条件,但while()和do-while()的括号内必须有表达式(哪怕是常数 1)。 - C: 错误。
for和while是“先判断后执行”,可能一次都不执行。只有do-while至少执行一次。 - D: 错误。如果循环体只有一条语句,花括号
{}可以省略。
- A: 正确。只要条件设置不当(如
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}—— 错误。函数形参只是声明,不能在参数列表中进行初始化赋值。
- B:
7、考察文件
题目:下列函数中,可以把整型数据以二进制形式写入文件中的函数是________
A、fputc() B、fwrite()
C、fread() D、fgetc()
- 解析:
- B:
fwrite()—— 专门用于二进制块读写的函数。 - A:
fputc()—— 写入单个字符(文本模式)。 - C/D:
fread()/fgetc()—— 都是读取函数,不是写入。
- B:
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)。 - 它不是字符串(没有双引号),也不是变量。虽然它代表一个双精度数,但“符号常量”是更准确的定义分类。
- 在 C 语言术语中,用
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。
- 错误原因:自增运算符
- 宏定义是纯文本替换。预处理阶段会将代码中所有的
注:上面的内容是原题,接下来的内容为推测必考点:
11、考察标识符
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
20、考察字符串比较函数strcmp()
如何通过strcmp函数比较两个字符串?
strcmp 函数定义在 <string.h> 头文件中,用于 比较两个字符串。
函数原型:
int strcmp(const char *str1, const char *str2);
返回值说明:
返回 0:两个字符串 完全相同
返回 < 0:str1 小于 str2(按 ASCII 码顺序比较)
返回 > 0:str1 大于 str2(按 ASCII 码顺序比较)
注意:strcmp 是区分大小写的。例如 "abc" 和 "ABC" 不相等。
二、填空题(共10空,每空1分,共10分)
1、考察三目运算符
题目:若定义 int a=5; 则表达式 (a>0 ? a : -a) 的值为 5
考点:
- 语法:
表达式1 ? 表达式2 : 表达式3 - 解析:
- 先判断
表达式1(即a>0) 是否为真。 - 因为
a=5,所以5>0成立(为真)。 - 取
表达式2(即a) 的值作为整个表达式的结果。 - 如果是假,则取
表达式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。
- 解析:
- 先算
!m:m是 23 (非 0 即为真)。对“真”取反就是“假”。在 C 语言中,假的值是 0。所以!m变成了0。 - 再算
m%n:23 除以 5,商 4 余 3。所以m%n是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)。
- 题目说“结构体 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 标准库提供
标准库
<stdio.h>中定义了常用的输入输出函数,例如:printf():格式化输出到标准输出scanf():从标准输入读取格式化数据putchar()、getchar():字符输入输出fopen()、fread()、fwrite()等:文件操作
- 所以:C 语言的 I/O 是“库函数”,而不是“语言关键字或语句”。
这与一些语言(如 Python 的
print是关键字或内建函数)不同。
四、程序阅读题(共5小题,每小题4分,共20分)
1、考察字符型变量(ASCII码 大小写转换)
非真题:(但由书上两道可能是真题的题目合成)
#include <stdio.h>
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 <stdio.h>
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;
}
- 基本类型的长度
sizeof(short)
- 分析:这是最基础的死记硬背考点。
- 规则:
short(短整型)在标准环境下通常占用 2 个字节。 - 结果:输出 2。
- 类型提升陷阱
a = sizeof(3 + 5.0)
- 分析:
sizeof计算的是括号内表达式运算结果的数据类型长度。 - 过程:
3是整数 (int)。5.0默认是双精度浮点数 (double)。- 规则:C 语言运算时,"小类型"往"大类型"靠。
int+double\(\rightarrow\)double。 double类型占用 8 个字节。
- 结果:输出 8。
- 优先级陷阱
b = sizeof 3 + 5.0
- 分析:这里没有括号,拼的是优先级。
- 过程:
- 优先级:
sizeof运算符的优先级 高于+号。 - 第一步:先算
sizeof 3。因为 3 是int,所以sizeof 3等于 4。 - 第二步:表达式变成了
4 + 5.0。结果是9.0(double)。 - 第三步:赋值给
int b。浮点数9.0被强制截断为整数9。
- 优先级:
- 结果:输出 9。
- 字符串陷阱
sizeof("China")
- 分析:肉眼看到的字符数 vs 实际内存占用。
- 过程:
- 可见字符:C-h-i-n-a (5个)。
- 规则:字符串常量在内存结束处必须有一个隐形的结束标记
\0。 - 计算:5 + 1 = 6。
- 结果:输出 6。
答案:
2, 8, 9, 6
3、考察嵌套循环与 Continue
可能是真题
#include<stdio.h>
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<stdio.h>
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
- 当前屏幕:
答案:
221
#include<stdio.h>
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<stdio.h>
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<stdio.h>
#define LAB1 0
#define LAB2 2
#include<stdio.h>
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 <stdio.h>
#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<stdio.h>
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 <stdio.h>
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;
}
2、可能还是考察画图(分支) 也可能考察程序
没有明确的暗示
自己掌握好相关知识点
💬 评论