1 条题解

  • 0
    @ 2026-5-15 22:49:31

    《星火征途》初赛模拟卷(七)

    一、单选题(每题5分,共75分)

    1. 请将二进制数 1101.101 转换为等值的十进制数( B

    【答案:B】

    • A. 14.25 ❌ 计算错误
    • B. 13.625 ✅ 正确!整数部分:1101₂ = 1×8 + 1×4 + 0×2 + 1×1 = 13;小数部分:0.101₂ = 1×0.5 + 0×0.25 + 1×0.125 = 0.625;合计 = 13.625
    • C. 13.5 ❌ 小数部分计算错误,0.101₂ = 0.625 而非 0.5
    • D. 14.5 ❌ 整数和小数部分均计算错误

    2. 执行以下程序段,输出值是( B

    int x = 5;
    if (x == (3 >> 2))
        x = (8 >> 3);
    cout << x << endl;
    

    【答案:B】

    • A. 0 ❌ 这是 8>>3 的结果,但条件不成立不会执行
    • B. 5 ✅ 正确!3 >> 2:3 的二进制 11 右移 2 位得 0;5 == 0 为 false,if 分支不执行,x 保持原值 5
    • C. 120 ❌ 无此可能
    • D. 1 ❌ 这是 8>>3 的结果(1000₂ >> 3 = 1₂),但条件不成立

    3. 以下关于 C++ 求最小值函数 min() 的描述,不正确的是( D

    【答案:D】

    • A. 函数必须返回一个值 ✅ 正确!min() 函数必须返回比较后的最小值
    • B. 该函数可以嵌套调用 ✅ 正确!如 min(a, min(b, c)) 是合法的
    • C. 调用 min(5) 是错误的,不能通过编译 ✅ 正确!min() 需要两个参数,只传一个会编译错误
    • D. 调用 min()(不传任何参数)可以通过编译,结果为 0 ❌ 错误!min() 不传参数同样无法通过编译,不存在默认返回 0 的行为

    4. 计算表达式 a & b | (c ^ d) 的结果,其中 a=3b=7c=15d=4,结果是( A

    【答案:A】

    • A. 十进制 11 ✅ 正确!按位运算:3 & 7:0011 & 0111 = 0011 = 3;15 ^ 4:1111 ^ 0100 = 1011 = 11;3 | 11:0011 | 1011 = 1011 = 11(十进制)
    • B. 二进制 11 ❌ 二进制 11 即十进制 3,结果不对
    • C. 八进制 11 ❌ 八进制 11 即十进制 9,结果不对
    • D. 十六进制 11 ❌ 十六进制 11 即十进制 17,结果不对

    5. 以下关于 C++ 中 abs() 函数的描述,正确的是( A

    【答案:A】

    • A. abs() 函数可用于计算 int 类型整数的绝对值,头文件为 <cmath><cstdlib> ✅ 正确!abs() 用于求整数绝对值,需要包含 <cmath>(C++)或 <cstdlib>(C)
    • B. 调用 abs(3.14) 可以四舍五入得到 3 ❌ abs() 是求绝对值,不是四舍五入;且浮点数应使用 fabs()
    • C. abs(-1, -2) 的返回值是 1 ❌ abs() 只接受一个参数,传入两个参数会编译错误
    • D. 若传入负数浮点数,abs() 会自动截断小数部分后返回整数绝对值 ❌ abs() 对浮点数行为未定义,应使用 fabs()

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

    【答案:C】

    • A. int p = &x; ❌ p 是普通 int 变量,不能存储地址(类型不匹配)
    • B. int *p = x; ❌ 将 x 的值赋给指针 p,p 指向未知内存地址,危险
    • C. int *p = &x; ✅ 正确!int *p 声明指针变量,&x 获取 x 的地址,p 正确指向 x
    • D. p = *x; ❌ p 未声明类型,且 *x 对非指针变量解引用是非法的

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

    int a = 5;
    int* p1 = &a;
    int* p2 = p1;
    *p2 = 10;
    

    【答案:C】

    • A. 5 10 10 ❌ a 的值已被修改为 10
    • B. 5 10 15 ❌ 计算错误
    • C. 10 10 10 ✅ 正确!p1 指向 a,p2 = p1 使 p2 也指向 a;*p2 = 10 通过 p2 修改了 a 的值,因此 a=10, *p1=10, *p2=10,三者都指向同一块内存
    • D. 5 5 10 ❌ p1 和 p2 指向同一地址,修改会同步

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

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

    【答案:D】

    • A. 5 6 ❌ 顺序反了
    • B. 6 5 ❌ 顺序反了
    • C. 5 5 ❌ 计算错误
    • D. 6 6 ✅ 正确!二维数组行优先存储:p+0→1, p+1→2, p+2→3, p+3→4, p+4→5, p+5→6,所以 *(p+5)=6arr[1][1] 是第 2 行第 2 列,值为 6

    9. 执行完下面的代码后,输出是( A

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

    【答案:A】

    • A. 3 1 ✅ 正确!全局 a=1test() 中局部 a=2(遮蔽全局 a);内层块 { int a=3; a++; } 声明了新的局部 a=3a++ 使其变为 4,但该变量在块结束时被销毁;回到 test() 作用域,a 仍为 2(内层块的 a 是独立变量,不影响外层),a++ 后变为 3,输出 3;main() 中输出全局 a=1。最终输出 "3 1"
    • B. 4 1 ❌ 错误!内层块 { int a=3; a++; } 中的 a 是独立的新变量,与 test() 的局部 a=2 无关,内层块结束后 test()a 仍为 2,而非 4
    • C. 3 2 ❌ 全局 a 未被修改,仍为 1
    • D. 4 2 ❌ 全局 a 未被修改,且 test() 的 a 最终为 3 而非 4

    10. 执行完下面的代码后,abc 的值分别是( 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);
        cout << a << " " << b << " " << c;
        return 0;
    }
    

    【答案:C】

    • A. 100 200 300 ❌ a 是值传递,不会被修改
    • B. 1 2 3 ❌ b 和 c 分别被引用传递和指针传递修改了
    • C. 1 200 300 ✅ 正确!byValue(a) 是值传递,修改的是副本,a 仍为 1;byRef(b) 是引用传递,直接修改 b 为 200;byPointer(&c) 是指针传递,通过解引用修改 c 为 300
    • D. 1 2 300 ❌ b 被引用传递修改了

    11. 运行如下代码会输出( A

    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】

    • A. 10 ✅ 正确!rect.topLeft.x = 5 修改左上角 x 坐标为 5;p->y = 5 通过指针修改右下角 y 坐标为 5;5 + 5 = 10
    • B. 30 ❌ 使用了原始坐标值 10+20
    • C. 15 ❌ 计算错误
    • D. 20 ❌ 计算错误

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

    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;
    }
    

    【答案:B】

    • A. 5 ❌ 这是 climbStairs(4) 的结果
    • B. 8 ✅ 正确!这是爬楼梯问题(斐波那契数列变体):f(1)=1, f(2)=2, f(3)=3, f(4)=5, f(5)=8。迭代过程:i=3: temp=1+2=3, a=2, b=3;i=4: temp=2+3=5, a=3, b=5;i=5: temp=3+5=8, a=5, b=8;返回 b=8
    • C. 13 ❌ 这是 climbStairs(6) 的结果
    • D. 10 ❌ 计算错误

    13. 对如下 4 个扑克牌进行排序,struct Card 定义及初始数据如下。使用某排序算法按 value 排序后,结果为:{3,'D'}, {3,'B'}, {5,'A'}, {5,'C'},则这个排序算法是稳定的吗?( B

    struct Card {
        int value;
        char suit; // 花色
    };
    Card cards[4] = {{5,'A'}, {3,'B'}, {5,'C'}, {3,'D'}};
    

    【答案:B】

    • A. 稳定,因为相同 value 的元素相对顺序保持不变 ❌ 实际上相对顺序发生了变化
    • B. 不稳定,因为 {3,'D'} 出现在 {3,'B'} 之前 ✅ 正确!原数组中 value=3 的元素顺序为:{3,'B'} 在前,{3,'D'} 在后。排序后 {3,'D'} 在前,{3,'B'} 在后——相同值的元素相对顺序发生了改变,因此该排序算法是不稳定的
    • C. 无法判断 ❌ 可以通过比较相同值元素的相对顺序来判断
    • D. 稳定,因为结果是有序的 ❌ 结果有序不代表算法稳定,稳定性关注的是相同值元素的相对顺序

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

    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;
            }
        }
    }
    

    【答案:B】

    • A. int j = 0; j < n; j++ ❌ 每次从 0 开始会重复扫描已排好的前 i 个元素
    • B. int j = i + 1; j < n; j++ ✅ 正确!这是标准的选择排序写法:maxIdx 初始化为 i,然后从 j = i+1 开始扫描剩余元素,与 students[maxIdx] 比较并更新 maxIdx。虽然跳过了 j = i,但 maxIdx 已经是 i,所以 students[i] 本身已经参与了比较(作为初始最大值)
    • C. int j = i; j < n; j++ ❌ 从 j = i 开始会导致 students[i] 与自己比较一次(无意义),虽然结果正确但效率略低,不是标准写法
    • D. int j = 1; j <= n; j++ ❌ 每次都从头扫描,且索引从 1 开始会遗漏 students[0],边界条件 j <= n 会导致越界

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

    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】

    • A. 第一空:i > 0 && updatedPlayer.score > players[i - 1].score;第二空:i < size - 1 && updatedPlayer.score < players[i + 1].score ✅ 正确!分数升高时向前移动:只要前面还有元素且当前分数大于前一个,就继续前移;分数降低时向后移动:只要后面还有元素且当前分数小于后一个,就继续后移
    • B. 第一空和第二空互换 ❌ 逻辑反了,向前移动应判断大于,向后移动应判断小于
    • C. 第一空:i > 0 && updatedPlayer.score < players[i - 1].score ❌ 分数升高时应判断大于而非小于
    • D. 第二空:i < size - 1 && updatedPlayer.score > players[i + 1].score ❌ 分数降低时应判断小于而非大于

    二、判断题(每题5分,共25分)


    16. 位运算符 &|^~ 的优先级高于算术运算符 +-*/。( ✗ 错误

    【答案:错误 ✗】 解析:

    • C++ 运算符优先级(从高到低):
      • 算术运算符 * / % > + -
      • 移位运算符 << >>
      • 关系运算符 < > <= >=
      • 相等运算符 == !=
      • 位运算符 & > ^ > |
    • 实际上,算术运算符 + - 的优先级高于位运算符 & ^ |
    • 例如:a + b & c 等价于 (a + b) & c,而不是 a + (b & c)
    • 因此"位运算符优先级高于算术运算符"的说法是错误的 ✗

    17. 给定一个正整数 a,当需要计算 -a 的补码时,有这样一个计算技巧:将 a 的二进制形式从右往左扫描,遇到第一个 1 之后,将找到的第一个 1 左边的所有位都取反,能得到 -a 的补码。( ✓ 正确

    【答案:正确 ✓】 解析:

    • 这是计算负数补码的快捷方法
    • 标准方法:按位取反再加 1(~a + 1
    • 快捷方法:从右往左找到第一个 1,该位保持不变,它右边的位也保持不变(都是 0),它左边的所有位取反
    • 例如 a=6(二进制 0110):从右往左第一个 1 在倒数第二位,左边位取反得 1010,即 -6 的补码
    • 验证:~6 + 1 = 1001 + 1 = 1010,结果一致 ✓

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

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

    【答案:正确 ✓】 解析:

    • int x = 5; → x 初始值为 5
    • int *p = &x; → 指针 p 指向 x 的地址
    • *p = *p + 3;*p 即 x 的值 5,5 + 3 = 8,将 8 赋给 *p(即 x)
    • 最终 x = 8 ✓
    • 通过指针解引用可以间接修改原变量的值

    19. 一个结构体不能包含另一个结构体。( ✗ 错误

    【答案:错误 ✗】 解析:

    • 结构体可以嵌套:一个结构体的成员可以是另一个结构体类型
    • 例如:
    struct Point { int x, y; };
    struct Rectangle {
        Point topLeft;      // 结构体包含另一个结构体
        Point bottomRight;  // 完全合法!
    };
    
    • 这种嵌套结构体在 C++ 中非常常见,用于构建复杂的数据结构
    • 因此"结构体不能包含另一个结构体"的说法是错误的 ✗

    20. 执行下面程序后,变量 a 的值会变成 15。( ✓ 正确

    void add(int &x) {
        x += 10;
    }
    int main() {
        int a = 5;
        add(a);
        cout << a;
        return 0;
    }
    

    【答案:正确 ✓】 解析:

    • void add(int &x) → 参数 x引用类型& 表示引用传递)
    • add(a) 调用时,x 成为 a 的别名(引用),它们指向同一块内存
    • x += 10 等价于 a += 10,a 从 5 变为 15
    • 最终 a = 15 ✓
    • 引用传递 vs 值传递:引用传递会修改原变量,值传递只修改副本

    信息

    ID
    4875
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    14
    已通过
    2
    上传者