2026年9月 GESP C++ 二级真题解析:循环是主角,转换是配角

四季读书网 12 0

2026年9月 GESP C++ 二级真题解析:循环是主角,转换是配角

二级这张卷,"多层循环"和"数据类型转换"两条线贯穿始终。读懂这两个板块,70% 的分数就稳了。


一、答案速查

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

判断题官方未公布答案,以下为按题意推算的参考答案。


二、单选题:五个板块

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

第 1 题 → C:与一级第 1 题完全相同——IDE 的功能边界(不能直接控制硬件)。

第 2 题 → B:Cache 的正确定位是"暂存 CPU 频繁访问的数据"。

选项
判断
理由
A
Cache 容量比主存小得多,速度比主存快
B
缓存热点数据,弥补 CPU 与主存的速度差
C
Cache 是易失性存储器,断电即失
D
速度排序:寄存器 > Cache > 主存

一句话记忆寄存器最快最小 → Cache 次之 → 主存最慢最大,且 Cache 是易失的。

板块 2:类型转换与布尔运算(第 3、4 题)

第 3 题 → A:cout << (3 == 3.0);比较时 int 3 会隐式提升为 double 3.0,3 == 3.0 成立,输出 1。

陷阱:有人以为"整数和浮点数不能直接比较",实际上 C++ 会自动做类型提升。

第 4 题 → D:cout << (bool(5) + bool(-5) + bool(5.0));bool 转换规则:非 0 即真。5、−5、5.0 全部为真 → 1 + 1 + 1 = 3。

关键点bool 参与算术运算时会提升为 inttrue 当 1、false 当 0 用。

板块 3:逻辑表达式与分支(第 5、9 题)

第 5 题 → A:闰年条件

(N % 4 == 0 && N % 100 != 0) || (N % 400 == 0)
  • B 错在缺括号&& 优先级高于 ||N % 4 == 0 && N % 100 == 0 || N % 400 == 0 会先算前半段,逻辑不成立;
  • C 用 / 代替 %,完全错(N / 4 == 0 只有 N 很小时才成立);
  • D 用了 && 连接两个互斥条件,永远为假

闰年判断是"必考级"知识点,% 和括号一个都不能错。

第 9 题 → B:for (i = -5; i < 5; i++) if (not(i % 3 != 0)) tot += 1;

not(x) 等价于 !x。先看内层:i % 3 != 0 为真表示"i 不是 3 的倍数";再取 not → 条件变成"i 是 3 的倍数"。

i 取 −5 ~ 4 中 3 的倍数:−3、0、3 →3 个

这类题不用逐个数,先把逻辑表达式化简,再找满足条件的数。

板块 4:多层循环(第 6、7、8、11、12 题)

第 6 题 → C

for (i = 0; i < 10; i++) if (i) tot += 1;

if (i) 表示 i != 0。i = 1~9 共9次。

if (i) 就是 if (i != 0),这是 C++ 的简写习惯,必须一眼看懂。

第 7 题 → B(n = 4)

for (i = 1; i < n; i++)          // i = 123    for (j = 1; j < i; j++)      // i=10次  i=21次  i=32        tot += 1;

总数 = 0 + 1 + 2 =3

结果是 C(n-1, 2),n = 4 时为 3。

第 8 题 → D

for (i = 0; i < 10; i++) if (i % 3) tnt += i;

i % 3 非 0 即 i 不是 3 的倍数:1、2、4、5、7、8 → 和 =27

第 11 题 → D

i = 1;while (i <= 3) { for (j = 1; j < i + 1; j++) total += i * j; i += 1; }
  • i = 1:1×1 = 1 → total = 1
  • i = 2:2×1 + 2×2 = 6 → total = 7
  • i = 3:3×1 + 3×2 + 3×3 = 18 → total = 25

第 12 题 → C(输出 4 1 2)

for (i = 1; i < 4; i++)    for (j = 0; j < i; j++) {        if (j % 3 == 0continue;      // j=0 时直接跳过        count += 1;        if (i * j >= 2break;    }printf(”%d %d %d”, i, j, count);
  • i = 1:只有 j = 0,被 continue 跳过 → count 不变
  • i = 2:j = 0 跳过;j = 1 → count = 1,2×1 ≥ 2 → break
  • i = 3:j = 0 跳过;j = 1 → count = 2,3×1 ≥ 2 → break
  • 循环变量:外层走完后 i = 4,内层最后一次 break 时 j = 1

输出 4 1 2。

注意for 循环结束后,内层变量保留的是最后一次执行时的值,外层变量则是超出边界的值

板块 5:填空与算法应用(第 10、13、14、15 题)

第 10 题 → D(选"错误的"):素数判定程序的边界分析

limit = sqrt(n) + 1;for (i = 2; i < limit; i++)    if (n % i == 0) { printf(”%d 非素数”, n); break; }if (i >= limitprintf(”%d 是素数”, n);
  • A ✔:n <= 1 分支不能省,否则 0、1 会被误判为素数;
  • B ✔:省略 n == 2 分支后,n = 2 走 else,limit = 1 + 1 = 2,循环不执行,i = 2 >= 2 成立,仍输出"2 是素数",结果不变;
  • C ✔:break 不能省,否则非素数会继续循环到 i >= limit,被误判为素数;
  • D ✘ 错误:把 +1 改成很大的数(比如 100)时,limit 可能超过 n,循环会枚举到 i = n,此时 n % n == 0 成立,素数会被误判为合数

这是二级最有区分度的一道题。它考的不是"会不会写素数判定",而是能不能分析边界

第 13 题 → A:line - j - 1

输出图形共 12 行,第 0 行前有 11 个空格、第 1 行前有 10 个……最后一行前 0 个空格。

空格数 = 总行数 - 1 - 当前行号 = line - j - 1

这是"居中图形"的标准公式:每行先补空格,再打字符。二级几乎每场都会出现这类图形题——2026 年 6 月是矩形边框的条件填空,本次是居中数字塔,2025 年则考过等腰三角形。换个图形、换个字符,内核都是同一个双重循环模型。

第 14、15 题 → 均为 A(同一情境的两种代码版本)

场景:找"身高最接近 1.65 米"的小朋友,若差值相同则取较矮的那个。

版本一(单横线)

if (diff < min_diff || (diff == min_diff && h < best_height)) {    min_diff = diff;    best_height = h;}

版本二(else-if 分支)

if (diff < min_diff) { min_diff = diff; best_height = h; }else if (diff == min_diff) { if (h < best_height) best_height = h; }

两个关键点

  1. 差值更小 → 一定更新diff < min_diff);
  2. 差值相等时,只更新更矮的h < best_height)——这就是"取较矮的第一个"的实现。

干扰项 diff <= min_diff && h < best_height 错在:差值相等但身高更高时也会被排除,逻辑不完整。


三、判断题(10 题)

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

关键依据
1
cin / scanf
 从标准输入(键盘)读取
2
5 && 2
 逻辑与:两边非 0 → 结果为真,输出 1
3
×
'2'
 的 ASCII 是 50,2 * (-50) / 4 = -25,不是 −1
4
×
a == +5;
 只是比较,不改变 a;输出仍是 5
5
×
not 5 = 0
not 0 = 1,输出 1,不是 5
6
i % 3 == 0
 时输出,i = 3、6、9 → 369
7
for (i = 0; i < N + 1; i++) tot += i;
 即 0+1+…+N
8
外层第一句就是 continue,内层从不执行,cnt = 0,输出 10 × 0 = 0
9
枚举 tu_tou 从 0 到 tou,能输出所有满足脚数条件的解
10
×
int(sqrt(N))
 会向下取整:N = 5、M = 2 时 int(sqrt(5)) = 2 = abs(2),程序会误判"5 是 2 的平方"

两处高频误区

  • 第 3 题:把 '2' 当成数字 2。字符常量 '2' 参与运算时用的是 ASCII 码 50
  • 第 4 题== 是判断相等,= 才是赋值。少打一个等号,行为完全不同——这是 C++ 最经典的坑。

四、编程题

4.1 直角三角形

题意:给定数列前两项 a1、a2,从第三项起 a_k = √(a_{k-1}² + a_{k-2}²)。求第几项开始超过给定上限 U。

样例:3.0、4.0、上限 10.0

a1 = 3.0     a2 = 4.0     a3 = 5.0      a4 ≈ 6.403a5 ≈ 8.124   a6 ≈ 10.344 > 10  →  答案 6

参考实现

double a, b, U;cin >> a >> b >> U;int ans = 1;if (a <= U) ans++;while (b <= U) {    ans++;    double t = sqrt(a * a + b * b);    a = b; b = t;              // 滚动前进}cout << ans << endl;

三个关键点

  1. 用滚动变量,不要开数组:只需保留前两项。
  2. 开方用 sqrt(),必须 #include <cmath>,返回 double
  3. 计数逻辑要想清楚ans 表示"当前已经数到第几项",一旦 b > U 就不再累加,此时 ans 就是第一个超限的项号。

易错:把 ans 初始化成 0 或漏掉 a1 的判断,会整体差 1。

4.2 字符变换

题意:8 行 16 列的画布,共 128 格,从 1 开始按行编号。初始全是 *。给定 3 个 ASCII 码值,把对应编号的格子换成该字符,输出最终画布。

核心换算

编号 id  →  行 = (id - 1) / 16 + 1            列 = (id - 1) % 16 + 1

样例:48 → 第 3 行第 16 列 → 0;65 → 第 5 行第 1 列 → A;97 → 第 7 行第 1 列 → a

***********************************************0****************A*******************************a*******************************

参考实现(计数器法,最简洁)

int a, b, c, p = 0;cin >> a >> b >> c;for (int i = 1; i <= 8; ++i) {    for (int j = 1; j <= 16; ++j) {        ++p;        if      (p == a) cout << (char)a;        else if (p == b) cout << (char)b;        else if (p == c) cout << (char)c;        else             cout << '*';    }    cout << '\n';}

三个关键点

  1. (char)
     转换:输入的整数本身就是 ASCII 码(48 是 '0'、65 是 'A'、97 是 'a'),直接做强转即可。
  2. 编号 vs 下标:画布编号从 1 开始,用计数器 p 自增最省事,避免 (id-1)/16 的换算错误。
  3. 每行结束要换行,且用一个 for 控制 8 行 16 列,不要手写 128 个字符。

五、二级划重点

必须掌握
说明
Cache / 存储器层次
速度:寄存器 > Cache > 主存 > 外存;Cache 易失
bool
 转换
非 0 即真,参与运算时真 = 1、假 = 0
if (i)
 简写
等价于 if (i != 0)
多层循环计数
先算内层次数,再乘/加外层次数
循环变量的终值
内层保留最后值,外层超出边界
continue
 / break 位置
会改变循环次数与变量终值
常见数学函数
sqrt
abspowmaxmin
图形输出公式
空格数 = 总行数 - 行号 - 1(居中图形)
二维编号换算
(id-1) / 列数
(id-1) % 列数

抱歉,评论功能暂时关闭!