exam-86 试卷整理与详解
这份笔记是根据 86.pdf 整理出来的,原卷文件在本地路径:
/Users/wff/Downloads/86.pdf因为原卷是 PDF 转文字,个别符号和排版有轻微 OCR 误差,我已经按常见 C 语言考试题的写法做了必要整理。对新手来说,你可以把这篇当成:
- 一份试卷答案
- 一份错题整理
- 一份考点复习笔记
1. 这套卷子主要考什么
Section titled “1. 这套卷子主要考什么”这套卷子虽然是综合卷,但高频考点很集中,主要是:
- 数组和字符串
- 函数调用、参数传递、递归
- 二维数组与初始化
- 指针与数组首地址
- 结构体、共用体、枚举、宏
- 位运算基础
- 文件读写基础
- 改错题与程序设计题
如果你是刚学 C 语言的新手,做这套卷子时最容易卡住的点往往不是“不会写代码”,而是:
- 没分清“语法是否正确”和“逻辑是否正确”
- 一看到数组、指针、函数嵌套就容易乱
- 忽略了字符串结尾的
'\0' - 对“传值”和“传地址”还不够敏感
所以这篇详解会特别强调这些点。
2. 答案速查
Section titled “2. 答案速查”2.1 选择题答案
Section titled “2.1 选择题答案”| 题号 | 答案 |
|---|---|
| 1 | D |
| 2 | C |
| 3 | D |
| 4 | A |
| 5 | A |
| 6 | A |
| 7 | A |
| 8 | A |
| 9 | A |
| 10 | B |
| 11 | A |
| 12 | A |
| 13 | C |
| 14 | D |
| 15 | A |
| 16 | A |
| 17 | B |
| 18 | D |
| 19 | D |
| 20 | A |
| 21 | D |
| 22 | B |
| 23 | A |
| 24 | A |
| 25 | B |
2.2 填空题答案
Section titled “2.2 填空题答案”| 题号 | 答案 |
|---|---|
| 1 | 220.000000 |
| 2 | getchar()、c >= 'a' && c <= 'z'、break |
| 3 | 32 |
| 4 | 32767 |
| 5 | p = a |
| 6 | 3 |
| 7 | 0 |
| 8 | gae |
| 9 | 1 |
| 10 | 0 |
2.3 判断题答案
Section titled “2.3 判断题答案”| 题号 | 答案 |
|---|---|
| 1 | Y |
| 2 | N |
| 3 | N |
| 4 | Y |
| 5 | N |
| 6 | Y |
| 7 | Y |
| 8 | Y |
| 9 | Y |
| 10 | N |
3. 选择题详解
Section titled “3. 选择题详解”选择题第 1 题
Section titled “选择题第 1 题”题目整理:
long fun(int n){ long s; if (n == 1 || n == 2) s = 2; else s = n - fun(n - 1); return s;}
printf("%ld\n", fun(3));答案:D
详细解析:
fun(1) = 2fun(2) = 2fun(3) = 3 - fun(2) = 3 - 2 = 1
所以输出结果是:
1容易踩坑点:
- 把递归题看复杂了,其实这里只要一步一步往下代。
- 题面 OCR 中有
|,但这里按题意理解就是判断n==1或n==2。
给新手的建议:
- 递归题不要硬想“整体规律”,先手算
n=1、n=2、n=3。 - 只要有递归,一定先找“结束条件”。
选择题第 2 题
Section titled “选择题第 2 题”题目整理:
char array[] = "China";问:数组 array 占多少字节?
答案:C
详细解析:
"China"有 5 个字符:C h i n a- 字符串常量最后还有一个结束标志
'\0'
所以数组里实际存了 6 个字符:
'C' 'h' 'i' 'n' 'a' '\0'因此占 6 个字节。
容易踩坑点:
- 只数可见字符,忘了
'\0'
给新手的建议:
- 只要看到字符串初始化字符数组,就先自动在脑子里补一个
'\0'
选择题第 3 题
Section titled “选择题第 3 题”题目整理:
exec((v1, v2), (v3, v4, v5), v6);问:实参个数是多少?
答案:D
详细解析:
最外层由逗号分隔的实参有 3 个:
(v1, v2)(v3, v4, v5)v6
括号里的逗号在这里是逗号运算符,不是“再多一个参数”。
所以实参个数是 3。
容易踩坑点:
- 看到所有逗号就乱数,结果把括号里的逗号也算成参数分隔符。
给新手的建议:
- 数函数参数时,只看最外层逗号。
选择题第 4 题
Section titled “选择题第 4 题”题目整理:
strcat(strcpy(str1, str2), str3)答案:A
详细解析:
先执行里面的:
strcpy(str1, str2)作用是:把 str2 复制到 str1
然后整体变成:
strcat(str1, str3)作用是:把 str3 拼接到 str1 后面
所以整个功能就是:
- 先把
str2复制到str1 - 再把
str3连接到str1后面
容易踩坑点:
- 不熟悉
strcpy和strcat的返回值 - 看见函数嵌套调用就慌
给新手的建议:
- 字符串函数题,先把内层函数翻译成中文,再看外层。
选择题第 5 题
Section titled “选择题第 5 题”题目整理:
题面初始化列表 OCR 有轻微误差,按题意可整理为一组非 0 整数,随后用:
while (k[i]){ if (k[i] % 2 == 0 || k[i] % 5 == 0) count++; i++;}答案:A
详细解析:
这题的关键不是每个数字本身,而是两个统计量:
i:最后统计了多少个非 0 元素count:其中多少个数能被 2 或 5 整除
按题面整理,这组数据共有 10 个非 0 元素,其中有 8 个满足条件。
所以输出:
8,10容易踩坑点:
- 忽略了
while(k[i])是“遇到 0 就停” - 把“能被 2 或 5 整除”错看成“同时被 2 和 5 整除”
给新手的建议:
- 遇到这种统计题,最好手工列两列:一列记
i,一列记count
选择题第 6 题
Section titled “选择题第 6 题”题目整理:
int a[3][4];问:哪个引用非法?
答案:A
详细解析:
二维数组 a[3][4] 表示:
- 第一维下标:
0 ~ 2 - 第二维下标:
0 ~ 3
所以:
a[0][4]非法,因为第 2 维最大只能到3- 其他几个都合法
容易踩坑点:
- 只看见
[4]就以为下标能到 4
给新手的建议:
- 数组长度是 4,不代表最后一个下标是 4,最后一个下标是
4 - 1 = 3
选择题第 7 题
Section titled “选择题第 7 题”问:下面说明不正确的是哪一个?
答案:A
详细解析:
A 类似于:
char a[10], *p;p = a = "china";这是错误的,因为:
- 数组名
a不是普通变量 - 数组名不能作为赋值号左边
也就是说:
a = "china";就是错的。
容易踩坑点:
- 把数组名当成普通指针变量
给新手的建议:
- 数组名可以“当地址用”,但它本身不是你能随便重新赋值的变量
选择题第 8 题
Section titled “选择题第 8 题”题目整理:
int a[3][4] = {0};答案:A
详细解析:
这种写法表示:
- 第一个元素初始化为 0
- 剩余元素自动补 0
所以整个二维数组的所有元素都变成 0。
容易踩坑点:
- 以为只有
a[0][0]是 0
给新手的建议:
= {0}是数组初始化里非常常见的一种“全 0 初始化”写法
选择题第 9 题
Section titled “选择题第 9 题”题目整理:
char c[] = "abc";int i = 0;do ;while (c[i++] != '\0');printf("%d", i - 1);答案:A
详细解析:
字符串 "abc" 在内存里其实是:
'a' 'b' 'c' '\0'循环检查过程:
- 第 1 次:
c[0] = 'a',不是'\0',i变成 1 - 第 2 次:
c[1] = 'b',不是'\0',i变成 2 - 第 3 次:
c[2] = 'c',不是'\0',i变成 3 - 第 4 次:
c[3] = '\0',条件不成立,但i++已经执行,所以i变成 4
最后输出 i - 1 = 3
容易踩坑点:
- 忘记
i++是后置自增 - 忘记最后一次判断时虽然退出了,但
i已经加了 1
给新手的建议:
- 遇到
i++和循环一起出现时,最好一轮一轮手算
选择题第 10 题
Section titled “选择题第 10 题”答案:B
详细解析:
B 类似于:
int y[5] = {0, 1, 3, 5, 7, 9};数组长度是 5,但给了 6 个初值,所以错误。
容易踩坑点:
- OCR 会把字符常量、十六进制转义写得有点乱,看花眼
给新手的建议:
- 这种题先数“数组长度”和“初始化元素个数”是否匹配
选择题第 11 题
Section titled “选择题第 11 题”题目整理:
int x[10] = {0, 2, 4};已知 int 占 2 个字节,问数组 x 占多少字节?
答案:A
详细解析:
- 数组有 10 个元素
- 每个
int2 字节
所以总共:
10 × 2 = 20容易踩坑点:
- 只看初始化了 3 个元素,就误以为数组长度是 3
给新手的建议:
- 数组总空间看定义的长度,不看你写了几个初值
选择题第 12 题
Section titled “选择题第 12 题”题目整理:
已定义:
char a[10];问:哪句不能从键盘上给 a 数组的所有元素输入值?
答案:A
详细解析:
A 类似:
a = getchar();这显然不对,因为:
a是数组名- 数组名不能整体赋值
getchar()只读一个字符,也不可能给整个数组赋值
容易踩坑点:
- 把字符数组和字符变量混成一回事
给新手的建议:
char a[10]是一个字符数组,不是一个单独字符
选择题第 13 题
Section titled “选择题第 13 题”题目整理:
char s[12] = "a book!";printf("%d", strlen(s));答案:C
详细解析:
字符串 "a book!" 的长度是:
a1- 空格 1
book4!1
总共 7
strlen() 统计的是字符串长度,不包括 '\0'
容易踩坑点:
- 把数组长度 12 当成字符串长度
- 把
'\0'也算进strlen
给新手的建议:
sizeof看空间strlen看字符串实际长度
选择题第 14 题
Section titled “选择题第 14 题”答案:D
详细解析:
传统 C 语言教材和考试里,一维数组定义时方括号里应写“常量表达式”:
int a[10];所以答案是:
[常量表达式]容易踩坑点:
- 现代编译器里有些支持 VLA(变长数组),但教材题不按这个考
给新手的建议:
- 做考试题时,优先按教材语法标准来答
选择题第 15 题
Section titled “选择题第 15 题”答案:A
详细解析:
二维数组定义时,除了第一维可以省略,后面的维数通常不能省略。
所以:
int a[2][];是错误的。
而:
int a[][2] = {1, 2, 3, 4};是对的,因为第一维可以由初始化个数推断出来。
容易踩坑点:
- 不知道“第一维可以省略,第二维不能省略”这个规则
给新手的建议:
- 二维数组初始化题,先盯住“列数是否明确”
选择题第 16 题
Section titled “选择题第 16 题”答案:A
详细解析:
void 类型函数没有返回值,所以不能把它当成一个有值的表达式来用。
比如:
int x = fun();如果 fun 是 void 函数,就不行。
但把它单独当一条语句调用:
fun();是可以的。
容易踩坑点:
- 把“能调用”误以为“能当表达式”
给新手的建议:
- 一看到
void,就先提醒自己:它不返回结果
选择题第 17 题
Section titled “选择题第 17 题”题目整理:
int a[][3] = {1, 2, 3, 4, 5, 6, 7};问:数组第一维大小是多少?
答案:B
详细解析:
每一行 3 个元素。
把 7 个初值按每行 3 个分组:
- 第 1 行:1, 2, 3
- 第 2 行:4, 5, 6
- 第 3 行:7, 0, 0
所以总共是 3 行。
第一维大小就是 3。
容易踩坑点:
- 以为 7 个元素就要 7 行
给新手的建议:
- 二维数组省略第一维时,先按“每行多少个”分组
选择题第 18 题
Section titled “选择题第 18 题”答案:D
详细解析:
长度为 5 的字符数组,最直接的就是:
char a[] = {'h', 'a', 'b', 'c', 'd'};这里只有 5 个元素,所以数组长度就是 5。
其他选项要么显式给了更大长度,要么因为含有 '\0' 变成 6 个元素。
容易踩坑点:
- 把“字符个数”和“数组长度”混淆
给新手的建议:
- 题目问数组长度,就数元素个数,不要先脑补成字符串
选择题第 19 题
Section titled “选择题第 19 题”答案:D
详细解析:
函数 max(x, y) 返回较大值。
调用:
max(45, 27)结果自然是 45。
容易踩坑点:
- 这题本身不难,但要先忽略 OCR 里的标点小错误
给新手的建议:
- 题目排版有点乱时,先提炼“核心逻辑”
选择题第 20 题
Section titled “选择题第 20 题”答案:A
详细解析:
int a[][3] = {1, 2, 3, 4, 5};这是合法的。
它会按每行 3 个元素去填:
- 第 1 行:1, 2, 3
- 第 2 行:4, 5, 0
而:
B初值太多C两维都省略,错误D第二维省略,错误
容易踩坑点:
- 以为少写几个初值就不合法
给新手的建议:
- 数组初始化时,少写可以自动补 0,多写才是大问题
选择题第 21 题
Section titled “选择题第 21 题”答案:D
详细解析:
题目要“输出前 5 个字符”。
最直接的写法就是:
printf("%.5s", a);%.5s 表示:
- 按字符串输出
- 最多输出 5 个字符
容易踩坑点:
puts(a)会把整个字符串都输出printf("%s", a)也是整个输出
给新手的建议:
printf的格式控制里,.5这种精度写法要熟悉
选择题第 22 题
Section titled “选择题第 22 题”答案:B
详细解析:
函数:
void fun(int a, int b, int c){ a = 456; b = 567; c = 678;}调用时:
fun(x, y, z);这是值传递,所以函数里改的是副本,不是原变量。
因此 x、y、z 还是原来的:
10,20,30容易踩坑点:
- 以为函数里改了参数,外面变量也会跟着变
给新手的建议:
- 只要不是传地址,就默认“外面不会被直接改到”
选择题第 23 题
Section titled “选择题第 23 题”答案:A
详细解析:
A:
int n = 5, a[n];按传统教材和这类考试标准来看,数组长度应是常量表达式,所以这里视为错误。
补充说明:
- 在一些较新的 C 标准和部分编译器里,变长数组(VLA)是允许的
- 但这类教材题一般按“数组长度必须是常量表达式”来判
容易踩坑点:
- 把“现代编译器能跑”和“教材标准答案”混为一谈
给新手的建议:
- 做卷子时,先按老师和教材讲的版本答题
选择题第 24 题
Section titled “选择题第 24 题”题目整理:
static char str[10] = "China";问:数组元素个数为多少?
答案:A
详细解析:
这里数组长度在定义时已经写死为 10,所以元素个数就是 10。
字符串 "China" 只占用前 6 个位置:
'C' 'h' 'i' 'n' 'a' '\0'剩下的位置自动补 0。
容易踩坑点:
- 只数
"China"的字符个数
给新手的建议:
- 只要数组长度显式给出,就以定义长度为准
选择题第 25 题
Section titled “选择题第 25 题”答案:B
详细解析:
先看:
for(i = 0; i < 10; i++) a[i] = i;所以数组 a 变成:
a = {0,1,2,3,4,5,6,7,8,9}再看:
for(i = 0; i < 3; i++) p[i] = a[i * (i + 1)];逐个算:
i=0:p[0] = a[0] = 0i=1:p[1] = a[2] = 2i=2:p[2] = a[6] = 6
所以:
p = {0, 2, 6}最后:
k = 5;k += p[0] * 2; // +0k += p[1] * 2; // +4k += p[2] * 2; // +12所以:
k = 5 + 0 + 4 + 12 = 21答案是 B。
容易踩坑点:
- 没先把数组真正写出来
i*(i+1)心算出错
给新手的建议:
- 这种题一定要把
a和p的每个元素列出来,别硬算
4. 填空题详解
Section titled “4. 填空题详解”填空题第 1 题
Section titled “填空题第 1 题”题目整理:
char c;int n = 100;float f = 10;double x;x = f *= n /= (c = 50);printf("%d%f\n", n, x);答案:220.000000
详细解析:
先算最右边:
c = 50然后:
n /= 50因为 n = 100,所以:
n = 2接着:
f *= n此时 f = 10,n = 2,所以:
f = 20最后:
x = 20所以输出:
220.000000容易踩坑点:
- 没看出复合赋值是从右往左结合
- 忘了
printf("%d%f")中间没有空格
给新手的建议:
- 一看到一长串赋值,先拆成三步四步来算
填空题第 2 题
Section titled “填空题第 2 题”答案:
c = getchar();if (c >= 'a' && c <= 'z') putchar(c - 'a' + 'A');else break;详细解析:
这题功能是:
- 一直输入字符
- 如果是小写字母,就转成大写输出
- 如果不是小写字母,就结束
核心判断条件就是:
c >= 'a' && c <= 'z'容易踩坑点:
- 忘了用
&& - 条件写反
- 写成一个不完整区间判断
给新手的建议:
- 判断字母范围时,直接写成“下限 <= 字符 <= 上限”的拆开版
填空题第 3 题
Section titled “填空题第 3 题”题目整理:
x = (i = 4, j = 6, k = 32);答案:32
详细解析:
逗号表达式的值是最后一个表达式的值。
所以:
(i = 4, j = 6, k = 32)整体值就是 32。
因此:
x = 32;容易踩坑点:
- 以为会把三个值加起来
给新手的建议:
- 逗号表达式就记一句:值看最后一个
填空题第 4 题
Section titled “填空题第 4 题”答案:32767
详细解析:
按传统 16 位 int 的教材环境,最大 int 是:
32767补充提醒:
- 现代大多数电脑上,
int常常是 4 字节,最大值一般是2147483647 - 但考试题要按题目和教材背景来答
给新手的建议:
- 只要题目是老教材环境,像
Turbo C、16 位int这种背景就要跟着题目走
填空题第 5 题
Section titled “填空题第 5 题”答案:p = a
详细解析:
数组名 a 在很多表达式中可看成首元素地址,所以:
p = a;就等价于:
p = &a[0];容易踩坑点:
- 以为一定要写
&a
给新手的建议:
- 一维数组首地址最常见两种写法:
a和&a[0]
填空题第 6 题
Section titled “填空题第 6 题”题目整理:
n = i = 2, ++i, i++;答案:3
详细解析:
按逗号表达式来看:
n = i = 2++i让i变成 3i++的表达式值是 3,然后i才变成 4
整个表达式的值取最后一个子表达式的值,也就是 3
容易踩坑点:
- 把最终值错看成 4
给新手的建议:
i++的“返回值”和“变量最终值”不是一回事
填空题第 7 题
Section titled “填空题第 7 题”题目整理:
int x, y = 4, z = 2;x = y == z;答案:0
详细解析:
先算:
y == z也就是:
4 == 2结果是假,即 0
所以:
x = 0;容易踩坑点:
- 误以为是
x = y
给新手的建议:
- 比较运算
==的结果只有 0 或 1
填空题第 8 题
Section titled “填空题第 8 题”答案:gae
详细解析:
程序比较两个字符串同一位置上的字符,如果相同就输出。
LanguagePrograme同位置相同的字符是:
gae
所以输出:
gae容易踩坑点:
- 没看出是在“同一位置比较”
给新手的建议:
- 字符串比较题,最稳的办法是把下标和字符一个一个对齐写出来
填空题第 9 题
Section titled “填空题第 9 题”答案:1
详细解析:
题面 OCR 有轻微误差,按常见写法可理解为:
x = 2 && 2 || 15 > 1;先算:
2 && 2为真,结果 115 > 1为真,结果 11 || 1结果还是 1
所以 x = 1
容易踩坑点:
- 对逻辑运算优先级不熟
给新手的建议:
- 逻辑题不会时就手动加括号
填空题第 10 题
Section titled “填空题第 10 题”答案:0
详细解析:
C 语言数组下标从 0 开始。
例如:
int a[5];合法下标是:
0 1 2 3 4给新手的建议:
- “数组下标从 0 开始”是 C 语言最基础也最容易反复出错的点之一
5. 判断题详解
Section titled “5. 判断题详解”判断题第 1 题
Section titled “判断题第 1 题”题目:共用体变量所占内存长度等于最长成员长度。
答案:Y
解析:
按教材和考试标准,这样判断是对的。共用体各成员共用同一块存储空间,所以空间大小通常按最长成员来确定。
容易踩坑点:
- 标准实现里还可能受对齐影响,但考试一般不深究
新手建议:
- 做卷子按教材口径答:结构体“各成员分开存”,共用体“共用一块存”
判断题第 2 题
Section titled “判断题第 2 题”题目:宏定义 #define S(a,b) t=a; a=b; b=t 因为 t 未定义,所以宏定义错误。
答案:N
解析:
宏定义本身只是替换规则,不会在定义时检查 t 是否定义。
所以“宏定义本身错误”这个说法不对。
但真正使用时,如果展开后 t 没定义,程序当然会出错。
判断题第 3 题
Section titled “判断题第 3 题”题目:宏名必须使用大写字母表示。
答案:N
解析:
大写只是习惯,不是语法强制要求。
判断题第 4 题
Section titled “判断题第 4 题”题目:在 Turbo C 中,long int 占 4 个字节。
答案:Y
解析:
按传统 Turbo C 环境,这是正确的。
判断题第 5 题
Section titled “判断题第 5 题”题目:char array[] = "hello"; 数组占 5 个字节。
答案:N
解析:
还要加结尾的 '\0',所以是 6 个字节。
判断题第 6 题
Section titled “判断题第 6 题”题目:被调用函数定义在主调函数之前时,可以不声明。
答案:Y
解析:
如果函数定义已经出现在前面,那么编译器已经知道它了,就不必再额外声明。
判断题第 7 题
Section titled “判断题第 7 题”题目:
int a[3][3] = {{3,5},{8,9},{12,35}}, i, sum = 0;for(i = 0; i < 3; i++) sum += a[i][2 - i];判断 sum == 21
答案:Y
解析:
数组补全后:
{3, 5, 0}{8, 9, 0}{12, 35, 0}求的是:
a[0][2] = 0a[1][1] = 9a[2][0] = 12
和为:
0 + 9 + 12 = 21判断题第 8 题
Section titled “判断题第 8 题”题目:整数 -32100 可以赋给 int 和 long int
答案:Y
解析:
在 16 位有符号 int 环境下,范围是 -32768 ~ 32767,所以 -32100 能放下。
判断题第 9 题
Section titled “判断题第 9 题”题目:a = (b = 4) + (c = 6) 是合法赋值表达式。
答案:Y
解析:
赋值表达式本身有值,所以当然可以参与更大的表达式。
判断题第 10 题
Section titled “判断题第 10 题”题目:有调用关系的所有函数必须放在同一个源程序文件中。
答案:N
解析:
函数可以分布在多个源文件中,只要声明和链接正确就行。
6. 改错题详解
Section titled “6. 改错题详解”功能:输入 10 个学生成绩,求最高分、最低分、平均分。
题目给出的 3 处错误分别是:
- 数组长度写成了 8,应该是 10
scanf("%f", a);应该改成scanf("%f", &a[i]);- 最小值判断方向写反了
我给你一份整理后的完整正确代码:
#include <stdio.h>
int main(void){ int i; float a[10], min, max, avg;
printf("input 10 score:\n"); for (i = 0; i < 10; i++) { printf("input a score of student: "); scanf("%f", &a[i]); }
max = min = avg = a[0]; for (i = 1; i < 10; i++) { if (min > a[i]) min = a[i]; if (max < a[i]) max = a[i]; avg += a[i]; }
avg /= 10;
printf("max:%f\nmin:%f\navg:%f\n", max, min, avg); return 0;}详细解析:
float a[10]:题目要求输入 10 个成绩,所以数组长度必须是 10scanf("%f", &a[i]):要把每次输入读到第i个元素中- 求最小值时应该是:
if (min > a[i])而不是反过来
容易踩坑点:
scanf忘记写地址符号&- 最值题里
>和<写反 - 平均值累加时忘记把第一个元素算进去
给新手的建议:
- 最值和平均值题是最典型的入门题,建议你自己手写一遍模板
功能:利用级数求圆周率近似值
题意:
π / 4 = 1 - 1/3 + 1/5 - 1/7 + ...题目给出的 4 处错误分别是:
#include <stdlib.h>应改为#include <math.h>s、t、p应为浮点型- 循环条件写反了
printf的格式说明符写错了
整理后的正确代码:
#include <stdio.h>#include <math.h>
void fun(void){ int i = 1; double s = 0, t = 1, p = 1;
while (fabs(t) > 1e-4) { s += t; p = -p; i += 2; t = p / i; }
printf("pi=%f\n", s * 4);}
int main(void){ fun(); return 0;}详细解析:
fabs()是浮点绝对值函数,头文件应该是math.h- 级数求和是小数运算,所以
s、t、p不能用int - 题目要求“直到最后一项绝对值小于等于 0.0001 为止”,所以当它还大于
1e-4时就继续循环 - 最终输出是浮点数,所以要用
%f
容易踩坑点:
- 用整型存小数,结果全部被截断
- 把循环终止条件写反
- 忘了
fabs()对应math.h
给新手的建议:
- 级数题先别急着看 π,先看“每一项怎么变”
1 - 1/3 + 1/5 - 1/7这种交错正负的题,最好单独拿个变量p控制符号
7. 程序设计题详解
Section titled “7. 程序设计题详解”程序设计 1
Section titled “程序设计 1”题目要求:
- 输入 10 个学生成绩
- 计算平均成绩
ave - 统计及格人数
pass - 统计高于平均分的人数
better - 对 10 个成绩进行排名
一份完整可运行的参考答案:
#include <stdio.h>
#define N 10
int main(void){ int i, j, a[N], ave, sum = 0, pass = 0, better = 0, t;
printf("请输入 10 个学生成绩:\n"); for (i = 0; i < N; i++) { scanf("%d", &a[i]); sum += a[i]; }
ave = sum / N;
for (i = 0; i < N; i++) { if (a[i] >= 60) pass++; if (a[i] > ave) better++; }
for (i = 0; i < N - 1; i++) { for (j = i + 1; j < N; j++) { if (a[i] < a[j]) { t = a[i]; a[i] = a[j]; a[j] = t; } } }
printf("平均分:%d\n", ave); printf("及格人数:%d\n", pass); printf("高于平均分人数:%d\n", better); printf("成绩从高到低排序:"); for (i = 0; i < N; i++) printf("%d ", a[i]); printf("\n");
return 0;}详细解题过程:
第一步,输入并求总分:
for (i = 0; i < N; i++){ scanf("%d", &a[i]); sum += a[i];}第二步,求平均分:
ave = sum / N;第三步,统计及格人数和高于平均分人数:
for (i = 0; i < N; i++){ if (a[i] >= 60) pass++; if (a[i] > ave) better++;}第四步,排序:
这里用的是最直接的交换排序思想,让分数从高到低排列。
容易踩坑点:
for(j=i+1;j<N,j++)这种地方原卷 OCR 容易把分号识别成逗号- 排序时交换语句漏写
- 统计完平均分前就先比较
a[i] > ave
给新手的建议:
- 综合题一定拆成小步骤做,不要想一口气写完
- 输入、统计、排序、输出,这四块分开写最稳
程序设计 2
Section titled “程序设计 2”题目要求:
求一个大于 10 的 n 位整数的后 n-1 位的数,并作为函数值返回。
通俗一点说,就是:
- 输入一个整数
- 去掉最高位
- 把剩下的数返回
例如:
1234 -> 23456789 -> 6789
参考答案:
#include <stdio.h>
int fun(int w){ int n = 0; int i = 1;
while (w > 10) { n = n + i * (w % 10); w /= 10; i *= 10; }
return n;}
int main(void){ int w;
printf("请输入一个大于 10 的整数:"); scanf("%d", &w);
printf("结果是:%d\n", fun(w)); return 0;}详细解题过程:
比如输入:
1234循环过程:
- 取个位
4,放入n - 去掉个位,剩下
123 - 再取个位
3,拼到前面结果后 - 再取
2 - 当只剩最高位
1时停止
于是最后得到:
234为什么 while (w > 10)?
因为题目要求去掉最高位,只保留后 n-1 位,所以当 w 还不止一位时就继续拆。
容易踩坑点:
- 把条件写成
w >= 10会影响边界 i *= 10忘写,结果数字拼接位置不对- 把
w % 10和w / 10的作用混淆
给新手的建议:
- 这种数字拆位题,建议你先拿
1234、5607这种例子手工模拟 - 如果以后想保留前导 0,比如
1005 -> 005,那就要换成字符串思路,单纯整数返回会丢掉前导 0
8. 这套卷子最容易暴露的问题
Section titled “8. 这套卷子最容易暴露的问题”如果你现在是刚学 C 语言的新手,这套卷子做下来,最容易暴露出下面这些问题:
- 字符串长度和数组长度分不清
- 数组初始化规则不熟
- 函数传值和传地址分不清
- 递归题不会手推
scanf、getchar、strlen、strcpy、strcat这些常见函数还不够熟- 排序题能看懂但自己写不出来
- OCR 或卷面稍微乱一点,就容易被格式干扰
9. 给新手的复习建议
Section titled “9. 给新手的复习建议”- 先把这套卷子里的数组题、字符串题、函数题各挑 3 题重新手写一遍。
- 选择题不要只背答案,要会说“为什么其他选项错”。
- 填空题尤其要自己手敲,像
getchar()、break、p=a这种都是高频基础。 - 改错题很值得反复看,因为它正好对应新手最常犯的真实错误。
- 程序设计题不要怕长,把题目拆成输入、处理、输出三个阶段就会好很多。
10. 最后总结
Section titled “10. 最后总结”这套 exam-86 卷子本质上考的不是“特别难的新知识”,而是你对 C 语言基础有没有真正掌握:
- 基本语法稳不稳
- 数组和字符串熟不熟
- 函数和参数传递清不清楚
- 能不能把一个完整小题拆开做
如果你能把这篇详解看懂,并且自己再手写一遍里面的改错题和程序设计题,那你对前面 C 语言基础章节的理解会扎实很多。