ARTICLE · 1133994
C++ GESP 2026年9月三级真题与解析
C++ GESP 2026年9月三级真题及解析
一、单项选择题
关于计算机的数据编码,下面说法不正确的是( )。
A. 数字 5,不管采用原码、反码、补码,它的 8 位二进制形式都是 。
B. 计算机科学中,单位换算默认 1KB = 1024B,而非 1000 B。
C. 原码是最直观的一种有符号数表示方法。
D. 反码运算中,最高位进位要抛掉。
【解析】正数的原码、反码、补码相同,5 的 8 位形式都是 0000 0101,A 正确;1KB = 1024B 是计算机科学的默认换算,B 正确;原码直接用最高位表示符号,最直观,C 正确;反码运算采用循环进位——最高位产生的进位要加到结果的最低位,而不是抛掉,D 错误。
【答案】D
关于进制转换,下面说法不正确的是( )。
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
下面程序的运行结果是( )。
#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
关于计算机编码中补码,下面说法错误的是( )。
A. 正数的补码:与其原码、反码相同。
B. 负数的补码:将其对应的正数的原码按位取反(得到反码),然后加 1。
C. 8 位的补码,最大表示数据是 128,最小表示数据是 −128。
D. 负数的补码,从右往左扫描正数的二进制形式,遇到第一个 1 之后,左边的所有位都取反。
【解析】8 位补码的表示范围是 −128 ~ +127,最大值是 127 而不是 128,C 错误。A、B 是补码的基本规则;D 是求负数补码的简便方法,也正确。
【答案】C
下面程序执行的结果是( )。
#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
关于位运算,下列说法错误的是( )。
A. 找唯一数:数组中唯一出现一次的数,其余出现两次,全部异或结果即为该数。例子:数组 [5, 7, 9, 7, 5](唯一数是 9)
B. 若左移导致高位溢出(如超过整型范围),结果不再符合乘法规律。
C. 有符号整数左移溢出时结果确定。
D. 位二进制数 ,一定是 4 的倍数(最后两位 00 是二进制的 00)。
【解析】有符号整数左移溢出在 C++ 中是未定义行为,结果不确定,C 错误。A 正确:相同的数异或为 0,全部异或后只剩下出现一次的数;B 正确;D 正确:末两位为 00 的数一定能被 4 整除。
【答案】C
计算 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
下面函数是一个加密解密的函数,横线处应该填入的程序段是( )。
#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
下列程序是分别判断输入的 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
下面的程序是位掩码技术实现权限的组合管理。首先定义四个权限常量,分别对应读、写、修改、删除,每个权限占用整数的一个独立二进制位。初始化权限掩码 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
下面选项中提到的变量都是正整数,关于位运算,下面说法错误的是( )。
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
已知: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
关于 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
以下数组定义,符合 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
三进制有个奇妙的应用,有 1000 个酒缸,恰好 1 缸有毒。毒酒喝下后 24 小时毒发死亡;无毒酒无影响。总共有 48 小时,可以做两轮实验,每轮可以重新安排老鼠喝酒。有三种情况,这只老鼠两轮都不喝这缸酒;这只老鼠第一轮喝这缸酒;这只老鼠第二轮喝这缸酒,要保证找出毒酒,最少需要多少只老鼠?( )
A. 5
B. 7
C. 10
D. 9
【解析】每只老鼠对每一缸酒有 3 种状态(两轮都不喝 / 第一轮喝 / 第二轮喝),即每只老鼠可以区分 3 种情况,k 只老鼠可区分 种情况。需要 :,,所以最少需要 7 只。
【答案】B
二、判断题
对于计算机编码运算,补码做加法运算时,如果最高位产生进位,需要把该进位循环加到结果的最低位。
A. 正确
B. 错误
【解析】"最高位进位循环加到最低位"是反码运算的规则;补码运算时最高位产生的进位直接丢弃即可。
【答案】错误
求 −13 的补码,可以对正数 13 的二进制,从右向左扫描,遇到第一个 1 之后,右边所有位全部取反,左边保持不变。
A. 正确
B. 错误
【解析】正确的简便方法是:从右向左扫描,遇到第一个 1 之后,左边的所有位取反,右边(含第一个 1)保持不变。题目把方向说反了。
【答案】错误
一个 8 位二进制原码表示的有符号数,可表示的数值范围是 −128 到 +127。
A. 正确
B. 错误
【解析】−128 ~ +127 是 8 位补码的范围。原码中 0 占用两个编码(+0、−0),其范围是 −127 ~ +127。
【答案】错误
这段代码执行后,能够将数组中所有大于 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)。
【答案】错误
a 是 int 有符号整型,若 (a & 1) == 1结果为 true,则 a 一定是正奇数。
A. 正确
B. 错误
【解析】(a & 1) == 1 只能说明 a 是奇数,不能说明是正数。负奇数如 -3 的补码末位也是 1,-3 & 1 的值同样是 1。
【答案】错误
char str[4] = "GESP";将在内存空间中给 str[4] 分配 5 个字节。
A. 正确
B. 错误
【解析】str[4] 只分配 4 个字节。而字符串 "GESP" 连同结束符 '\0' 共需要 5 个字节,4 个字节装不下,该初始化本身就是非法的(会导致无 '\0' 结尾,属于数组越界问题)。
【答案】错误
判断字符串中字符是否是 '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')。
【答案】错误
下面程序执行后,将输出 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。
【答案】正确
枚举可以在保证不漏解的前提下缩小枚举范围,不是必须遍历全部。
A. 正确
B. 错误
【解析】枚举法的核心是在保证不漏解、不重复的前提下,利用约束条件缩小枚举范围、减少无效枚举,从而提高效率,并非必须遍历所有可能。
【答案】正确
下面流程图逻辑:初始化 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;
}
