GESP 客观题评测系统

试卷解析 · 理解每一步

2026-09-Level-4

2026-09-Level-4

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

单选题

第 1 题(单选题,2 分)

小杨使用指针修改计数器的值。执行下面程序后,输出结果是( )。

int count = 8;
int *p = &count;
*p += 4;
cout << count << " " << *p;
return 0;
A.
8 8
B.
8 12
C.
12 12
D.
12 8

正确答案C

解析详情
答案 C指针解引用
思路与推导
  1. p保存count的地址,*p就是count本身。执行*p+=4后count从8变为12,因此count和*p均输出12,选C。

第 2 题(单选题,2 分)

关于下面指针声明的说法,正确的是( )。

int a = 10;
int b = 20;
const int *p = &a;
A.
可以通过 p 修改 a 的值
B.
可以令 p = &b
C.
p 的指向和所指向的值都不能修改
D.
p 必须始终指向 a

正确答案B

解析详情
答案 B指向常量的指针
思路与推导
  1. const int *p限制的是通过p修改所指对象,指针变量p本身仍可改变指向,所以可以执行p=&b,选B。

第 3 题(单选题,2 分)

小杨用二维数组记录仓库货物数量。执行下面代码后,变量 x 的值是( )。

int goods[3][4] = {{2, 4, 6, 8}, {10, 12, 14, 16}, {18, 20, 22, 24}};
int (*p)[4] = goods;
int x = *(*(p + 1) + 2);
A.
12
B.
14
C.
20
D.
22

正确答案B

解析详情
答案 B二维数组与行指针
思路与推导
  1. p指向含4个int的一行,p+1指向第二行;再取该行偏移2的元素,就是goods[1][2]=14,选B。

第 4 题(单选题,2 分)

下面函数用于将一个 3 行 5 列二维数组的第 r 行元素全部加 1,横线处正确的形参写法是( )。

void addOne(________, int r) {
    for (int j = 0; j < 5; j++) {
        arr[r][j]++;
    }
}
A.
int arr[][]
B.
int **arr
C.
int arr[][5]
D.
int arr[5][]

正确答案C

解析详情
答案 C二维数组形参
思路与推导
  1. 二维数组作为形参时必须明确每行的列数,int arr[][5]等价于指向含5个int的数组的指针,因此C正确。

第 5 题(单选题,2 分)

执行下面程序后,输出结果是( )。

int score = 60;

void update(int &score) {
    score += 5;
}

int main() {
    int score = 80;
    update(score);
    cout << score << " " << ::score;
    return 0;
}
A.
85 60
B.
80 65
C.
85 65
D.
80 60

正确答案A

解析详情
答案 A引用传参与作用域
思路与推导
  1. main里的局部score初值80,通过引用传入update后增加到85;全局score没有被修改,::score仍为60,因此输出85 60。

第 6 题(单选题,2 分)

执行下面程序后,输出结果是( )。

struct Device {
    int id;
    int state;
};

void reset(Device d) {
    d.state = 0;
}

void start(Device &d) {
    d.state += 1;
}

int main() {
    Device d{7, 2};
    reset(d);
    start(d);
    cout << d.id << " " << d.state;
    return 0;
}
A.
7 0
B.
7 1
C.
7 2
D.
7 3

正确答案D

解析详情
答案 D结构体值传递与引用
思路与推导
  1. reset接收副本,把副本state改成0不影响原对象。start接收引用,把原state从2加到3,id仍为7,输出7 3,选D。

第 7 题(单选题,2 分)

小杨定义了结构体数组,并使用指针访问其中的元素。执行下面代码后输出的是( )。

struct Book {
    string name;
    int pages;
};

int main() {
    Book books[2] = {{"C++", 120}, {"Math", 150}};
    Book *p = books + 1;
    p->pages += 10;
    cout << books[1].name << " " << books[1].pages;
    return 0;
}
A.
C++ 120
B.
Math 150
C.
Math 160
D.
C++ 160

正确答案C

解析详情
答案 C结构体指针
思路与推导
  1. books+1指向第二本书Math,p->pages+=10把其页数从150改为160,输出Math 160,选C。

第 8 题(单选题,2 分)

关于冒泡排序、插入排序和选择排序,下列说法正确的是( )。

A.
三种排序算法的最坏时间复杂度都是 O(n)O(n)
B.
冒泡排序只能从小到大排序,不能从大到小排序
C.
插入排序每次将一个待排序元素插入前面已经有序的序列中
D.
选择排序每轮只需要比较一次就能确定最小元素

正确答案C

解析详情
答案 C基础排序算法
思路与推导
  1. 插入排序把当前元素插入前面已排序的前缀中,C正确。三种算法的最坏复杂度均为平方级;冒泡可通过改变比较方向实现降序。

第 9 题(单选题,2 分)

某机器人每次可以向前移动 1 格或 2 格,到达第 n 格的方法数由下面函数计算。 ways(6) 的返回值是( )。

int ways(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 b;
}
A.
8
B.
10
C.
13
D.
21

正确答案C

解析详情
答案 C递推与滚动变量
思路与推导
  1. 最后一步走1格或2格,所以ways(n)=ways(n-1)+ways(n-2)。从1、2开始得到3、5、8、13,因此ways(6)=13,选C。

第 10 题(单选题,2 分)

对一组 struct student 的学生按成绩( score )升序排序。排序前后的数据如下。关于该排序的稳定性,判断正确的是( )。

struct student {
    int score;
    char id;
};

排序前:

(90, 'A'), (80, 'B'), (90, 'C'), (80, 'D')

排序后:

(80, 'B'), (80, 'D'), (90, 'C'), (90, 'A')
A.
稳定,因为所有成绩已经按升序排列
B.
稳定,因为分数相同不会影响排序结果
C.
不稳定,因为相同成绩的 (90, 'A') 和 (90, 'C') 的相对顺序发生了改变
D.
无法判断,因为没有给出排序算法的代码

正确答案C

解析详情
答案 C排序稳定性
思路与推导
  1. 原来同为90分的A在C之前,排序后C却在A之前,说明相等关键字的相对顺序被改变,所以不稳定,选C。

第 11 题(单选题,2 分)

下面代码使用插入排序将数组按升序排列,横线处应填写( )。

void insertionSort(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] == key
D.
a[j + 1] > key

正确答案B

解析详情
答案 B插入排序的移动条件
思路与推导
  1. 升序插入时应把大于key的前缀元素向右移动,为key腾出位置,因此填写a[j]>key,选B。相等元素不移动还能保持稳定性。

第 12 题(单选题,2 分)

下面代码的时间复杂度是( )。

int countPairs(int a[], int n) {
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (a[i] + a[j] == 100) {
                cnt++;
            }
        }
    }
    return cnt;
}
A.
O(1)O(1)
B.
O(n3)O(n^3)
C.
O(n)O(n)
D.
O(n2)O(n^2)

正确答案D

解析详情
答案 D嵌套循环复杂度
思路与推导
  1. 内层总执行次数为(n-1)+(n-2)+…+1=n(n-1)/2,每次只做常数操作,因此时间复杂度为平方级O(n²),选D。

第 13 题(单选题,2 分)

假设文件 data.txt 的内容如下:

Blue Sky

执行下面程序后,输出结果是( )。

int main() {
    ifstream fin("data.txt");
    string a, b;
    fin >> a >> b;
    cout << b << "-" << a;
    fin.close();
    return 0;
}
A.
Blue-Sky
B.
Sky-Blue
C.
Blue Sky
D.
Sky Blue

正确答案B

解析详情
答案 B文件流与分词读取
思路与推导
  1. fin>>a>>b按空白分隔读取,a得到Blue,b得到Sky。输出先b后a,并用连字符连接,结果是Sky-Blue,选B。

第 14 题(单选题,2 分)

执行下面程序后,输出结果是( )。

int main() {
    try {
        int age = -1;
        if (age < 0)
             throw age;
        cout << "A";
    } catch (const char *msg) {
        cout << "B";
    } catch (int value) {
        cout << "C" << value;
    }
    return 0;
}
A.
A
B.
B
C.
C-1
D.
程序崩溃

正确答案C

解析详情
答案 C异常类型匹配
思路与推导
  1. age为−1,throw age抛出int异常,跳过后面的A,匹配catch(int value)。该分支输出C再输出−1,得到C-1,选C。

第 15 题(单选题,2 分)

下面函数使用冒泡排序将数组按升序排列。为了在数组已经有序时提前结束,两处横线应分别填写( )。

void bubbleSort(int a[], int n) {
    for (int i = n - 1; i > 0; i--) {
        bool changed = __________;
        for (int j = 0; j < i; j++) {
            if (a[j] > a[j + 1]) {
                int t = a[j];
                a[j] = a[j + 1];
                a[j + 1] = t;
                changed = __________;
            }
        }
        if (!changed)
            break;
    }
}
A.
false , true
B.
true , false
C.
false , false
D.
true , true

正确答案A

解析详情
答案 A冒泡排序提前退出
思路与推导
  1. 每轮先设changed=false,只有真正交换过才设为true;若整轮没有交换,数组已排序,可提前结束。因此两空依次为false、true,选A。

判断题

第 1 题(判断题,2 分)

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

int a = 10;
int *p = &a;
*p += 5;

正确答案正确

解析详情
答案 正确指针修改对象
思路与推导
  1. p指向a,*p+=5直接把a从10修改为15,因此正确。

第 2 题(判断题,2 分)

一个函数必须在调用之前既声明又定义。

正确答案错误

解析详情
答案 错误函数声明与定义
思路与推导
  1. 调用前通常需要有可见声明,但定义可以放在调用之后或其他源文件中;并不要求调用前既声明又定义,因此错误。

第 3 题(判断题,2 分)

下面二维数组在内存中按行优先连续存储,因此 *(*(a + 1) + 0) 的值为 5 。

int a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};

正确答案正确

解析详情
答案 正确二维数组行优先存储
思路与推导
  1. a+1指向第二行,再偏移0得到a[1][0],值为5,因此正确。

第 4 题(判断题,2 分)

执行下面程序后会输出 20 。

void change(int x) {
    x = 20;
}

int main() {
    int x = 10;
    change(x);
    cout << x;
    return 0;
}

正确答案错误

解析详情
答案 错误值传递
思路与推导
  1. change的形参x是调用者x的副本。函数内部修改副本为20,main中的x仍为10,实际输出10,因此错误。

第 5 题(判断题,2 分)

下面结构体初始化语句是合法的。

struct Point {
    int x;
    int y;
};

Point p{3, 4};

正确答案正确

解析详情
答案 正确结构体聚合初始化
思路与推导
  1. Point的两个int成员按声明顺序由3和4初始化,得到x=3、y=4,符合C++11及之后的语法,因此正确。

第 6 题(判断题,2 分)

对于按升序实现的稳定插入排序,移动元素的条件通常应为 a[j] >= key ,这样能够保证相等元素的相对顺序不变。

while (j >= 0 && a[j] >= key) {
    a[j + 1] = a[j];
    j--;
}

正确答案错误

解析详情
答案 错误稳定插入排序
思路与推导
  1. 使用>=会把前面等于key的元素也右移,使新元素插到旧的相等元素之前,破坏稳定性,因此错误。应只移动严格大于key的元素。

第 7 题(判断题,2 分)

下面递推程序计算 n!n!。当 n = 4 时,返回值为 24 。

int factorial(int n) {
    int result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

正确答案正确

解析详情
答案 正确阶乘递推
思路与推导
  1. result从1开始,n=4时依次乘1、2、3、4,得到24,因此正确。

第 8 题(判断题,2 分)

下面两层循环的时间复杂度是 O(n2)O(n^2)。

for (int i = 0; i < n; i++) {
    for (int j = 1; j < n; j *= 2) {
        cout << i + j;
    }
}

正确答案错误

解析详情
答案 错误倍增循环复杂度
思路与推导
  1. 外层执行n次,内层j每次乘2,只执行约log₂n次,总复杂度是O(n log n),题目按紧确增长阶写成O(n²)不正确。

第 9 题(判断题,2 分)

假设文件能够正常打开,下面程序会把 Welcome 写入 log.txt 。

int main() {
    ofstream fout("log.txt");
    fout << "Welcome";
    fout.close();
    return 0;
}

正确答案正确

解析详情
答案 正确文件输出流
思路与推导
  1. ofstream用于文件输出,fout<<"Welcome"将文本写入log.txt,随后关闭文件;在题设文件正常打开条件下,表述正确。

第 10 题(判断题,2 分)

执行下面程序时, catch (int e) 能够捕获由 throw "Error" 抛出的异常,因此程序输出 Caught 。

int main() {
    try {
        throw "Error";
    } catch (int e) {
        cout << "Caught";
    }
    return 0;
}

正确答案错误

解析详情
答案 错误异常处理匹配
思路与推导
  1. 字符串字面量抛出后对应const char*类型,catch(int e)不能匹配,因此不会输出Caught;没有其他匹配处理器时程序终止,表述错误。