GESP 客观题评测系统

试卷解析 · 理解每一步

2024-09-Level-4

2024-09-Level-4

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

单选题

第 1 题(单选题,2 分)

在 C++ 中,()正确定义了一个返回整数值并接受两个整数参数的函数。

A.
int add(int a, int b) { return a + b; }
B.
void add(int a, int b) { return a + b; }
C.
int add(a, b) { return a + b; }
D.
void add(int a, int b) { return a - b; }

正确答案A

解析详情
答案 A函数定义语法
思路与推导
  1. C++中定义函数的标准语法为:返回类型 函数名(参数列表) { 函数体 }。

  2. 选项A正确指定了int作为返回类型,并接收两个int类型的形式参数。

第 2 题(单选题,2 分)

在C++中,形参与实参的关系描述正确的是()。

A.
形参在函数调用时指定,实参在函数定义时传递
B.
形参在函数定义时指定,实参在函数调用时传递
C.
形参和实参可以互换
D.
形参和实参必须是完全相同的类型,不能有任何差异。

正确答案B

解析详情
答案 B形参与实参的概念
思路与推导
  1. 形参(形式参数)是在函数定义时声明的,用于接收调用者传入的数据。

  2. 实参(实际参数)是在调用函数时实际传递给函数的值或变量。

第 3 题(单选题,2 分)

运行以下代码,屏幕上将输出()。

#include <iostream>
using namespace std;

int var = 100;

void function() {
    int var = 200;

    cout << var << " ";
    cout << ::var << " ";
}

int main() {
    cout << var << " ";

    function();

    var += 100;
    cout << var << " ";
    return 0;
}
A.
100 200 100 200
B.
100 200 100 300
C.
100 200 200 200
D.
100 200 200 300

正确答案A

解析详情
答案 A作用域与全局变量访问
思路与推导
  1. 1. main输出全局变量var(100);2. function内输出局部var(200)和全局::var(100);

  2. 3. main中var += 100修改全局变量为200并输出。最终序列:100 200 100 200。

第 4 题(单选题,2 分)

运行下面代码,屏幕上输出是()。

int arr[3] = {24, 9, 7};
int* p = arr;
p++;
cout << *p << endl;
A.
24
B.
9
C.
7
D.
不确定

正确答案B

解析详情
答案 B指针算术运算
思路与推导
  1. 指针p最初指向arr[0](24)。执行p++后,指针向后移动一个int单位的距离,指向arr[1]。

  2. 解引用*p获取当前指向的值,即9。

第 5 题(单选题,2 分)

运行下面代码片段的结果是()。

int x = 20;
int y = 24;
int* p = &x;
int* q = &y;
p = q;
A.
将x赋值为24
B.
将y赋值为20
C.
将q指向x的地址
D.
将p指向y的地址

正确答案D

解析详情
答案 D指针赋值逻辑
思路与推导
  1. 指针变量存储的是地址。执行p = q赋值操作后,指针p中存储的内容变为了q所指向的地址。

  2. 因此,p现在指向了变量y所在的内存地址。

第 6 题(单选题,2 分)

在C++中,()正确定义一个名为student的结构体,其中包含一个name字符数组和一个age整数?

A.
struct student { char name[20]; int age; };
B.
student struct { char name[20]; int age; };
C.
student struct { string name; int age; };
D.
struct student { char[20] name; int age; };

正确答案A

解析详情
答案 A结构体定义语法
思路与推导
  1. C++定义结构体的关键字是struct,成员定义需放在大括号内,且末尾必须有分号。

  2. 选项A中name数组和age整数的声明完全符合语法规范。

第 7 题(单选题,2 分)

在C++中,()正确声明了一个3行4列的二维数组。

A.
int arr[3, 4];
B.
int arr[3][4];
C.
int arr[4][3];
D.
int arr(3, 4);

正确答案B

解析详情
答案 B二维数组声明
思路与推导
  1. 声明二维数组的格式为:类型 数组名[行数][列数]。

  2. 3行4列对应的声明应为 int arr[3][4];。

第 8 题(单选题,2 分)

一个二维数组定义为 int arr[3][4];(假设一个int变量占4个字节),则 int arr[0] 占用( )个字节的内存。

A.
3
B.
4
C.
12
D.
16

正确答案D

解析详情
答案 D数组内存空间计算
思路与推导
  1. arr[0]表示二维数组的第一行,它本身是一个包含4个整数的一维数组。

  2. 由于每个int占4字节,总空间为 4 * 4 = 16 字节。

第 9 题(单选题,2 分)

下面代码采用递推算法来实现整数n的阶乘(n!=n×(n−1)×⋯×2×1n! = n \times (n-1) \times \cdots \times 2 \times 1),则横线上应填写()。

int factorial(int n) {
    int result = 1;
    for (int i = 2; i <= n; i++) {
        // 在此处填入代码
    }
    return result;
}
A.
result *= i;
B.
result += i;
C.
result *= result;
D.
result += result;

正确答案A

解析详情
答案 A阶乘的递推实现
思路与推导
  1. 阶乘运算是将1到n的所有正整数相乘。在循环中,result需要逐次乘以当前的循环变量i。

  2. 因此应填入 result *= i;。

第 10 题(单选题,2 分)

在排序算法中,稳定性指的是()。

A.
排序后数据不会丢失
B.
排序后相同元素的相对顺序保持不变
C.
排序后数据不会被修改
D.
排序后数据的时间复杂度不变

正确答案B

解析详情
答案 B排序算法稳定性
思路与推导
  1. 稳定性是指在排序过程中,具有相同值的元素在输出序列中保持其在原始序列中的相对位置。

  2. 这是评价排序算法应用场景的重要依据之一。

第 11 题(单选题,2 分)

下面代码实现了冒泡排序函数,则横线上应填写()。

// 交换数组arr的第i个元素和第j个元素

void swap(vector<int> &arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

int bubble_sort(vector<int> &arr) {
    for (int i = arr.size() - 1; i > 0; i--) {
        bool flag = false; // 标志位
        // 在此处填入代码
        for (_____ ) {
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1);
                flag = true;
            }
        }

        if (!flag)
            break; // 此轮“冒泡”未交换任何元素
    }
}
A.
for (int j = 0; j < arr.size() - 1; j++)
B.
for (int j = arr.size() - 1; j > 0; j--)
C.
for (int j = 0; j < i; j++)
D.
for (int j = i - 1; j <= 0; j--)

正确答案C

解析详情
答案 C冒泡排序逻辑优化
思路与推导
  1. 冒泡排序每一轮都会将当前未排序部分的最大值移至边界i处。内层循环只需遍历到i即可。

  2. 因此循环条件应为 j < i。

第 12 题(单选题,2 分)

上一题算法的时间复杂度为()。

A.
O(n2)O(n^2)
B.
O(2n)O(2^n)
C.
O(1)O(1)
D.
O(n)O(n)

正确答案A

解析详情
答案 A冒泡排序复杂度分析
思路与推导
  1. 冒泡排序包含两层嵌套循环,且最坏情况下需要进行的比较次数与元素数量n的平方成正比。

  2. 因此其时间复杂度为 O(n^2)。

第 13 题(单选题,2 分)

下面代码实现了插入排序函数(升序),则横线上应填写()。

void insertion_sort(vector<int> &nums) {
    for (int i = 1; i < nums.size(); i++) {
        int base = nums[i], j = i - 1;
        // 在此处填入代码
        while (_____) {
            nums[j + 1] = nums[j];
            j--;
        }
        nums[j + 1] = base;
    }
}
A.
while (j >= 0 && nums[j] > base)
B.
while (j > 0 && nums[j] > base)
C.
while (j >= 0 && nums[j] < base)
D.
while (j > 0 && nums[j] < base)

正确答案A

解析详情
答案 A插入排序条件控制
思路与推导
  1. 插入排序在移动元素时,需要满足当前索引j不越界且前一个元素大于基准值base。

  2. 对应的while循环条件是 j >= 0 && nums[j] > base。

第 14 题(单选题,2 分)

小杨用文件重定向实现在 log.txt 文件中输出日志,则下面横线上应填写()。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
    ofstream log_file("log.txt");

    streambuf* original_cout = cout.rdbuf();
    cout.rdbuf(log_file.rdbuf());
    // 在此处填入代码

    cout.rdbuf(original_cout); // 恢复原始的标准输出缓冲区
    return 0;
}
A.
cout << "This output will go to the log file." << endl;
B.
log_file << "This output will go to the log file." << endl;
C.
cout >> "This output will go to the log file." >> endl;
D.
log_file >> "This output will go to the log file." >> endl;

正确答案A

解析详情
答案 A标准输出重定向
思路与推导
  1. 代码通过 cout.rdbuf() 将标准输出流重定向到了文件流。此时执行 cout 语句会将内容直接写入文件。

  2. 填入 cout << ... 即可实现日志写入。

第 15 题(单选题,2 分)

运行下面的代码,屏幕上将输出()。

#include <iostream>
using namespace std;

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

int main() {
    int x = 10;
    int y = 0; // 设为 0 会导致除零错误
    try {
        int result = divide(x, y);
        cout << "result: " << result << endl;
    } catch (const runtime_error& e) {
        cout << "caught an exception: " << e.what() << endl;
    }
    return 0;
}
A.
division by zero error result: caught an exception:
B.
result: caught an exception: division by zero error
C.
caught an exception: division by zero error
D.
division by zero error caught an exception: division by zero error

正确答案C

解析详情
答案 C异常抛出与捕获
思路与推导
  1. divide函数抛出的runtime_error被catch块捕获。e.what() 返回抛出时设置的错误信息。

  2. 程序输出 "caught an exception: " 后紧跟错误字符串。

判断题

第 1 题(判断题,2 分)

代码 int a = 10; int* p = &a; 可以正确定义指针和初始化指针。

正确答案正确

解析详情
答案 正确指针定义与取地址
思路与推导
  1. 代码正确定义了一个整型变量a,并通过取地址符&将其地址赋给了整型指针p。

第 2 题(判断题,2 分)

在 C++ 中,引用传递允许函数修改传递给它的参数的值。

正确答案正确

解析详情
答案 正确引用传递机制
思路与推导
  1. 引用传递相当于给实参起了一个别名,函数内对引用参数的操作会直接反映在原始实参上。

第 3 题(判断题,2 分)

指针的大小与其所指向的变量的数据类型的大小相同。

正确答案错误

解析详情
答案 错误指针的存储空间
思路与推导
  1. 所有指针在同一系统环境下占用的内存空间是固定的(如64位系统为8字节),与其指向的数据类型无关。

第 4 题(判断题,2 分)

二维数组的行的大小的必须在定义时确定,列的大小可以动态变化。

正确答案错误

解析详情
答案 错误静态数组维度约束
思路与推导
  1. 在C++中声明静态二维数组时,所有维度的大小都必须在编译时确定,不能在运行期间动态改变。

第 5 题(判断题,2 分)

递推算法通过逐步求解当前状态和前一个或几个状态之间的关系来解决问题。

正确答案正确

解析详情
答案 正确递推算法核心思想
思路与推导
  1. 递推算法通过已知的初始状态,利用确定的数学关系逐步计算出后续各个状态的值。

第 6 题(判断题,2 分)

选择排序是稳定的排序算法。

正确答案错误

解析详情
答案 错误选择排序稳定性分析
思路与推导
  1. 选择排序在交换最小元素到前面的过程中,可能会跨越相同值的元素,从而破坏其原有的相对顺序。

第 7 题(判断题,2 分)

插入排序的时间复杂度总是比冒泡排序低。

正确答案错误

解析详情
答案 错误算法复杂度比较
思路与推导
  1. 在最坏情况下,插入排序和冒泡排序的时间复杂度均为 O(n^2),不存在“总是更低”的说法。

第 8 题(判断题,2 分)

在 C++ 中,如果没有捕获到异常(没有匹配的 catch 块),程序会继续执行而不会终止。

正确答案错误

解析详情
答案 错误异常处理机制
思路与推导
  1. 如果抛出的异常没有对应的catch块捕获,C++运行时会调用 std::terminate 强制终止程序。

第 9 题(判断题,2 分)

以下代码用递推法求斐波那契数列的第n项,时间复杂度为指数级。

int fibonacci(int n) {
    if (n == 0) return 0;
    if (n == 1) return 1;
    int f0 = 0; // F(0)
    int f1 = 1; // F(1)
    int current;
    for (int i = 2; i <= n; i++) {
        current = f0 + f1; // F(n) = F(n-1) + F(n-2)
        f0 = f1;
        f1 = current;
    }
    return current;
}

正确答案错误

解析详情
答案 错误算法复杂度识别
思路与推导
  1. 该代码使用了单一循环实现的迭代法求斐波那契数,其时间复杂度为线性阶 O(n),而非指数阶。

第 10 题(判断题,2 分)

执行下面 C++ 代码后,输出的是 20。

int point(int* p){
    return *p * 2;
}

int main() {
    int a = 10;
    int* p = &a;
    *p = point(p);
    cout << *p << endl;
}

正确答案正确

解析详情
答案 正确指针参数的副作用
思路与推导
  1. point(p)计算得出20,随后通过 *p = ... 将该结果存回指针p所指的地址a。因此最终输出20。