夜雨聆风学习资料网

ARTICLE · 1133994

C++ GESP 2026年9月三级真题与解析

C++ GESP 2026年9月三级真题与解析

C++ GESP 2026年9月三级真题及解析

一、单项选择题

  1. 关于计算机的数据编码,下面说法不正确的是(  )。

A. 数字 5,不管采用原码、反码、补码,它的 8 位二进制形式都是 。

B. 计算机科学中,单位换算默认 1KB = 1024B,而非 1000 B。

C. 原码是最直观的一种有符号数表示方法。

D. 反码运算中,最高位进位要抛掉。

【解析】正数的原码、反码、补码相同,5 的 8 位形式都是 0000 0101,A 正确;1KB = 1024B 是计算机科学的默认换算,B 正确;原码直接用最高位表示符号,最直观,C 正确;反码运算采用循环进位——最高位产生的进位要加到结果的最低位,而不是抛掉,D 错误。

【答案】D

  1. 关于进制转换,下面说法不正确的是(  )。

A. 数字 1101B 可以分解为:(十进制)

B. 数字 42Q 可以分解为:(十进制)

C. 数字 2BEH 可以分解为:(十进制)

D. 345Q = 0E3H(通常写作 E3H)

【解析】A、B、C 的按权展开均正确。D 中 345Q = 3×64 + 4×8 + 5 = 229,而 E3H = 14×16 + 3 = 227,两者不相等,D 错误。

【答案】D

  1. 下面程序的运行结果是(  )。
#include<iostream>
usingnamespacestd;
intmain(){
int x = 1;
for (int i = 0; i = 0; i <= 5) {
        x++;
    }
cout << x << endl;
return0;
}

A. 1

B. 10

C. 15

D. 程序编译错误

【解析】for 的第二个位置是循环条件,这里写成了赋值 i = 0,赋值表达式的值为 0,条件为假,循环体一次都不执行。程序可以正常编译(不会报错),x 保持 1,输出 1。

【答案】A

  1. 关于计算机编码中补码,下面说法错误的是(  )。

A. 正数的补码:与其原码、反码相同。

B. 负数的补码:将其对应的正数的原码按位取反(得到反码),然后加 1。

C. 8 位的补码,最大表示数据是 128,最小表示数据是 −128。

D. 负数的补码,从右往左扫描正数的二进制形式,遇到第一个 1 之后,左边的所有位都取反。

【解析】8 位补码的表示范围是 −128 ~ +127,最大值是 127 而不是 128,C 错误。A、B 是补码的基本规则;D 是求负数补码的简便方法,也正确。

【答案】C

  1. 下面程序执行的结果是(  )。
#include<iostream>
usingnamespacestd;
intmain(){
int x = 2026;
int count = 0;
while (x > 0) {
        count++;
        x = x & (x - 1);
    }
cout << count << endl;
}

A. 2026

B. 8

C. 16

D. 32

【解析】x & (x - 1) 每执行一次就消去 x 二进制中最低位的 1,循环次数即 x 中 1 的个数。2026 = ,共有 8 个 1,输出 8。

【答案】B

  1. 关于位运算,下列说法错误的是(  )。

A. 找唯一数:数组中唯一出现一次的数,其余出现两次,全部异或结果即为该数。例子:数组 [5, 7, 9, 7, 5](唯一数是 9)

B. 若左移导致高位溢出(如超过整型范围),结果不再符合乘法规律。

C. 有符号整数左移溢出时结果确定。

D.  位二进制数 ,一定是 4 的倍数(最后两位 00 是二进制的 00)。

【解析】有符号整数左移溢出在 C++ 中是未定义行为,结果不确定,C 错误。A 正确:相同的数异或为 0,全部异或后只剩下出现一次的数;B 正确;D 正确:末两位为 00 的数一定能被 4 整除。

【答案】C

  1. 计算 3 & 7 | 15 ^ ~11(a=3, b=7, c=15, d=11):(  )

A. -9

B. -1

C. -7

D. -5

【解析】优先级:~ 高于 & 高于 ^ 高于 |。~11 = -12(即 …11110100);3 & 7 = 3;15 ^ (-12) = …11111011 = -5;3 | (-5) = …11111011 = -5。结果为 -5。

【答案】D

  1. 下面函数是一个加密解密的函数,横线处应该填入的程序段是(  )。
#include<iostream>
#include<string>
usingnamespacestd;
intmain(){
int key;
cin >> key;
string msg = "Hello GESP";
cout << msg << endl;
for (int i = 0; i < msg.size(); i++) {
        msg[i] = msg[i] ^ key;
    }
cout << msg << endl;
    _________________________________
cout << msg << endl;
return0;
}

A. for (int i = 0; i < msg.size(); i++) { msg[i] = msg[i] | key; }

B. for (int i = 0; i < msg.size(); i++) { msg[i] = msg[i] >> key; }

C. for (int i = 0; i < msg.size(); i++) { msg[i] = msg[i] ^ key; }

D. for (int i = 0; i < msg.size(); i++) { msg[i] = msg[i] & key; }

【解析】异或运算满足自反性:(a ^ key) ^ key = a,所以解密只需对密文再异或同一个 key 即可还原明文,选 C。

【答案】C

  1. 下列程序是分别判断输入的 N 个数是否可能是二进制、八进制、十进制、十六进制,横线处应该填入的是(  )
#include<iostream>
usingnamespacestd;
intmain(){
int n = 0;
cin >> n;
for (int i = 0; i < n; i++) {
char str[11];
cin >> str;
char max = '0';
for (int i = 0; str[i] != '\0'; i++)
if (str[i] > max)
                max = str[i];
        _____________________________
    }
return0;
}

A. cout << (max <= '1') << " " << (max <= '7') << " " << (max <= '9') << " " << (max <= 'F') << endl;

B. cout << (max <= 1) << " " << (max <= 7) << " " << (max <= 9) << " " << (max <= 'F') << endl;

C. cout << (max <= 1) << " " << (max <= 7) << " " << (max <= 9) << " " << (max <= F) << endl;

D. cout << (max >= 1) << " " << (max >= 7) << " " << (max >= 9) << " " << (max >= F) << endl;

【解析】max 是字符类型,应与字符常量比较:二进制最大数码 '1',八进制最大 '7',十进制最大 '9',十六进制最大 'F'。B、C 用整数 1、7、9(甚至未加引号的 F)与字符比较,语义错误;D 的比较方向也不对。只有 A 正确。

【答案】A

  1. 下面的程序是位掩码技术实现权限的组合管理。首先定义四个权限常量,分别对应读、写、修改、删除,每个权限占用整数的一个独立二进制位。初始化权限掩码 mask 为 0,代表没有任何权限。如果想实现如下的操作:添加读权限;添加写权限;清除读权限,其他位不变;添加删除权限。则横线处应该填入的是(  )。
#include<iostream>
usingnamespacestd;
intmain(){
constint READ = 1 << 0;
constint WRITE = 1 << 1;
constint MODIFY = 1 << 2;
constint DELETE_ = 1 << 3;
int mask = 0;
    __________________________
return0;
}

A. mask = mask | READ;mask = mask | WRITE;mask = mask & (~READ);mask = mask | DELETE_;

B. mask = mask & READ;mask = mask & WRITE;mask = mask | (~READ);mask = mask & DELETE_;

C. mask = mask | READ;mask = mask & WRITE;mask = mask & (~READ);mask = mask | DELETE_;

D. mask = mask | READ;mask = mask | WRITE;mask = mask | (~READ);mask = mask | DELETE_;

【解析】位掩码规则:添加权限用 |(对应位置 1),清除权限用 & (~xxx)(对应位清 0,其他位不变)。依次为:加读 | READ,加写 | WRITE,清读 & ~READ,加删除 | DELETE_,A 正确。

【答案】A

  1. 下面选项中提到的变量都是正整数,关于位运算,下面说法错误的是(  )。

A. num >> 1,对于正整数,等价于对 num 做整数除以 2,向下取整

B. num | 0x0F,可以把 num 的低 4 位全部置为 1,高位保持不变

C. num ^ num 的结果一定等于 0

D. 若 num 右移时低位被移出丢弃,结果一定符合除法数学规律

【解析】右移丢弃低位等价于"除以 2 的幂后向下取整",与数学除法并不相同(如 5 >> 1 = 2,而 5 ÷ 2 = 2.5),D 错误。A、B、C 都是位运算的正确性质。

【答案】D

  1. 已知:a=0, b=2, c=11, d=7, e=5,表达式 !a & b << c ^ d | e 的结果是(  )

A. 5

B. 13

C. 7

D. 28

【解析】优先级:! 高于 << 高于 & 高于 ^ 高于 |。!a = !0 = 1;b << c = 2 << 11 = 4096;1 & 4096 = 0;0 ^ 7 = 7;7 | 5 = 7。结果为 7。

【答案】C

  1. 关于 string 的成员函数,下面说法错误的是(  )

A. size() 返回字符串的字符个数,不包含末尾的 '\0';length() 和 size() 功能完全等价

B. s.empty():字符串为空时返回 true,字符串不为空返回 false

C. s.substr(pos, len),当省略第二个参数 len 时,代表从 pos 位置一直截取到字符串末尾

D. s.erase(2) 表示删除字符串中下标为 2 的这一个字符

【解析】s.erase(2) 删除的是从下标 2 开始一直到末尾的所有字符,而不是仅一个字符;只删一个字符要写成 s.erase(2, 1),D 错误。A、B、C 均正确。

【答案】D

  1. 以下数组定义,符合 C++ 语法的是(  )

A. int a[] = {1, 2, 3.0};

B. int b['A'];

C. int c[ ];

D. float d[10.0];

【解析】B 中数组大小是常量表达式 'A'(其 ASCII 码为 65),等价于 int b[65];,合法。A 中 3.0 对 int 数组属于窄化转换,列表初始化不允许;C 未指定大小也未初始化,非法;D 数组大小必须是整型常量表达式,10.0 非法。

【答案】B

  1. 三进制有个奇妙的应用,有 1000 个酒缸,恰好 1 缸有毒。毒酒喝下后 24 小时毒发死亡;无毒酒无影响。总共有 48 小时,可以做两轮实验,每轮可以重新安排老鼠喝酒。有三种情况,这只老鼠两轮都不喝这缸酒;这只老鼠第一轮喝这缸酒;这只老鼠第二轮喝这缸酒,要保证找出毒酒,最少需要多少只老鼠?(  )

A. 5

B. 7

C. 10

D. 9

【解析】每只老鼠对每一缸酒有 3 种状态(两轮都不喝 / 第一轮喝 / 第二轮喝),即每只老鼠可以区分 3 种情况,k 只老鼠可区分  种情况。需要 :,,所以最少需要 7 只。

【答案】B

二、判断题

  1. 对于计算机编码运算,补码做加法运算时,如果最高位产生进位,需要把该进位循环加到结果的最低位。

A. 正确

B. 错误

【解析】"最高位进位循环加到最低位"是反码运算的规则;补码运算时最高位产生的进位直接丢弃即可。

【答案】错误

  1. 求 −13 的补码,可以对正数 13 的二进制,从右向左扫描,遇到第一个 1 之后,右边所有位全部取反,左边保持不变。

A. 正确

B. 错误

【解析】正确的简便方法是:从右向左扫描,遇到第一个 1 之后,左边的所有位取反,右边(含第一个 1)保持不变。题目把方向说反了。

【答案】错误

  1. 一个 8 位二进制原码表示的有符号数,可表示的数值范围是 −128 到 +127。

A. 正确

B. 错误

【解析】−128 ~ +127 是 8 位补码的范围。原码中 0 占用两个编码(+0、−0),其范围是 −127 ~ +127。

【答案】错误

  1. 这段代码执行后,能够将数组中所有大于 0 的元素赋值为 0。
int a[] = {2, -5, 7, 0, -1};
int n = sizeof(a) / sizeof(a[0]);
for (int num : a) {
if (num > 0) {
        num = 0;
    }
}

A. 正确

B. 错误

【解析】范围 for 循环中的 num 是数组元素的副本,修改 num 不会影响数组本身。要修改原数组应使用引用:for (int &num : a)。

【答案】错误

  1. a 是 int 有符号整型,若 (a & 1) == 1 结果为 true,则 a 一定是正奇数。

A. 正确

B. 错误

【解析】(a & 1) == 1 只能说明 a 是奇数,不能说明是正数。负奇数如 -3 的补码末位也是 1,-3 & 1 的值同样是 1。

【答案】错误

  1. char str[4] = "GESP"; 将在内存空间中给 str[4] 分配 5 个字节。

A. 正确

B. 错误

【解析】str[4] 只分配 4 个字节。而字符串 "GESP" 连同结束符 '\0' 共需要 5 个字节,4 个字节装不下,该初始化本身就是非法的(会导致无 '\0' 结尾,属于数组越界问题)。

【答案】错误

  1. 判断字符串中字符是否是 '0' 或者 '1',可以写条件:if(str[i]==0 || str[i]==1)。

A. 正确

B. 错误

【解析】0 和 1 是整数,字符 '0' 的 ASCII 码是 48、'1' 是 49,str[i]==0 判断的其实是结束符 '\0'。应写成 if (str[i]=='0' || str[i]=='1')。

【答案】错误

  1. 下面程序执行后,将输出 98。
#include<iostream>
usingnamespacestd;
intmain(){
int a = 'a', b = 'b';
if (a > 0 || b++ > 0) {
    }
cout << b;
}

A. 正确

B. 错误

【解析】a = 'a' = 97 > 0 为真,|| 发生短路,b++ > 0 不会执行,b 保持 'b' = 98,输出 98。

【答案】正确

  1. 枚举可以在保证不漏解的前提下缩小枚举范围,不是必须遍历全部。

A. 正确

B. 错误

【解析】枚举法的核心是在保证不漏解、不重复的前提下,利用约束条件缩小枚举范围、减少无效枚举,从而提高效率,并非必须遍历所有可能。

【答案】正确

  1. 下面流程图逻辑:初始化 sum←0,i←0;当 i<n 成立时,执行 sum←sum+a[i],再执行 i←i+1;循环结束输出 sum。该流程图可以正确计算一维数组 a[0]~a[n] 全部元素的总和。
  • 正确
  • 错误

【解析】循环条件是 i < n,循环结束时 i = n,累加的是 a[0] ~ a[n-1],共 n 个元素,并不包含 a[n]。若要包含 a[n],条件应改为 i <= n。

【答案】错误

三、编程题

公共二进制位

说明/提示

样例解释 1

三个整数的二进制表示分别为 、 和 。

其中第  位和第  位均为 ,因此答案为 。

数据范围

,。

题目分析

初始时,假定每个位都是 1;

然后将每个数字拆分成二进制形式,只要发现有一位为 0,那么就设置为 0,最后统计所有 1 的数量。

参考程序

#include<bits/stdc++.h>
usingnamespacestd;

int a[31];

intmain(){

int n;
cin >> n;

int cnt = 0;

for(int i = 0; i < 31; i++) a[i] = 1;

for(int i = 1; i <= n; i++){
int x;
cin >> x;
for(int j = 0; j < 31; j++){
if((x >> j & 1) == 0)
    a[j] = 0;
  }
 }

for(int i = 0; i < 31; i++)
if(a[i])
   cnt++;

cout << cnt;

return0;
}

分割字符串

题目分析

字符串模拟。

参考程序

#include<bits/stdc++.h>
usingnamespacestd;

intmain(){
string s;
    getline(cin, s);

for (int k = 1; ; ++k) {
int pos = -1;
for (int i = 0; i + k < s.size(); i++) {
bool ok = true;
for (int j = i; j < i + k; j++){
if (s[j] != ' ') { 
     ok = false; 
break; 
    }
   }

if (ok) { // 第一处连续 k 个空格
    pos = i; 
break; 
   }       
        }
if (pos < 0) {  // 无法再分割
cout << s << endl;
break;
        }
cout << s.substr(0, pos) << endl;      // 左侧(可能为空行)
        s = s.substr(pos + k);                 // 消耗恰好 k 个空格
    }
return0;
}

相关学习资料