夜雨聆风学习资料网

ARTICLE · 1008076

2026年9月 GESP C++ 一级真题解析:把"读程序"练成条件反射

2026年9月 GESP C++ 一级真题解析:把"读程序"练成条件反射

一级整卷难度不高,但读程序写结果的题占了 11 道。一级考的不是知识点有多深,而是"你能不能准确模拟计算机执行"。


一、答案速查

题号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
单选
C
D
A
A
B
C
D
A
C
D
D
B
A
A
D

判断题官方未公布答案,以下为按题意推算的参考答案(详见第四部分)。


二、单选题:四个模块,逐个击破

模块 1:计算机基础(第 1、2 题)

第 1 题 → C

四个选项都是 IDE 的常见功能,唯独"C. 可以直接控制机器人电机转动"越界了——IDE 只负责编写、编译、调试代码,真正控制电机的是编译后的程序加硬件驱动。

这道题在二级第 1 题原样又出了一遍。属于"送分题",但每年都有人错。

第 2 题 → D

计算机四个时代的划分依据是核心元器件:电子管 → 晶体管 → 中小规模集成电路 → 大规模/超大规模集成电路。

易错项是"运算速度"——速度是结果,元器件才是依据。

模块 2:表达式与运算符(第 3、4、6、7 题)

第 3 题 → A:int a = 4 + -2 * 3;先算乘法 -2 * 3 = -6,再算加法 4 + (-6) = -2。

第 4 题 → A:与 2 * -2 % 3 值相同的是 (2 * -2) % 3关键两点:① 乘号 * 与取余 %优先级相同,从左到右算;② C++ 中负数取余结果为负。

2 * -2 % 3   →  (2 * -2) % 3  =  -4 % 3  =  -1
  • B. 2 * (-2 % 3) = 2 * (-2) = −4
  • C. 2 * -(2 % 3) = 2 * (-2) = −4
  • D. 2 % -2 * 3 = 0 * 3 = 0

第 6 题 → C:a = 8, b = 10

cout << (a % b) << ” ” << (a * 1 / b) << ” ” << (a * 1.0 / b);
  • a % b
     = 8 % 10 = 8
  • a * 1 / b
     = 8 / 10 = 0(整数除法,直接截断)
  • a * 1.0 / b
     = 8.0 / 10 = 0.8(出现浮点数即触发浮点除法)

输出 8 0 0.8。"整数除法截断"是一级最高频的失分点。

第 7 题 → D:int b = 8; ++b *= 2 + 1;先处理前缀自增:++b → b 变成 9;再算 2 + 1 = 3;最后 9 = 3 →27。(= 的右操作数是整个 2 + 1,不是 2。)

模块 3:循环与控制(第 8、9、10、11、13 题)

第 8 题 → A

for (i = 0; i < 10; i++) cnt += 1;cout << i << ' ' << cnt;

循环执行 10 次,cnt = 10;循环结束时 i 增到 10(不满足条件才退出)。输出 10 10。

第 9 题 → C

for (i = -10; i < 0; i++) cnt += 1;   // cnt 最终 = 10cout << (i * cnt);

i 从 −10 到 −1,共 10 次;退出时 i = 0。所以 i * cnt = 0 * 10 =0。

第 10 题 → D

int i;for (i = 1; i < 5; i++) {    if (i % 3 == 0) { printf(”%d+”, i); continue; }    else            { printf(”%d-”, i); break; }}printf(”%dEND*”, i);
  • i = 1
    :1 % 3 != 0 → 走 else,输出 1-,break 直接终止整个循环,i 保持 1;
  • 循环后输出 1END*。合起来是 1-1END*,选 D。

第 11 题 → D(选"错误的")

int N, tot;  cin >> N;  tot = 0;while (N > 0) { cout << N << ”#”; tot += 1; N -= 1; }cout << tot << ”-END”;

程序会从 N 倒数打印到 1,最后输出循环次数 tot(等于 N)。

  • A:输入 3 → 3#2#1#3-END ✔ 正确
  • B:输入 −10 → 循环不执行,tot = 0 → 0-END ✔ 正确
  • C:输入 0 → 同理输出 0-END ✔ 正确
  • D:输入 1 → 实际是 1#1-END,而非 1#0-END ✘ 错误

第 13 题 → A

int k = 0;while (k < 8) { k += 2; continue; if (k > 5) break; cout << k << ”#”; }if (k >= 8) cout << ”FINISH”;

continue 让 cout 和 break永远不会被执行。k 依次为 2、4、6、8,到 8 时退出循环,输出 FINISH。

这是一道"死代码"题:读懂 continue 的位置,答案就一目了然。

模块 4:数位与"填空"题(第 12、14 题)

第 12 题 → B:"%3d", N - i输出样例每个数字占 3 列右对齐,且每 10 个换行。循环 i 从 0 到 N−1,每次应输出 N - i,所以填 "%3d", N - i。

第 14 题 → A:N / M10 % 10M10 = 10^(M-1),所以 N / M10 把要取的那一位挪到个位,再 % 10 取出来。

记牢这个万能模板:取从右往左第 M 位 = N / 10^(M-1) % 10。

模块 5:鸡兔同笼改错(第 15 题)→ A

for (tu_tou = 0; tu_tou < tou + 1; tu_tou++) {   // L1    ji_tou = tou - tu_tou;    if (tu_tou * 4 + ji_tou * 2 == jiao) { ...; break; }}if (tu_tou == tou) printf(”无解\n”);            // L2
  • A 对:程序本身能正确求解。
  • B 错:ji_tou 在循环体内马上被 tou - tu_tou 赋值,不需要额外初始化。
  • C 错:把 tu_tou < tou + 1 改成 tu_tou < tou,会漏掉"全是兔子"(tu_tou = tou)的情况。
  • D 错:无解时 tu_tou 恰好停在 tou,改成 tou + 1 则永远不输出"无解"。

三、判断题(10 题)

参考答案:√ × × √ √ √ √ × × ×

题
判
关键依据
1
√
cin / scanf
 从标准输入(键盘)读数据
2
×
123 % 100 = 23
,取到的是后两位,不是最高位
3
×
循环结束时 i = 21,输出 21 而非 20
4
√
10 > 10
 为假 → 走 else,输出"10 小于 10"
5
√
while (N > 0) { tot += N; N += -1; }
 即 1+2+…+N
6
√
2 % 2 = 0
,(-2) % 2 = 0,两数相同
7
√
z = 3.0 → z-- = 2.0 → cout << z++
 输出 2
8
×
_
 和 __ 是两个不同的合法标识符,不会冲突
9
×
27 % 12 = 3
,赋给 double 得 3.0,结果确定
10
×
实际输出是 4(1+3=4;idx=5 被 continue,idx=7 触发 break)

两道最容易做错的

  • 第 8 题:不少人以为"下划线多了会混淆",其实 _、__、___ 都是独立合法的标识符。
  • 第 10 题:continue 跳过的正是 idx = 5 那一次,所以 5 不加;idx = 7 时 7*7 = 49 > 30 触发 break。答案是 4,不是 3、也不是 8。

四、编程题

4.1 新龟兔赛跑

题意:距离固定为 1000。输入三行浮点数:乌龟全程用时 t1、兔子速度 v、兔子睡觉时长 t2。求谁赢,并输出兔子总用时(保留两位小数)。

解题思路

float t1, v, t2;cin >> t1 >> v >> t2;float tt = 1000.0 / v + t2;      // 兔子:跑的时间 + 睡觉时间if      (tt < t1) printf(”rabbit\n”);else if (tt > t1) printf(”turtle\n”);else              printf(”tie\n”);printf(”%.2f\n”, tt);

三个关键点

  1. 浮点数比较必须写三种情况:小于、大于、等于(平局 tie)。漏掉 tie 就丢分。
  2. .0
     不能省:写 1000 / v 会变成整数除法(若 v 为整数类型),必须写 1000.0 / v。
  3. %.2f
     输出两位小数,不能用 cout 默认输出(会丢掉末尾的 0,例如 21.0 而非 21.00)。

样例:20.0 / 100.0 / 11.0 → tt = 10 + 11 = 21.00 > 20 → 输出 turtle 和 21.00。

4.2 棋盘上的奖赏

题意:第 1 格 1 粒,以后每格翻倍(第 i 格 2^(i-1) 粒),求前 n 格总粒数。

核心公式

$$\text{总粒数} = 1 + 2 + 4 + \dots + 2^{n-1} = 2^{n} - 1$$

解法一:倍增累加(推荐,贴合考纲)

long long f = 1, ans = 0;for (int i = 1; i <= n; i++) {    ans += f;      // 累加当前格的麦粒    f *= 2;        // 每格翻倍}printf(”%lld\n”, ans);

解法二:位运算(更快,但要注意溢出)

ans = (1LL << n) - 1;   // 注意 1LL,用 1 会溢出

关键点

  1. 必须用 long long。n 稍大时 2^n 就会超过 int 范围(int 最大约 2.1×10⁹,即 2^31-1)。
  2. 循环里先累加再翻倍,顺序不能反,否则会多算一格。
  3. 数据范围决定算法:n 到 30 左右,两种写法都行;n 到 60 以上,位运算写法更省事,但仍需 long long。

五、一级划重点

必须掌握
典型场景
运算符优先级
4 + -2 * 3
、2 * -2 % 3
整数除法截断
8 / 10 = 0
、8 * 1.0 / 10 = 0.8
自增与复合赋值
++b *= 2 + 1
循环结束后的变量值
for (i = 0; i < 10; i++)
 结束后 i = 10
continue
 / break 的作用范围
第 10、13 题
取数位模板
N / 10^(M-1) % 10
浮点比较与格式化输出
%.2f
、三种分支

相关学习资料