GESP 客观题评测系统
2026-03-Level-4
2026-03-Level-4
试卷解析总览,可直接查看每题答案与解析。
第 1 题(单选题)
执行下面程序后,输出为()。
int f(int x = 2){
return x * 3;
}
int main(){
cout << f() << " " << f(4);
}正确答案B
解析详情
【答案】B
【考点】函数默认参数
【解析】 函数 f 具有默认参数 x=2。在 main 函数中,第一次调用 f() 使用默认值,返回 2*3=6;第二次调用 f(4) 显式传入 4,返回 4*3=12。因此输出结果为 6 12。
【易错点】 误认为调用无参函数 f() 会导致编译错误,或忽略默认参数的乘法计算。
第 2 题(单选题)
执行下面代码后,输出为()。
int main() {
int a = 5;
int* p = &a;
int** q = &p;
**q += 7;
cout << a << " " << *p;
}正确答案B
解析详情
【答案】B
【考点】多级指针与间接访问
【解析】 p 指向变量 a,q 是指向 p 的二级指针。表达式 **q 等价于 *p,最终指向变量 a 本身。执行 **q += 7 即 a += 7,使 a 的值变为 12。由于 *p 也指向 a,因此输出 a 和 *p 均为 12。
【易错点】 未能理清多级指针的解引用层次,误认为修改 **q 不会影响 a 或 *p 的输出。
第 3 题(单选题)
已知:
int a[3][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
int (*p)[4] = a;则表达式 *(*(p + 2) + 1) 的值为()。
正确答案B
解析详情
【答案】B
【考点】二维数组与数组指针
【解析】 p 是指向含有 4 个整数数组的指针。p + 2 指向二维数组的第三行(即子数组 {9,10,11,12})。*(p + 2) 得到该行的起始地址。*(p + 2) + 1 指向该行第二个元素的地址,解引用后得到 a[2][1] 的值,即 10。
【易错点】 对数组指针 p 的偏移计算不熟练,误认为 p + 2 指向的是元素级别而非行级别。
第 4 题(单选题)
执行下面程序后,输出为()。
void fun(int a, int &b, int *c){
a += 1;
b += 2;
*c += 3;
}
int main(){
int x = 1, y = 1, z = 1;
fun(x, y, &z);
cout << x << " " << y << " " << z;
}正确答案B
解析详情
【答案】B
【考点】函数参数传递方式
【解析】 x 传值给 a,函数内修改不影响原变量;y 传引用给 b,修改 b 使 y 变为 1+2=3;z 传指针地址给 c,修改 *c 使 z 变为 1+3=4。最终输出 x y z 分别为 1 3 4。
【易错点】 误认为传值调用(x 到 a)也会修改原变量,导致首个数字误选为 2。
第 5 题(单选题)
执行下面程序后输出为()。
int x = 3;
void f(int& x){
x += 2;
}
int main(){
int x = 10;
f(x);
cout << x << " " << ::x;
}正确答案A
解析详情
【答案】A
【考点】变量作用域与全局标识符
【解析】 main 函数内的局部变量 x (10) 屏蔽了全局变量 x (3)。调用 f(x) 传入的是局部变量 x 的引用,修改后局部变量变为 12。::x 显式指明访问全局作用域中的 x,其值仍为 3。因此输出 12 3。
【易错点】 误认为 f(x) 修改的是全局变量,或者混淆了 ::x 与普通 x 的指向。
第 6 题(单选题)
下列关于结构体初始化的写法,正确的是()。
struct Point { int x, y; };
Point p = (1,2);struct Point { int x, y; };
Point p = {1,2};struct Point { int x, y; };
Point p = new Point(1,2);struct Point { int x, y; };
Point p = <1,2>;正确答案B
解析详情
【答案】B
【考点】结构体初始化
【解析】 在 C++ 中,结构体可以通过大括号 {} 进行列表初始化。选项 B 的 Point p = {1, 2} 是标准的初始化语法。选项 A 使用圆括号会被解释为逗号表达式;选项 C 的 new 语法用于动态内存分配且应赋值给指针;选项 D 使用 <> 不符合语法。
【易错点】 混淆结构体变量声明与构造函数调用,或对列表初始化语法记忆不牢。
第 7 题(单选题)
执行下面代码后输出为()。
struct S { int a; int b; };
void g(S s){ s.a += 10; }
void h(S& s){ s.b += 10; }
int main(){
S s{1,2};
g(s);
h(s);
cout << s.a << " " << s.b;
}正确答案B
解析详情
【答案】B
【考点】结构体参数传递(传值 vs 传引用)
【解析】 g(s) 是传值调用,函数内对 s.a 的修改只影响局部副本,不影响 main 中的原变量;h(s) 是传引用调用,对 s.b 的修改直接作用于 main 中的 s。最终输出 s.a=1, s.b=2+10=12。
【易错点】 误认为结构体作为参数时默认总是按引用传递,导致错误地认为 a 的值也会改变。
第 8 题(单选题)
关于递推算法的描述,正确的是()。
正确答案B
解析详情
【答案】B
【考点】递推算法定义与特征
【解析】 递推算法的核心是从已知的边界条件(初值)出发,通过确定的递推公式逐步求解后续项。函数调用自身是递归;递推不强制要求回溯;递推常用于多项式时间问题(如斐波那契、动态规划等)。
【易错点】 混淆递推(从已知向未知推导)与递归(从目标向下层拆分)的概念。
第 9 题(单选题)
执行 climb(6) 的返回值为()。
int climb(int n){
if(n <= 2) return n;
int a = 1, b = 2, c = 0;
for(int i = 3; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
return c;
}正确答案B
解析详情
【答案】B
【考点】循环递推与斐波那契数列
【解析】 此程序模拟爬楼梯问题,即 f(n)=f(n-1)+f(n-2)。初始 f(1)=1, f(2)=2。循环计算:i=3, c=3, a=2, b=3;i=4, c=5, a=3, b=5;i=5, c=8, a=5, b=8;i=6, c=13。最终返回 13。
【易错点】 由于该数列起始值为 1, 2,而非标准斐波那契的 1, 1,容易因套用习惯公式导致结果偏移一位。
第 10 题(单选题)
某排序算法对如下数据排序(按 score 升序),则下面关于该排序算法稳定性的描述中,说法正确的是()。初始:(90,'A'),(90,'B'),(80,'C'),(90,'D')排序后:(80,'C'),(90,'A'),(90,'B'),(90,'D')
正确答案B
解析详情
【答案】B
【考点】排序算法的稳定性
【解析】 稳定性是指如果两个元素关键字相同,排序后它们的相对先后顺序保持不变。在本题中,分数为 90 的三个元素 A、B、D 在排序后的相对顺序依然是 A 在前、B 在中、D 在后,符合稳定性定义。
【易错点】 误认为只要元素发生了移动就是“不稳定”,忽略了“相对顺序”这一核心判断标准。
第 11 题(单选题)
下面代码试图把数组按升序进行“插入排序”,横线处应填写()。
void ins(int a[], int n){
for(int i = 1; i < n; i++) {
int key = a[i];
int j = i - 1;
while (j >= 0 && _____){
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
}正确答案B
解析详情
【答案】B
【考点】插入排序算法实现
【解析】 在升序插入排序中,需要将当前待插入值 key 与前面已排序部分的元素逐一比较。若 a[j] 大于 key,则应将 a[j] 向后搬移一位为 key 腾出空间,因此 while 循环的条件是 a[j] > key。
【易错点】 误选 a[j] < key 导致程序执行降序排序,或者混淆了 j 与 j+1 的下标含义。
第 12 题(单选题)
下列代码段的时间复杂度为()。
int cnt=0;
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
if((i+j) % 3 == 0) cnt++;
}
}正确答案C
解析详情
【答案】C
【考点】时间复杂度分析(双重循环)
【解析】 外层循环从 0 到 n-1 执行 n 次,内层循环同样从 0 到 n-1 执行 n 次。循环体内是常数时间的操作。总的基本操作执行次数为 n * n = n^2,故时间复杂度为 O(n^2)。
【易错点】 忽略嵌套循环的乘积关系,或者错误地认为 if 语句中的取模操作会改变复杂度级别。
第 13 题(单选题)
下面哪种方式不能实现将字符串 Welcome to 2026!输出重定向到文件 log.txt()。
freopen("log.txt", "w", stdout);
cout << "Welcome to 2026!" << endl;
fclose(stdout);std::ofstream outFile("log.txt");
cout << "Welcome to 2026!" << endl;
outFile.close();ofstream log_file("log.txt");
streambuf* org_cout = cout.rdbuf();
cout.rdbuf(log_file.rdbuf());
cout << "Welcome to 2026!" << endl;
cout.rdbuf(org_cout);std::ofstream outFile("log.txt");
outFile << "Welcome to 2026!" << endl;
outFile.close();正确答案B
解析详情
【答案】B
【考点】C++ 输出重定向与文件流操作
【解析】 选项 B 中,虽然定义了 outFile,但 cout 依然指向标准输出(屏幕)。程序随后执行 cout << ...,内容依然会显示在控制台而非写入文件。选项 A (freopen)、C (rdbuf) 均实现了 cout 的重定向,选项 D 则是直接使用文件流写入。
【易错点】 看到 ofstream 就误认为会自动重定向 cout,忽略了重定向需要显式修改输出流的目标缓冲区。
第 14 题(单选题)
执行下面程序,输出结果是()。
int divi(int a,int b){
if(b==0) throw 0;
return a/b;
}
int main(){
try{
cout << divi(10,0);
}catch(const char* msg){
cout << "A";
}catch(int){
cout << "B";
}
}正确答案B
解析详情
【答案】B
【考点】异常处理(try-catch 机制)
【解析】 divi(10, 0) 检测到除数为 0,抛出一个整数异常 throw 0。在 main 函数的 try 块中,该异常会被 catch(int) 分支捕获,并输出 "B"。catch(const char*) 只处理字符串类型的异常。
【易错点】 混淆不同数据类型的异常匹配规则,或误认为除以 0 抛出的异常会导致程序直接崩溃。
第 15 题(单选题)
下列函数实现排行榜中单个元素的位置调整(类似插入排序的相邻搬移)。当某玩家分数增加,需将其向前移动时,while 循环的条件应为()。
struct Player{ int score; };
void up(Player players[], int n, int idx){
Player cur = players[idx];
int i = idx;
while( _____ ) {
players[i] = players[i-1];
i--;
}
players[i] = cur;
}正确答案A
解析详情
【答案】A
【考点】插入排序逻辑应用
0 解析】 将玩家向前移动(下标减小方向),需要保证下标 i > 0 且当前玩家分数 cur.score 大于前一个位置玩家的分数 players[i-1].score,此时才将前一个玩家后移。因此条件为 i > 0 && cur.score > players[i-1].score。
【易错点】 边界条件(i > 0)判断错误,或者分不清应该与 i-1 还是 i+1 比较。
判断题(每题 2 分)
第 1 题(判断题)
下面代码执行结束时,变量 a 的值变成 15。
void add10(int &x) { x += 10; }
int main() {
int a = 5;
add10(a);
}正确答案正确
解析详情
【答案】正确
【考点】引用传递
【解析】 add10 函数参数为 int &x(引用传递),函数内部对 x 的修改会同步反映到实参 a 上。a 的初始值为 5,执行加 10 后变为 15。
【易错点】 误将引用传递看作值传递,从而认为 a 的值保持 5 不变。
第 2 题(判断题)
引用一旦绑定某个变量,就不能再绑定其他变量。()
正确答案正确
解析详情
【答案】正确
【考点】引用基本性质
【解析】 在 C++ 中,引用必须在定义时初始化,且初始化后不能更改其所绑定的对象。后续对引用的赋值只是修改被引用变量的值,而非改变引用本身的绑定关系。
【易错点】 将引用与指针混淆,误以为引用可以像指针一样随时指向不同的内存地址。
第 3 题(判断题)
执行下面代码,输出结果为 5。
int main() {
int a[2][3];
cout << &a[1][2] - &a[0][1] << endl;
return 0;
}正确答案错误
解析详情
【答案】错误
【考点】二维数组地址计算与指针减法
【解析】 二维数组 a[2][3] 中,每行有 3 个元素。a[1][2] 的线性位置是 1*3+2=5,a[0][1] 的位置是 0*3+1=1。指针相减结果为它们之间相隔的元素个数,即 5-1=4,而非 5。
【易错点】 行偏移量计算错误,或误以为指针减法返回的是字节差。
第 4 题(判断题)
下面程序可以正常编译并输出 10 。
int calc(int x, int y = 10);
int calc(int x) { return x * 2; }
int calc(int x, int y) { return x * y; }
int main() {
cout << calc(5);
}正确答案错误
解析详情
【答案】错误
【考点】函数重载与默认参数的冲突
【解析】 程序中同时存在 calc(int) 和带有默认参数的 calc(int, int=10)。调用 calc(5) 时,编译器无法确定是调用第一个版本还是第二个版本的省略形式,存在二义性冲突,导致编译失败。
【易错点】 忽略了默认参数在重载匹配时带来的二义性问题。
第 5 题(判断题)
下面程序执行后输出 2010 。
int x = 10;
void f() { int x = 20; cout << x; }
int main() {
f();
}正确答案正确
解析详情
【答案】正确
【考点】变量屏蔽与局部变量优先
【解析】 全局变量 x = 10。在函数 f 内部定义了同名局部变量 x = 20,这会屏蔽掉全局变量。执行 f() 时输出的是局部变量的值 20。由于 main 没其他输出,最终结果就是 20。
【易错点】 误认为全局变量具有最高优先级,或忽略了局部变量对同名全局变量的遮蔽效应。
第 6 题(判断题)
在 C++ 中,如果声明了一个指针变量但没有显式初始化,该指针会自动被初始化为 nullptr。
正确答案错误
解析详情
【答案】错误
【考点】变量初始化规则
【解析】 在 C++ 中,局部非静态变量(包括指针)在声明时如果没有初始化,其初始值是未定义的随机值(垃圾值)。只有全局变量或静态变量才会自动初始化为 0 (nullptr)。
【易错点】 习惯了 Java 等语言的自动零初始化机制,误以为 C++ 的局部变量也会自动赋初值。
第 7 题(判断题)
下面代码没有语法错误。
struct GameCharacter {
string name;
int level;
float position_x;
float position_y;
struct Equipment {
string weapon;
int attack_bonus;
int defense_bonus;
} equipment;
struct Skill {
string name;
int damage;
} skills[8];
int skill_count;
};正确答案正确
解析详情
【答案】正确
【考点】嵌套结构体定义
【解析】 C++ 允许在一个结构体内部定义并实例化其他结构体,这在处理多级复杂数据(如角色的装备、技能数组)时是标准做法,语法完全合法。
【易错点】 误认为必须先在外部定义子结构体,不能在内部直接嵌套定义。
第 8 题(判断题)
下面程序能够把 Hello 写入 data.txt 文件中。
ofstream fout("data.txt");
cout << "Hello";
fout.close();正确答案错误
解析详情
【答案】错误
【考点】文件流输出操作
【解析】 程序虽然创建了指向文件的 fout 流,但第二行使用的是 cout << "Hello",这将内容输出到了标准控制台而非文件。要写入文件应使用 fout << "Hello"。
【易错点】 误认为只要定义了 fout,后续所有的 cout 内容都会被自动重定向到该文件流中。
第 9 题(判断题)
由于选择排序和插入排序的时间复杂度均为 O(n^{2}) ,在任何实际场景下两者的性能表现几乎相同,可以互相替代。
正确答案错误
解析详情
【答案】错误
【考点】排序算法性能特性对比
【解析】 虽然最坏复杂度相同,但插入排序是稳定的且在处理“几乎有序”数据时效率接近 O(n),而选择排序是不稳定的且无论数据状况如何始终执行 n^2 次比较。两者在实际场景表现差异巨大。
【易错点】 片面相信 O 复杂度,忽略了算法的稳定性及对数据敏感性的差异。
第 10 题(判断题)
下面用递推方式计算斐波那契数列第 n 项的程序,时间复杂度是 O(2^{n}) 。
int fib(int n) {
if (n <= 1) return n;
int f0 = 0, f1 = 1, cur = 0;
for (int i = 2; i <= n; i++) {
cur = f0 + f1;
f0 = f1;
f1 = cur;
}
return cur;
}正确答案错误
解析详情
【答案】错误
【考点】算法复杂度分析(迭代 vs 递归)
【解析】 该程序采用单层循环(迭代方式)计算斐波那契数列,执行次数随 n 线性增长,复杂度为 O(n)。只有不带备忘录的简单递归实现才是 O(2^n)。
【易错点】 对斐波那契数列的常见复杂度印象过于死板,未能区分代码中具体的迭代实现逻辑。