GESP 客观题评测系统

试卷解析 · 理解每一步

2025-12-Level-4

2025-12-Level-4

试卷解析总览,可直接查看每题答案与解析。

单选题

第 1 题(单选题,2 分)

小杨想让指针 p 指向整数变量 x,正确写法是()。

A.
int p = &x;
B.
int *p = x;
C.
int *p = &x;
D.
p = *x;

正确答案C

解析详情
答案 C指针定义与赋值
思路与推导
  1. 在 C++ 中,指针变量用于存储内存地址。要让指针 p 指向整数变量 x,需要先声明 p 为指针类型 `int *`,并使用取地址符 `&` 获取变量 x 的地址赋给 p。选项 C 完全符合语法要求。

第 2 题(单选题,2 分)

小杨写了如下的指针接力程序,程序执行完后变量 a、*p1 和 *p2 的值分别是()。

int a = 5;
int* p1 = &a;
int* p2 = p1;
*p2 = 10;
A.
5 10 10
B.
5 10 15
C.
10 10 10
D.
5 5 10

正确答案C

解析详情
答案 C指针指向与解引用修改
思路与推导
  1. 1. `p1` 指向 `a`,`p2 = p1` 使 `p2` 也指向 `a`。

  2. 2. `*p2 = 10` 通过指针修改了变量 `a` 的值为 10。

  3. 3. 由于 `p1` 和 `p2` 均指向 `a`,解引用 `*p1` 和 `*p2` 获取的都是变量 `a` 的当前值 10。因此 a, *p1, *p2 均为 10。

第 3 题(单选题,2 分)

小杨用一个二维数组表示棋盘,其中1表示有棋子,0表示没有棋子。他想知道第2行第3列有没有棋子,可采用的代码是:()。

int a[3][4] = {
{1, 0, 1, 0},
{0, 1, 0, 1},
{1, 1, 0, 0}
};
A.
cout << a[1, 2] << endl;
B.
cout << a[1][2] << endl;
C.
cout << a(1, 2) << endl;
D.
cout << a{1}{2} << endl;

正确答案B

解析详情
答案 B二维数组索引访问
思路与推导
  1. C++ 二维数组下标从 0 开始。第 2 行对应行下标 1,第 3 列对应列下标 2。标准的访问语法为 `数组名[行下标][列下标]`,即 `a[1][2]`。

第 4 题(单选题,2 分)

执行完下面的代码后,*(p + 5)和 arr[1][1] 的值分别是()。

int arr[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int* p = &arr[0][0];
A.
5 6
B.
6 5
C.
5 5
D.
6 6

正确答案D

解析详情
答案 D二维数组内存布局与指针运算
思路与推导
  1. 二维数组按行优先存放,`arr[3][4]` 每行 4 个元素。`p + 5` 从 `arr[0][0]` 开始偏移 5 个位置:前 4 个跨过第 0 行,第 5 个落到第 1 行第 1 列(即 `arr[1][1]`)。此时对应元素为 6,因此两者值均为 6。

第 5 题(单选题,2 分)

执行完下面的代码后,sum 的值是()。

int arr[2][3][2] = {
    {{1,2}, {3,4}, {5,6}},
    {{7,8}, {9,10}, {11,12}}
};
int sum = 0;
for(int i = 0; i < 2; i++)
    for(int j = 0; j < 3; j++)
        for(int k = 0; k < 2; k++)
            if((i+j+k) % 2 == 0)
                sum += arr[i][j][k];
A.
36
B.
39
C.
78
D.
30

正确答案B

解析详情
答案 B多维数组遍历与条件判断
思路与推导
  1. 累加满足 `(i+j+k)` 为偶数的元素:

  2. (0,0,0)→1, (0,1,1)→4, (0,2,0)→5

  3. (1,0,1)→8, (1,1,0)→9, (1,2,1)→12

  4. 总和 = 1 + 4 + 5 + 8 + 9 + 12 = 39。

第 6 题(单选题,2 分)

执行完下面的代码后,输出是()。

int a = 1;

void test() {
    int a = 2;
    {
        int a = 3;
        a++;
    }
    a++;
    cout << a << " ";
}

int main() {
    test();
    cout << a;
    return 0;
}
A.
3 1
B.
4 1
C.
3 2
D.
4 2

正确答案A

解析详情
答案 A作用域与变量遮蔽
思路与推导
  1. 1. `test` 函数内部,代码块 `{ int a = 3; a++; }` 修改的是最内层局部变量,块结束即销毁。

  2. 2. 块外的 `a++` 修改的是函数级局部变量(初始为 2),变为 3,输出 3。

  3. 3. `main` 中输出的是全局变量 `a`,值仍为 1。因此输出为 3 1。

第 7 题(单选题,2 分)

执行完下面的代码后,a、b 和 c 的值分别是()。

void byValue(int x) { x = 100; }
void byRef(int& x) { x = 200; }
void byPointer(int* x) { *x = 300; }

int main() {
    int a = 1, b = 2, c = 3;
    byValue(a);
    byRef(b);
    byPointer(&c);
    return 0;
}
A.
100 200 300
B.
1 2 3
C.
1 200 300
D.
1 2 300

正确答案C

解析详情
答案 C参数传递方式(值、引用、指针)
思路与推导
  1. 1. `byValue` 是值传递,不影响原变量 a。

  2. 2. `byRef` 是引用传递,直接修改原变量 b 为 200。

  3. 3. `byPointer` 是指针传递,通过地址修改原变量 c 为 300。故结果为 1 200 300。

第 8 题(单选题,2 分)

运行如下代码会输出()。

struct Point {
    int x, y;
};
struct Rectangle {
    Point topLeft;
    Point bottomRight;
};
int main() {
    Rectangle rect = {{10, 10}, {20, 20}};
    rect.topLeft.x = 5;
    Point* p = &rect.bottomRight;
    p->y = 5;
    cout << rect.topLeft.x + rect.bottomRight.y;
    return 0;
}
A.
10
B.
30
C.
15
D.
20

正确答案A

解析详情
答案 A结构体成员访问与指针修改
思路与推导
  1. 1. `rect.topLeft.x` 修改为 5。

  2. 2. 通过指针 `p` 修改 `rect.bottomRight.y` 为 5。

  3. 3. 最终求和 5 + 5 = 10。

第 9 题(单选题,2 分)

给定函数 climbStairs(int n) 的定义如下,则 climbStairs(5) 的返回的值是()。

int climbStairs(int n) {
    if(n <= 2) return n;
    int a = 1, b = 2;
    for(int i = 3; i <= n; i++) {
        int temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}
A.
5
B.
8
C.
13
D.
10

正确答案B

解析详情
答案 B递推算法(斐波那契数列)
思路与推导
  1. 典型的爬楼梯问题递推公式:f(n) = f(n-1) + f(n-2)。

  2. f(1)=1, f(2)=2

  3. f(3)=3, f(4)=5, f(5)=8。

  4. 函数通过迭代计算得到 8。

第 10 题(单选题,2 分)

对如下4个扑克牌进行排序,

struct Card {
    int value;
    char suit; // 花色
};

Card cards[4] = {{5, 'A'}, {3, 'B'}, {5, 'C'}, {3, 'D'}};

使用某排序算法按value排序后,结果为:{3,'D'},{3,'B'},{5,'A'},{5,'C'},则这个排序算法是稳定的吗?

A.
稳定,因为相同 value 的元素相对顺序保持不变
B.
不稳定,因为 {3,'D'} 出现在 {3,'B'} 之前
C.
无法判断
D.
稳定,因为结果是有序的

正确答案B

解析详情
答案 B排序算法的稳定性
思路与推导
  1. 稳定性要求相同键值的元素在排序后保持原有相对顺序。原序列中 {3,'B'} 在 {3,'D'} 之前,排序后变为 {3,'D'} 在 {3,'B'} 之前,相对顺序改变,故不稳定。

第 11 题(单选题,2 分)

下面的函数 selectTopK() 实现从 n 个学生中选出前 k 名成绩最好的学生颁发奖学金(不需要对所有学生完全排序,只需要找出前 k 名),则横线上应填写()。

struct Student {
    string name;
    int score;
};

void selectTopK(Student students[], int n, int k) {
    for (int i = 0; i < k; i++) {
        int maxIdx = i;
        for (___, ___){ // 在此处填入代码
            if (students[j].score > students[maxIdx].score) {
                maxIdx = j;
            }
        }
    }
    if (maxIdx != i) {
        Student temp = students[i];
        students[i] = students[maxIdx];
        students[maxIdx] = temp;
    }
}
A.
int j = 0; j < n; j++
B.
int j = i + 1; j < n; j++
C.
int j = i; j < n; j++
D.
int j = 1; j <= n; j++

正确答案B

解析详情
答案 B选择排序思想的应用
思路与推导
  1. 该算法旨在每轮选出剩余部分的最大值。在外层循环第 `i` 轮,需在下标 `[i+1, n-1]` 范围内寻找比 `students[i]` 更大的元素。因此内层循环起点应为 `j = i + 1`。

第 12 题(单选题,2 分)

某游戏的排行榜系统需要实时更新玩家分数。每次只有一个玩家的分数发生变化,排行榜已经是按分数降序排列的。现在需要将更新后的玩家调整到正确位置。下面的函数 updateRanking() 要实现上述功能,则两处横线上应分别填写()。

struct Player {
    string name;
    int score;
};

// 玩家索引playerIdx的分数刚刚更新,需要调整位置

void updateRanking(Player players[], int size, int playerIdx) {
    Player updatedPlayer = players[playerIdx];

    if (playerIdx > 0 && updatedPlayer.score > players[playerIdx - 1].score) {
        int i = playerIdx;
        while (_____) { // 在此处填入代码
            players[i] = players[i - 1];
            i--;
        }
        players[i] = updatedPlayer;
    }
    else if (playerIdx < size - 1 && updatedPlayer.score < players[playerIdx + 1].score) {
        int i = playerIdx;
        while (_____) { // 在此处填入代码
            players[i] = players[i + 1];
            i++;
        }
        players[i] = updatedPlayer;
    }
}
A.
i > 0 && updatedPlayer.score > players[i - 1].score
i < size - 1 && updatedPlayer.score < players[i + 1].score
B.
i < size - 1 && updatedPlayer.score < players[i + 1].score
i > 0 && updatedPlayer.score > players[i - 1].score
C.
i > 0 && updatedPlayer.score < players[i - 1].score
i < size - 1 && updatedPlayer.score < players[i + 1].score
D.
i > 0 && updatedPlayer.score < players[i - 1].score
i < size - 1 && updatedPlayer.score > players[i + 1].score

正确答案A

解析详情
答案 A插入排序思想与数组调整
思路与推导
  1. 排行榜按降序排列:

  2. 1. 分数变大需前移:只要 `i>0` 且分数大于前一名,就将前一名后移。

  3. 2. 分数变小需后移:只要 `i<size-1` 且分数小于后一名,就将后一名内移。选项 A 符合描述。

第 13 题(单选题,2 分)

给定如下算法,其时间复杂度为()。

bool f(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        int sum = 0;
        for (int j = 0; j < n; j++) {
            if (i & (1 << j)) {
                sum += arr[j];
            }
        }
        if (sum == target) return true;
    }
    return false;
}
A.
O(n)O(n)
B.
O(n2)O\left(n^{2}\right)
C.
O(n3)O\left(n^{3}\right)
D.
O(2n)O\left(2^{n}\right)

正确答案B

解析详情
答案 B时间复杂度分析
思路与推导
  1. 外层循环执行 nn 次,内层循环执行 nn 次。两层嵌套循环的总执行次数为 n×n=n2n \times n = n^2。尽管内部有位运算,但都是常数时间操作。因此复杂度为 O(n2)O(n^2)。

第 14 题(单选题,2 分)

执行下面 C++ 程序,会输出()。

int main() {
    ofstream fout("test.txt");
    fout << "Happy" << endl;
    fout << "New Year";
    fout.close();

    ifstream fin("test.txt");
    string s1, s2;
    fin >> s1;
    getline(fin, s2);
    fin.close();

    cout << s1 << "||" << s2;
    return 0;
}
A.
Happy|| New Year
B.
Happy| New Year
C.
HappyNew Year|
D.
Happy|

正确答案D

解析详情
答案 D文件流输入与 `getline` 特性
思路与推导
  1. 1. `fin >> s1` 读取第一个单词 "Happy",停在换行符前。

  2. 2. `getline(fin, s2)` 读取当前位置到行尾的所有内容。由于当前紧邻换行符,它读入空字符串并消耗换行符。因此 `s2` 为空,输出 `Happy||`。

第 15 题(单选题,2 分)

执行下面 C++ 代码,会输出()。

int divide(int a, int b) {
    if(b == 0) throw "Division by zero";
    return a / b;
}

int main() {
    int result = 0;
    try {
        result = divide(10, 0);
        cout << "A";
    }
    catch(const char* msg) {
        cout << "B";
        result = -1;
    }
    cout << result;
    return 0;
}
A.
A0
B.
B-1
C.
A10
D.
程序崩溃

正确答案B

解析详情
答案 B异常处理机制(try-catch)
思路与推导
  1. 1. `divide(10, 0)` 抛出异常,`try` 块内后续语句 `cout << "A"` 被跳过。

  2. 2. 进入 `catch` 块输出 `B` 并设 `result = -1`。

  3. 3. 执行 `try-catch` 外的 `cout << result` 输出 -1。综合输出 B-1。

判断题

第 1 题(判断题,2 分)

小杨正在调试他的温度传感器程序,其中变量 x 保存当前温度。下面这段代码运行后,变量 x 的值变成了 8。

int x = 5;
int *p = &x;
*p = *p + 3;

正确答案正确

解析详情
答案 正确指针解引用赋值
思路与推导
  1. `*p` 即为变量 `x` 的别名。`*p = *p + 3` 相当于 `x = 5 + 3`,故 `x` 变为 8。

第 2 题(判断题,2 分)

一个结构体不能包含另一个结构体。

正确答案错误

解析详情
答案 错误结构体嵌套定义
思路与推导
  1. C++ 允许结构体成员是另一个已定义的结构体类型(嵌套结构体)。

第 3 题(判断题,2 分)

在 C++ 中,定义如下二维数组: int a[3][4];,数组 a 在内存中是按行优先连续存放的,即 a[0][0]、a[0][1]、a[0][2]、a[0][3] 在内存中是连续的。

正确答案正确

解析详情
答案 正确二维数组内存布局
思路与推导
  1. C++ 二维数组采用行优先存储,即同一行的元素在内存地址上是连续相邻的。

第 4 题(判断题,2 分)

执行下面程序后,变量 a 的值会变成 15。

void add(int &x){
    x += 10;
}
int a = 5;
add(a);

正确答案正确

解析详情
答案 正确引用传递
思路与推导
  1. 函数形参是引用类型 `int &x`,修改 `x` 相当于直接操作实参 `a`,故 `a` 变为 15。

第 5 题(判断题,2 分)

执行下面的C++代码,会输出8,因为两个指针地址相差8个字节(假设int占4字节)。

int arr[5] = {1, 2, 3, 4, 5};
int* p1 = arr;
int* p2 = arr + 2;

cout << p2 - p1; // 输出结果

正确答案错误

解析详情
答案 错误指针算术运算
思路与推导
  1. 两个同类型指针相减的结果是它们之间相隔的元素个数,而非字节数。`p2 - p1` 结果为 2。

第 6 题(判断题,2 分)

考虑用如下递推方式计算斐波那契数列,时间复杂度是O(n)O(n)。

int n = 10;
int f[20];
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= n; i++)
f[i] = f[i - 1] + f[i - 2];

正确答案正确

解析详情
答案 正确算法复杂度分析
思路与推导
  1. 该代码通过单一循环完成计算,执行次数与 nn 成正比,复杂度为 O(n)O(n)。

第 7 题(判断题,2 分)

冒泡排序和插入排序都是稳定排序算法。

正确答案正确

解析详情
答案 正确排序算法稳定性性质
思路与推导
  1. 冒泡和插入排序在比较相等元素时均可设计为不改变相对位置,故属于稳定排序。

第 8 题(判断题,2 分)

下面这段代码实现了选择排序算法。

void sort(int a[], int n) {
    for (int i = 1; i < n; i++) {
        int x = a[i];
        int j = i - 1;
        while (j >= 0 && a[j] > x) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = x;
    }
}

正确答案错误

解析详情
答案 错误排序算法识别
思路与推导
  1. 代码逻辑是通过寻找位置插入当前元素,这是典型的插入排序实现,而非选择排序。

第 9 题(判断题,2 分)

下面代码可以正常编译并输出 10。

#include <iostream>
using namespace std;

int calculate(int x, int y = 10);
int main() {
    cout << calculate(5); // 调用1
    return 0;
}

int calculate(int x, int y) {
    return x * y;
}

int calculate(int x) { // 重载函数
    return x * 2;
}

正确答案错误

解析详情
答案 错误函数重载冲突与调用歧义
思路与推导
  1. `calculate(5)` 既能匹配带默认参数的版本,也能匹配单参数版本,编译器无法确定调用哪个,产生歧义报错。

第 10 题(判断题,2 分)

执行下面代码会输出 100 。

int main() {
    ofstream fout("data.txt");
    fout << 10 << " " << 20 << endl;
    fout << 30 << " " << 40;
    fout.close();

    ifstream fin("data.txt");
    int a, b, c, d;
    fin >> a >> b >> c >> d;
    fin.close();

    cout << a + b + c + d;
    return 0;
}

正确答案正确

解析详情
答案 正确文件读写操作
思路与推导
  1. 抽取运算符 `>>` 会自动跳过空格和换行符。四个整数被依次读入,总和为 100。