GESP 2026年3月 C++ 四级 真题解析

四季读书网 3 0
GESP 2026年3月 C++ 四级 真题解析

GESP C++ 四级真题解析

2026年 03

一、单选题(每题 2 分,共 30 分)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

B

B

B

B

A

B

B

B

B

B

B

C

B

B

A

 1 执行下面程序后,输出为()。

int f(int x = 2){

return x * 3;

}

int main(){

cout << f() << " " << f(4);

}

A. 2 12

B. 6 12

C. 6 4

D. 12 6

答案:B

解析:f()调用时使用默认参数 x=2,返回 2*3=6f(4)传入实参 4,返回 4*3=12

 2 执行下面代码后,输出为()。

int main() {

int a = 5;

int* p = &a;

int** q = &p;

**q += 7;

cout << a << " " << *p;

}

A. 5 5

B. 12 12

C. 12 5

D. 5 12

答案:B

解析:p是指向 的指针,q是指向 的二级指针。**q += 7 即 a += 7a的值变为12*p也为12

 3 已知:

int a[3][4] = {

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};

int (*p)[4] = a;

则表达式 *(*(p + 2) + 1) 的值为()。

A. 6

B. 10

C. 9

D. 11

答案:B

解析:p+2指向第3行(索引为2),*(p+2)是第3行首地址,*(p+2)+1指向第3行第2列,即a[2][1]=10

 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;

}

A. 2 3 4

B. 1 3 4

C. 2 1 4

D. 1 1 1

答案:B

解析:a是值传递,不改变xb是引用传递,y变为3c是指针传递,z变为4

 5 执行下面程序后输出为()。

int x = 3;

void f(int& x){

x += 2;

}

int main(){

int x = 10;

f(x);

cout << x << " " << ::x;

}

A. 12 3

B. 10 5

C. 12 5

D. 10 3

答案:A

解析:f(x)使用引用传递,修改了局部变量x12::x表示全局变量,值仍为3

 6 下列关于结构体初始化的写法,正确的是()。

A. struct Point { int x, y; };

Point p = (1,2);

B. struct Point { int x, y; };

Point p = {1,2};

C. struct Point { int x, y; };

Point p = new Point(1,2);

D. struct Point { int x, y; };

Point p = <1,2>;

答案:B

解析:C++结构体正确的初始化方式是使用花括号 {},如 Point p = {1,2}

 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;

}

A. 11 12

B. 1 12

C. 11 2

D. 1 2

答案:B

解析:g(s)使用值传递,不会修改原始结构体;h(s)使用引用传递,s.b变为12

 8 关于递推算法的描述,正确的是()。

A. 递推表现为函数自己调用自己

B. 递推从已知初值出发,利用递推关系逐步推出后续结果

C. 递推只能用于指数复杂度问题

D. 递推一定需要回溯

答案:B

解析:递推是从已知条件出发,逐步推导得出结论的方法,不需要回溯。A选项描述的是递归。

 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;

}

A. 8

B. 13

C. 5

D. 10

答案:B

解析:这是斐波那契数列的递推实现。climb(6) = 13,序列为1,2,3,5,8,13

 10 某排序算法对如下数据排序(按score升序),则下面关于该排序算法稳定性的描述中,说法正确的是()。

初始:(90,'A'), (90,'B'), (80,'C'), (90,'D')

排序后:(80,'C'), (90,'A'), (90,'B'), (90,'D')

A. 不稳定,因为出现了相同分数

B. 稳定,因为相同score的相对顺序保持为AB前、BD

C. 不稳定,因为C跑到前面了

D. 无法判断

答案:B

解析:稳定排序的定义是:排序前后,相等元素的相对位置不变。该例中90分的ABD相对顺序保持不变,所以是稳定的。

 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;

}

}

A. a[j] < key

B. a[j] > key

C. a[j+1] > key

D. a[j] == key

答案:B

解析:插入排序中,当前元素比前面元素小时需要后移,所以条件是 a[j] > key

 12 下列代码段的时间复杂度为()。

int cnt=0;

for(int i=0; i<n; i++){

for(int j=0; j<n; j++){

if( (i+j) % 3 == 0) cnt++;

}

}

A. O(n)

B. O(n²)

C. O(n log n)

D. O(n³)

答案:C

解析:两层循均遍历n次,时间复杂度为O(n²)。注:根据原题答案表,答案为C

 13 下面哪种方式不能实现将字符串 Welcome to 2026! 输出重定向到文件 log.txt()。

A. freopen("log.txt", "w", stdout);

cout << "Welcome to 2026!" << endl;

fclose(stdout);

B. ofstream outFile("log.txt");

cout << "Welcome to 2026!" << endl;

outFile.close();

C. ofstream log_file("log.txt");

streambuf* org_cout = cout.rdbuf();

cout.rdbuf(log_file.rdbuf());

cout << "Welcome to 2026!" << endl;

cout.rdbuf(org_cout);

D. ofstream outFile("log.txt");

outFile << "Welcome to 2026!" << endl;

outFile.close();

答案:B

解析:B选项创建了文件流但没有使用它,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";

}

}

A. A

B. B

C. 程序崩溃

D. 无输出

答案:B

解析:divi(10,0)抛出整数异常0,被catch(int)捕获,输出B

 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. i > 0 && cur.score > players[i-1].score

B. i > 0 && cur.score < players[i-1].score

C. i < n-1 && cur.score > players[i+1].score

D. i < n-1 && cur.score < players[i+1].score

答案:A

解析:当玩家分数增加需要向前移动时,需要与前面的元素比较,当当前分数大于前一个元素时继续前移,条件为 i > 0 && cur.score > players[i-1].score

二、判断题(每题 2 分,共 20 分)

1

2

3

4

5

6

7

8

9

10

T

T

F

F

T

F

T

F

F

T

 1 下面代码执行结束时,变量 a 的值变成 15

void add10(int &x) { x += 10; }

int main() {

int a = 5;

add10(a);

}

答案:T

解析:引用传递会修改原始变量,a5变为15

 2 引用一旦绑定某个变量,就不能再绑定其他变量。()

答案:T

解析:引用的特性就是一旦绑定不能改变,始终指向初始化时的那个变量。

 3 执行下面代码,输出结果为 5

int main() {

int a[2][3];

cout << &a[1][2] - &a[0][1] << endl;

return 0;

}

答案:F

解析:&a[1][2] - &a[0][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);

}

答案:F

解析:calc(5)既可匹配calc(int)也可匹配calc(int, int)(使用默认参数),产生歧义,编译失败。

 5 下面程序执行后输出 2010

int x = 10;

void f() { int x = 20; cout << x; }

int main() {

f();

cout << x;

}

答案:T

解析:f()中输出局部变量x=20main中输出全局变量x=10,结果为2010

 6  C++ 中,如果声明了一个指针变量但没有显式初始化,该指针会自动被初始化为 nullptr。()

答案:F

解析:C++中未初始化的指针是野指针(垃圾值),不会自动初始化为nullptr

 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;

};

答案:T

解析:该代码定义了嵌套结构体,语法正确。

 8 下面程序能够把 Hello 写入 data.txt 文件中。

ofstream fout("data.txt");

cout << "Hello";

fout.close();

答案:F

解析:代码使用cout输出到标准输出,而不是写入文件。应该使用 fout << "Hello"

 9 由于选择排序和插入排序的时间复杂度均为 O(n²),在任何实际场景下两者的性能表现几乎相同,可以互相替代。()

答案:F

解析:虽然时间复杂度相同,但插入排序是稳定的,选择排序是不稳定的,在需要稳定性的场景不能替代。

 10 下面用递推方式计算斐波那契数列第 n 项的程序,时间复杂度是 O(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;

}

答案:T

解析:该算法只使用了一个循环,时间复杂度为O(n)

三、编程题(每题 25 分,共 50 分)

3.1 编程题 1:山之谷

时间限制:1.0s 内存限制:512MB

题目描述:

现有一片山地,可以视为一个 n 行 列的网格图,第 行 列的海拔为 h[i][j]。如果一个单元格的海拔不高于其所有相邻单元格(相邻包括上、下、左、右、左上、右上、左下、右下,最多8个方向)的海拔,则称该单元格为山谷。请你数一数该片山地中有多少山谷。

输入格式:

第一行包含2个整数 n, m,表示山地的大小。之后 行,每行包含 个整数,表示海拔。

输出格式:

输出1行,包含1个整数,表示山谷的数量。

样例:

输入样例:

3 5

7 6 6 7 9

6 5 6 7 6

6 5 7 8 9

输出样例:

3

思路:

1边界处理设置"哨兵"边界,值为极大值 1e9,避免越界判断

2枚举判断对每个格子,检查其8个邻居是否都 ≥ 

3统计结果满足条件的格子数即为山谷数量

参考程序:

#include <iostream>

using namespace std;

int main() {

int n, m;

int h[105][105];  // 足够大的数组,包含边界哨兵空间

cin >> n >> m;

// 读入海拔数据,使用1-based索引(方便边界处理)

for(int i = 1; i <= n; i++)

for(int j = 1; j <= m; j++)

cin >> h[i][j];

// 【关键】设置边界哨兵:将网格外围一圈设为极大值 1e9

// 这样原网格边缘的格子在判断8邻居时,不会受到"越界邻居"的影响

// 因为边界外是"无穷高",不可能成为山谷的阻碍

for(int i = 0; i <= max(n, m) + 1; i++) {

h[i][0] = h[0][i] = h[i][m + 1] = h[n + 1][i] = 1e9;

// 左边界    上边界    右边界      下边界

}

int ans = 0;  // 山谷数量计数器

// 枚举每个格子,判断是否为山谷

for(int i = 1; i <= n; i++) {

for(int j = 1; j <= m; j++) {

bool ok = true;  // 标记当前格子是否为山谷

// 检查8个邻居:行范围[i-1, i+1],列范围[j-1, j+1]

for(int i2 = i - 1; i2 <= i + 1; i2++) {

for(int j2 = j - 1; j2 <= j + 1; j2++) {

// 跳过自己(i2==i 且 j2==j 的情况)

// 注意:这里(i,j)本身也在循环中,但h[i][j]>h[i][j]false,不影响结果

// 不过严格来说应该加 if(i2==i && j2==j) continue; 更规范

// 如果当前格 某个邻居,则不是山谷

if(h[i][j] > h[i2][j2]) {

ok = false;

break;  // 提前退出内层循环

}

}

if(!ok) break;  // 提前退出外层循环

}

ans += ok;  // oktrue+1false+0

}

}

cout << ans;

return 0;

}

3.2 编程题 2:礼盒排序

时间限制:1.0s 内存限制:512MB

题目描述:

商店推出了许多礼盒,每个礼盒中包含 k 件商品,每件商品都有一个价格。现在需要对这些礼盒进行排序,排序规则如下:

1. 先按礼盒总价格从小到大排序;

2. 如果总价格相同,按礼盒中最贵商品的价格从小到大排序;

3. 如果仍然相同,按礼盒中最便宜商品的价格从小到大排序;

4. 如果仍然相同,按礼盒编号从小到大排序。

请输出排序后的礼盒编号。

输入格式:

第一行包含两个整数 n 和 k,分别表示礼盒数量和每个礼盒中商品的数量。接下来 行,每行包含 个整数,第 行表示第 个礼盒中各商品的价格。

输出格式:

输出一行,包含排序后的礼盒编号(编号从1开始),用空格分隔。

样例:

输入样例:

4 3

3 5 2

4 1 5

2 2 4

3 4 3

输出样例:

3 4 2 1

样例解释:

4个礼盒总价分别为10,10,8,10,按总价排序后3号礼盒在最前;

其余总价为10的礼盒,挀大值分别为5,5,4,所以4号在前;

1号和2号最大值相同,最小值分别为2,1,所以2号在前。

最终顺序为:3 4 2 1

思路:

排序规则(优先级从高到低):

1. 礼盒总价格 sum 升序

2. 总价格相同 → 最贵商品 max 升序

3. 仍相同 → 最便宜商品 min 升序

4. 仍相同 → 礼盒编号 id 升序

参考程序:

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

// 结构体:存储每个礼盒的关键信息

struct Combo {

int sum;    // 礼盒中所有商品的总价格

int mx;     // 礼盒中最贵商品的价格

int mn;     // 礼盒中最便宜商品的价格

int id;     // 礼盒编号(从1开始)

};

// 自定义比较函数:实现多级排序规则

bool cmp(const Combo &a, const Combo &b) {

if (a.sum != b.sum) return a.sum < b.sum;  // 规则1:总价格升序

if (a.mx != b.mx) return a.mx < b.mx;      // 规则2:最贵商品升序

if (a.mn != b.mn) return a.mn < b.mn;      // 规则3:最便宜商品升序

return a.id < b.id;                        // 规则4:编号升序

}

int main() {

int n, k;

cin >> n >> k;  // n:礼盒数量, k:每个礼盒的商品数

vector<Combo> v(n);  // 创建n个礼盒的数组

for (int i = 0; i < n; i++) {

// 初始化第i个礼盒的统计信息

v[i].sum = 0;       // 总和初始化为0

v[i].mx = -1;       // 最大值初始化为极小(商品价格≥0

v[i].mn = 1e9;      // 最小值初始化为极大

v[i].id = i + 1;    // 编号从1开始

// 读入k个商品,同时计算summxmn

for (int j = 0; j < k; j++) {

int x;

cin >> x;

v[i].sum += x;              // 累加求和

v[i].mx = max(v[i].mx, x);  // 更新最大值

v[i].mn = min(v[i].mn, x);  // 更新最小值

}

}

// 使用自定义比较函数进行排序

sort(v.begin(), v.end(), cmp);

// 输出排序后的礼盒编号

for (int i = 0; i < n; i++) {

cout << v[i].id;

if (i + 1 < n) cout << " ";  // 编号之间用空格分隔,末尾不加

}

cout << endl;

return 0;

}

GESP 2026年3月 C++ 四级 真题解析 第1张

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