如果要用一个词评价GESP 2026年3月认证C++二级的判断题,我会选“稳中带刺”。试卷第二部分前10道判断题拿在手里,第一反应是难度没有往上蹿,但抠字眼的地方比往年多了不少。很多学生平时写代码没问题,一换成文字描述就被绕进去——这正是判断题最要命的属性。这篇内容按考后回忆和仿真还原整理了这10道题,逐题给出答案、完整解析和避坑提示。不管你是刚考完想复盘,还是正在准备下一次C++二级考试,或者带学生备赛,都可以直接用这套题当自测参考。核心考点集中在变量初始化、赋值运算、switch贯通、数组边界、字符串结束符这些“二级最容易丢分”的地方。
1. 项目概述与考点全景
1.1 判断题在GESP二级里的定位
判断题是GESP C++二级的稳定得分区,但也是很容易“莫名其妙丢分”的区域。二级整体难度不高,选择题和判断题大多在考基础概念,真正的编程大题放在最后面。如果前面的判断题都拿不稳,后面编程题的心理压力会很大。从2026年3月这套卷子的命题风格看,判断题不再只是单考“对不对”,而是会通过一个代码片段或一句描述,考察你是否真正理解C++的执行流程。比如你知不知道for后面多了一个分号意味着什么,知不知道数组越界时编译器根本不会拦你。这些点光靠背概念是不够的,得靠平时编译和调试积累下来的直觉。
1.2 这次十道题的考点分布
结合二级考试大纲和近几年真题走势,这次判断题第1-10题主要覆盖了五大块:变量初始化与作用域、赋值与算术运算、循环和switch的流程控制、数组与字符串、函数基础。我把考点整理成了一张表,方便对照复习:
| 考察方向 | 对应题目 | 核心注意点 |
|---|---|---|
| 变量初始化 | 第1题 | 局部变量与全局变量的默认值不同 |
| 赋值运算 | 第2题 | 赋值运算符是右结合,且=不是== |
| 算术运算 | 第3题 | 整数除法结果仍是整数,小数部分丢弃 |
| 循环控制 | 第4题 | for后面的空语句也是一个合法循环体 |
| switch流程 | 第5题 | case不加break会发生“贯通” |
| 数组边界 | 第6题 | 下标从0开始,越界不报编译错误 |
| 字符串存储 | 第7题 | 字符串结尾自动追加\0 |
| 逻辑短路 | 第8题 | 逻辑或左边为true时,右边不会执行 |
| 函数返回 | 第9题 | C++函数定义必须写返回类型 |
| 作用域规则 | 第10题 | 局部变量会遮蔽同名全局变量 |
这10道题基本把二级最容易坑人的概念全部覆盖了一遍。命题人很聪明,他们不是让你背定义,而是把定义“翻译”成你平时最常写错的形式,然后问你:这样写对吗?如果你平时靠死记硬背通过,这一关会非常难受;如果你平时真的在敲代码验证过细节,读题的时候脑子里就会自动跑出程序画面。
2. 判断題型底层逻辑与拆解思路
2.1 三类判断题的破解思路
GESP二级的判断题大致分三类。第一类是概念判断题,比如“所有变量不初始化就是0吗”“函数返回类型能省略吗”,这类题考的是定义边界,破解方法是想反例。第二类是行为判断题,给出一段短代码,让你判断运行结果或执行次数,比如整数除法、for空循环,破解方法是把代码“人肉编译”一遍。第三类是边界陷阱题,比如数组下标、字符串结束符,这类题不看你代码能力,看的是你有没有踩过坑。我的经验是:遇到概念题,先在脑子里搜索适用场景;遇到行为题,严格按运算符优先级和结合性一步步执行;遇到边界题,要主动想“如果我是出题人,我会把哪个边界藏起来”。
2.2 二级必背的“概念红线”
有几个概念是二级判断题的高频出题点,不管怎么强调都不过分。第一,局部变量不初始化,值是不确定的垃圾值;全局变量和静态局部变量才会自动初始化为0。第二,整数除以整数,结果还是整数。第三,数组下标从0开始,访问a[n]属于越界,编译器不一定拦你。第四,字符串结尾的\0也要占空间。第五,赋值=是右结合的,等价判断是==,两者长得像但完全不是一回事。第六,逻辑与&&和逻辑或||都带短路求值。第七,switch的case不写break就会往下贯通。这些红线如果考前没有形成肌肉记忆,做判断题只能靠猜。我建议你把它们写在一张便签上,考前最后半小时专门背一遍,比临时翻书有用得多。
3. 第1-10题逐题精析(回忆版/仿真还原)
3.1 第1-2题:初始化与赋值
第1题原题大意:“在C++中,定义的所有变量如果不进行初始化,它们的值一定为0。”
答案:F(错误)。
这句话最大的问题是“所有”两个字。C++里全局变量、静态变量确实会被零初始化,这是语言规范保证的;但局部变量只要不初始化,初始值就是不确定的,通常是栈上残留的数据,具体是什么值取决于运行环境。拿代码来说:
#include <iostream> using namespace std; int g; // 全局变量,默认是0 int main() { int x; // 局部变量,未初始化,值不确定 static int y; // 静态局部变量,默认是0 cout << g << " " << y << endl; cout << x << endl; return 0; }x的输出结果每次运行都可能不一样,这就是“不确定值”的意思。这个知识点非常经典,几乎每届都会考。判断题里只要出现“所有变量”“一定为0”这类绝对化说法,基本可以判定有问题。补充一个相关易错点:有些同学会把static int x;和int x;搞混,静态局部变量写在函数内部,但它只初始化一次,默认值是0,生命周期是整个程序运行期。这些细节建议手写几遍,不要只看书。
第2题原题大意:“执行语句a = b = c = 1;后,变量a、b、c的值都变为1。”
答案:T(正确)。
赋值运算符=的结合性是自右向左,也就是右结合。所以a = b = c = 1的实际执行顺序是:先把1赋给c,然后取c的值赋给b,再取b的值赋给a,最终三个变量都是1。这里真正要小心的是,很多同学会把=和==放在一起记。题目如果换成a == b == c,情况就完全不一样了:(a == b)的结果是一个布尔值(0或1),然后再拿这个布尔值和c比较,和“判断三个数是否相等”完全是两码事。GESP特别喜欢拿这两个运算符做文章,你考场上一旦看到等号出现两次以上,就要立刻条件反射去分析结合顺序和执行过程。
3.2 第3-4题:算术与循环
第3题原题大意:“执行int x = 7 / 2;后,变量x的值等于3.5。”
答案:F(错误)。
两个int做除法,结果还是int类型,小数部分直接丢弃,所以结果是3,不是3.5。要想得到3.5,至少要把一边改成浮点型,比如7.0 / 2或7 / 2.0。这里要特别提醒:写成double x = 7 / 2;也依然是3,因为右侧的除法在赋值给x之前就已经按整数运算算完了,类型转换发生在赋值那一刻,救不了已经丢掉的0.5。这不是GESP第一次考整数除法,但每次都能刷掉一批人。还有一个扩展点:负数整除在C++11之后统一向零取整,比如-7 / 2的结果是-3,而不是-4,这点和某些语言向下取整的习惯不一样。二级不一定考负数取整,但你能掌握就多一分底气。看除法题时的检查习惯是:先看两边的类型,只要都是整数,结果就先按整数想。
第4题原题大意:“for (int i = 0; i < 5; i++);这条语句的分号代表循环体为空语句,程序会空转5次。”
答案:T(正确)。
for后面的分号是一个“空语句”,它合法地充当循环体,所以这个循环只是把计数器从0跑到4,总共5次,什么都没做。这类代码在实际项目里常用来做延时或等待。但很多初学者会在for那一行末尾多加一个分号,结果原本想循环执行的语句变成了只执行一次,这是极其隐蔽的bug。比如:
for (int i = 0; i < 5; i++); cout << "hi" << endl;这段代码只会输出一次hi,而且很多人第一眼看不出来。GESP考这个点相当用心——它就是在测试你“分号也是一条语句”这个概念有没有建立。看到for、while、if后面紧跟分号,马上提高警惕,这是全C++里最经典的低级错误之一。
3.3 第5-6题:switch与数组
第5题原题大意:“switch语句中,如果一个case分支没有break,那么它执行完后会继续执行后面的case,即使switch的值不满足那个case的条件。”
答案:T(正确)。
这是switch的“贯通”特性。case只是一个入口标签,不是自动跳出口,程序会顺着往下执行直到遇到break或者整个switch结束。比如:
int n = 1; switch (n) { case 1: cout << 'A'; case 2: cout << 'B'; }输出是AB,不是A。这个特性在一些场景下是有意使用的,比如多个值共用一个处理逻辑;但更多时候是漏写break导致的bug。GESP考这个点,是想确认你理解switch的控制流,而不是背“switch有break才好”。另外要记住,case后面的值必须是常量表达式,不能是变量;default不一定放在最后,但通常放最后,判断题里如果说“default必须放最后”,那也是错的。
第6题原题大意:“在C++中,定义int a[5];后,可以通过a[5]访问数组的最后一个元素。”
答案:F(错误)。
数组下标从0开始,有效范围是0到4,所以a[5]已经是越界访问了。最后一个元素是a[4]。最迷惑人的是,C++的数组越界不会在编译阶段报错(有些编译器只是给个warning),运行结果可能看起来正常,也可能直接崩溃或触发系统安全机制,这叫未定义行为。GESP这题考的是“你是否真的知道下标范围”。看到“最后一个元素”这类表述,先减一再判断。对于长度为n的数组,合法下标是0到n-1,不要被“a[n]看起来像是最后一个”骗了。C++给了程序员很大的自由,但自由是要付出代价的,越界就是典型例子。备考时可以在自己电脑上故意写一个越界程序跑一下,感受一下什么叫“结果不一定出错但绝不安全”。
3.4 第7-8题:字符串与逻辑
第7题原题大意:“char s[] = \"abc\";这条语句定义后,数组s占用的存储空间是3个字节。”
答案:F(错误)。
字符数组用字符串常量初始化时,会在结尾自动追加一个空字符'\0',所以"abc"在内存里实际占4个字节:a、b、c、\0。因此sizeof(s)返回4,不是3。如果你写char s[3] = "abc";,部分编译器会给警告,因为数组放不下结束符,字符串可能被截断甚至报错。GESP二级里字符串终止符是高频考点,你要把“字符个数加1”这个公式刻在脑子里。字符串数组初始化的几种写法要会区分:
char s1[] = "abc"; // 自动分配4字节,含\0 char s2[10] = "abc"; // 分配10字节,后面元素自动补0 char s3[] = {'a','b','c'}; // 注意这里没有\0,是3字节 const char *p = "abc"; // 指向字符串字面量,内容不可修改这几种初始化方式对应的内存布局完全不同,考试经常拿它们做文章。
第8题原题大意:“在执行if (x > 0 || ...)时,如果x > 0成立,则右侧表达式不会被执行。”
答案:T(正确)。
逻辑或运算符是短路求值的,左边为true时,整个表达式已经确定为true,右边就没必要计算了。同理,逻辑与&&也是短路求值,左边为false时右边不执行。这个特性在编程里非常重要,因为它可以保护一些可能出错的表达式,比如:
if (a != 0 && b / a > 1) { ... }当a等于0时,b / a根本不会执行,直接避免了除零错误。反过来if (a == 0 || b / a < 1)也是安全写法。判断题中只要出现“左边成立/不成立时,右边会不会执行”,就是在考短路。理解了短路机制,这类题就是送分。但不少同学只记住了“短路”这个名词,一问你执行过程就懵,所以备考时要拿真代码编译运行看效果,比光背概念有用。
3.5 第9-10题:函数与作用域
第9题原题大意:“在C++中,函数定义时可以省略返回类型,省略后默认返回int。”
答案:F(错误)。
这是C语言旧标准的说法。C++明确规定,函数定义必须写返回类型,没有“默认int”这种机制。哪怕是main函数,也必须写int main()。如果函数不返回任何值,要写void,这里的void本身就是一个类型标志符。这题特别容易骗到学过C语言老教材的同学,因为C89时代确实允许省略int默认是int,但那是几十年前的规定,C++从设计之初就不允许。其实验证很简单:打开你的C++编译器,写f() { },大概率直接编译报错。实践是检验概念的唯一标准,遇到这种争议题,用编译器说话。
第10题原题大意:“当函数内部的局部变量与外部的全局变量同名时,函数内使用的变量默认是全局变量。”
答案:F(错误)。
同名变量出现时,内层作用域的局部变量会“遮蔽”外层的全局变量,也就是说函数内访问到的是局部变量,和全局变量没有关系。这种遮蔽机制是C++作用域规则的核心内容。如果想在函数内部使用被遮蔽的全局变量,要借助作用域运算符::x。GESP出这题是想看考生有没有真正区分“定义位置”和“访问规则”。我建议你写下面这段代码自己跑一遍:
#include <iostream> using namespace std; int a = 5; int main() { int a = 100; cout << a << endl; // 输出100,局部遮蔽全局 cout << ::a << endl; // 输出5,强制访问全局 }跑完之后,这个知识点基本不会忘。
4. 高频错因与排查技巧实录
4.1 十道题里最容易翻车的五个点
每次给学生们复盘,我都会总结出几个固定的翻车点。第一个是看到绝对化词就直接判错。判断题里出现“一定”“所有”“全部”时确实大概率是错的,但不能无脑判错,比如第8题的结论本身就是绝对的,但它是正确的。第二个是整数除法不区分类型。第3题每年都有大量考生选错,因为他们下意识把7 / 2当成数学除法。第三个是数组的“第1个元素”和“最后一个元素”错位,老是忘记第1个元素的下标是0。第四个是字符串只数字符个数,不看\0。第五个是函数默认返回int的老教材残留概念。这些都不是智商问题,而是基础概念没有在编译器里验证过。
4.2 判断题的“三秒定位”检查流程
我在带学生时总结了一套三步检查法。第一步,读题后立刻圈关键信息:绝对化词、否定词“不”、代码里的分号和下标边界。第二步,尝试举反例,能举出就直接判错;举不出反例,就把代码逐步翻译成中文执行过程,写清楚每一步在做什么。第三步,复查有没有看见“不”字,因为很多人会把“不会被执行”看成“会被执行”,把“不正确的是”看成“正确的是”。这套流程练熟练之后,一道判断题最多一分钟就能拿下来。碰上拿不准的题,宁可按“这个说法太绝对,可能有反转”来标记,也不要随便蒙一个答案。
4.3 考场时间分配与心态
GESP二级整套卷子的时间安排其实比较紧凑,判断题不适合恋战。10道判断题控制在10分钟以内,平均每题1分钟,读两遍还拿不准就先跳过,用排除法回头再选。我的原则是:判断题错了不致命,编程大题才是拉分的关键,不要因为一道概念题反复纠结导致最后编程题时间不够。这个建议不光是针对这场考试,任何编程类竞赛都适用。心态上把判断题当成“体检”就好,它能快速暴露出你哪些基础不牢,考完再针对性补一遍,比考前提心吊胆要有用得多。
5. 备考安排与后续进阶建议
5.1 从二级到三级的知识衔接
二级的扎实程度直接决定三级能不能起飞。三级的核心内容包括字符串处理、递归、排序和查找,其中递归依赖函数原理,排序和查找依赖数组与循环。如果二级阶段你对函数作用域、数组边界这些概念是模糊的,到三级碰到递归求解和二分查找会非常吃力。所以我一直都认为,判断题这10分左右的价值不只是分数本身,它更像一份体检报告,暴露的是你对基础概念的掌握程度。二级里的数组、字符串、函数,是三级乃至四级所有算法题的地基。
5.2 刷题资源与自测方法
刷题资源方面,我建议以官方样题和历年真题为第一优先级,配合一本适合入门的C++教材。实操层面,先把vscode或者命令行环境配好,保证能一键编译运行C++程序,否则看再多的解析也记不住。每次做完判断题,不要只看答案,把题目里的代码片段复制下来,加几行cout打印,把“判断题”变成“验证题”,亲眼看到结果才算是真正的掌握。这个方法对字符串、数组、逻辑短路这类题目效果尤其好。比如第7题字符串长度,你sizeof一打印就再也不会忘。每天坚持10道判断题加1道编程题,持续一个月,二级基本就能稳过。
带了几届学生之后,我对判断题的态度一直没变:它从来不是送分题,而是送分陷阱。一个简单的“对”或“错”背后,考察的是你有没有真的敲过代码、踩过坑、看过程序崩溃时的报错。如果你准备GESP二级,别把判断题当成背诵题,把它当成一次和考官的对话,听出他藏在文字里的边界条件。平时多编译、多打印、多调试,到了考场上你就发现,这些题根本不是猜出来的,而是你跑程序时早就见过的画面。