1 单选题(每题 2 分,共 30 分)
第1题 8位二进制原码能表示的最小整数是:( )
A. -127 B. -128 C. -255 D. -256
解析:答案:A。原码最高位表示符号,8位二进制原码低7位表示数值,最大值为127,所以8位二进制原码表达数值范围为-127≤X原≤127,故选A。
第2题 反码表示中,零的表示形式有:( )
A. 1种 B. 2种 C. 8种 D. 16种
解析:答案:B。反码表示负数时符号位1,其他位是原码取反,所以0可以表示为000…00(+0),也可以表示为111…11(-0),其中的00…00表示除符号位的所有数值位都为0,11…11表示除符号位的所有数值位都为1。故选B。
第3题 补码 1011 1011 对应的真值是:( )
A. -69 B. -59 C. -68 D. -58
解析:答案:A。负数的补码为除符号位外原码数值位取反加1,负数的补码转原码,仍可用为除符号位外补码数值取反加1(也可先减1,再取反)。补码 10111011转原码为11000101,(1000101)₂=69。故选A。
第4题 若X的8位补码为 0000 1010,则 X/2 的补码是( )。
A. 0000 0101 B. 1000 0101
C. 0000 0101 或 1000 0101 D. 算术右移后结果取决于符号位
解析:答案:A。正数补码与原码相同,X=(0000 1010)₂=10,X/2=5=(0000 0101)₂ (相当于右移一位)。故选A。
第5题 二进制数 1101.101 对应的十进制数是( )
A. 13.625 B. 12.75 C. 11.875 D. 14.5
解析:答案:A。1101.101₂=1×2³+1×2²+0×2¹+1×2⁰+1×2⁻¹+0×2⁻²+1×2⁻³=8+4+1+0.5+0.125=13.625。故选A。
第6题 补码加法中,若最高位和次高位进位不同,则说明( )
A. 结果正确 B. 发生上溢 C. 发生下溢 D. 结果符号位错误
解析:答案:B。在补码加法运算中,若最高位(符号位)产生的进位与次高位(最高数值位)产生的进位不同,则说明运算发生了溢出。一般正溢出称上溢出、负溢出称下溢出。溢出判断,一般用双符号位进行判断:符号位00表示正数,11表示负数,结果的符号位为01时,称为上溢;为10时,称为下溢。对正数加,最高位(符号位)不可能产生的进位,次高位(最高数值位)不产生的进位,则正常(结果正确);若最高位(符号位)不产生的进位,次高位(最高数值位)产生的进位,则发生上溢出。例如:设x=01101000,y=01001000,用补码求x+y。符号位用双符号位
[x]补+[y]补=00 1101000+00 1001000=01 0110000
上溢出(注负数加属减法)。
用补码求-x-y(属减法)。符号位用双符号位
[-x]补-[y]补=[-x]补+[-y]补=11 0011000+11 0111000=10 1010000
下溢出。
故选B。
第7题 八进制数35.6对应的十进制数是( )
A. 29.75 B. 28.5 C. 27.625 D. 30.25
解析:答案:A。35.6₈=3×8¹+5×8⁰+6×8¯¹=29.75。故选A。
第8题 二进制数 1010 | 1100 的结果是( )
A. 1000 B. 1110 C. 1010 D. 1100
解析:答案:B。按位或“|”,两个位同为0时才为0,两个位只要有为一个为1时为1。
故选B。
第9题 以下哪个位运算可以交换两个变量的值(无需临时变量)( )
A. a = a ^ b; b = a ^ b; a = a ^ b; B. a = a & b; b = a | b; a = a & b;
C. a = a | b; b = a ^ b; a = a ^ b; D. a = ~a; b = ~b; a = ~a;
解析:答案:A。位运算“^”的特点是两次^同一数,内容不变,即b^a^a=b。设原a、原b为运算前的a、b,a = a ^ b;,a=原a^原b,b = a ^ b=原a^原b^原b=原a,a = a ^ b=原a^原b^原b^原a=原b,实现了a、b交换。故选A。
第10题 如何正确定义一个长度为5的整型数组( )
A. int array = new int[5]; B. array int[5];
C. int[] array = {1,2,3,4,5}; D. int array[5];
解析:答案:D。A. int array = new int[5]; 错误;new 返回的是指针(int*),不能直接赋值给 int 变量。正确写法应为 int* array = new int[5];(动态数组,需手动 delete[])。B. array int[5]; 错误;语法完全不符合C++规范,类型和变量名顺序错误。C. int[] array = {1,2,3,4,5}; 错误;C++不支持int[]作为变量声明语法(Java风格)。正确静态初始化应为 int array[] = {1,2,3,4,5}; 或 int array[5] = {1,2,3,4,5};。D. int array[5]; 正确;这是C++中定义静态数组的标准方式,声明一个长度为5的整型数组(未初始化,值随机)。若需初始化,可改为 int array[5] = {};(全零初始化)。故选D。
第11题 以下程序使用枚举法(穷举法)求解满足条件的三位数,横线处应该填入的是( )
- #include <iostream>
- using namespace std;
- int main() {
- int count = 0;
- for (int i = 100; i <= 999; i++) {
- int a = i / 100;
- ___________________
- int c = i % 10;
- if (a * a + b * b == c * c) {
- count++;
- }
- }
- cout << count << endl;
- return 0;
- }
A. int b = (i / 10) / 10; B. int b = (i / 10) % 10; C. int b = (i % 10) / 10; D. int b = (i % 10) % 10;
解析:答案:B。按题目上下文,a为百位,c为位,那要填的b为十位。求十位,可将数整除10后,再求除以10的余数,即(i/10) %10;或将数除以100的余数,再整除10,即(i % 100) / 10。故选B。
第12题 以下程序模拟了一个简单的小球反弹过程,横线处应该填入的是( )
- #include <iostream>
- using namespace std;
- int main() {
- int height = 10;
- int distance = 0;
- for (int i = 1; i <= 5; i++) { // 模拟5次落地
- _________________
- height /= 2;
- distance += height;
- }
- cout << distance << endl;
- return 0;
- }
A. distance += height/2; B. distance += height;
C. distance += height*2; D. distance += height+1;
解析:答案:B。根据题目和程序,程序应该是求经过的总距离,下降h,反弹h/2,所以第8行应该填加下降h,第9、10行加反弹的h/2,参照第10行,第8行应填distance += height。故选B。
第13题 C++代码 string s = "GESP考试"; ,s占据的字节数是( )
A. 10 B. 8
C. 8或10 D. 取决于计算机采用什么编码
解析:答案:D。string占用字节数不同编译系统是不同,如TDM-GCC 32位为4字节,TDM-GCC 64位为8字节,MinGW-w64 64位为32字节。故选D。
第14题 C++语句 string s="Gesp Test"; 执行s.rfind("e")以后,输出的是( )
A. 1 B. 2 C. 6 D. 3
解析:答案:C。rfind()是从右向左查找。s.rfind("e")是从s中从右向左查找第一个"e",也就是Test中的"e",索引(下标)为6。故选C。
第15题 字符串"Gesp考试",字符数是( )
A. 10 B. 8
C. 6 D. 字符数多少取决于编码
解析:答案:C。在C++中汉字按GBK编码存储,英文单字节,汉字双字节。" Gesp考试")四个英文字符占4字节,两个汉字为2字符占4字节,合计6字符8字节。故选C。
2 判断题(每题 2 分,共 20 分)
第1题 C++中 string 的 == 运算符比较的是字符串的内存地址,而非内容。( )
解析:答案:错误。在 C++ 中,string 类型的对象使用 == 运算符进行比较时,并不是比较它们的内存地址,而是比较它们的内容;也就是说string 类型的个变量可以直接用==进行比较。故错误。
第2题 string 的 substr(1, 3) 返回从下标1开始的3个字符的子串。( )
解析:答案:正确。在 C++ 中,substr语法为substr(int pos = 0, int n = npos)
其中:pos——要截取的起始位置;位置从0开始计数,表示字符串中的第一个字符;n——要截取的字符数量; 默认值为npos(表示到字符串末尾的所有字符)。该函数返回一个包含从pos位置开始的n个字符的新字符串。故正确。
第3题 x是浮点数,(x >> 1)等价于 x / 2。( )
解析:答案:错误。在C++中,浮点数不能进行左移、右移操作,编译错误。故错误。
第4题 string("hello") == "hello" 的比较结果为true。
解析:答案:正确。在C++中,string("hello") == "hello" 的比较结果为true,输出为1。故正确。
第5题 sort可以直接用于排序set中的元素。( )
解析:答案:错误。在C++中,sort要求传入的迭代器必须是随机访问迭代器(RandomAccessIterator),而set的内部实现(基于红黑树)只提供双向迭代器(BidirectionalIterator),无法支持随机访问操作(如索引跳转)。故错误。
第6题 (x & 1) == 0 可以判断整数 x 是否为偶数。( )
解析:答案:正确。在C++中,(x & 1)则只保留x的最低位,其他位置为0,如x的最低位为0则x为偶数,否则x的最低位为1则x为奇数,故(x & 1) == 0 为“真”则整数x是为偶数,否则不是。故正确。
第7题 string 的 substr(2, 10) 在字符串长度不足时会抛出异常。( )
解析:答案:错误。在C++中,string的substr(2, 10)函数在字符串长度不足时确实可能抛出异常,具体行为如下:substr(int pos, int n)异常触发条件:当起始位置pos(本题是2)大于等于字符串长度时,会抛出out_of_range异常,当pos有效但pos + len(这里是2+10)超过字符串长度时,默认会截取到字符串末尾而不会抛出异常。故错误。
第8题 在数学纸面计算中,pow(2, 3)的计算结果一定是8,但是在C++中,如果遇到数据类型是浮点数,那就不一定正确。( )
解析:答案:正确。在数学纸面计算中,pow(2,3)计数结果一定是8(精确计算),但在C++中使用浮点数进行幂运算时,结果可能就不一定与纸面计算结果一致。原因是浮点数的精度限制,浮点数(float、double)遵循IEEE 754标准,以二进制形式存储数值,尾数用有限的二进制位表示,所以浮点数无法精确表示为二进制浮点数,导致舍入误差。运算过程中(pow为乘法)会累积这些误差,影响最终结果。故正确。
第9题 在C++中,枚举的底层类型可以是非整型(如 float 或 double )。( )
解析:答案:错误。C++标准规定枚举的底层类型只能是整数类型(包括char、short、int、long等),不支持浮点数(如float或double)作为底层类型。故错误。
第10题 函数声明double f(); 返回int时,会自动转换为double。( )
解析:答案:正确。在C++中,当函数声明的返回类型为double,但实际返回int类型时,编译器会自动将int值隐式转换为double类型。若反向操作(如声明返回int但实际返回double),则需显式类型转换,隐式转换会丢失小数部分。故正确。
3 编程题(每题 25 分,共 50 分)
3.1 编程题1
- 试题名称:奇偶校验
- 时间限制:1.0 s
- 内存限制:512.0 MB
3.1.1 题目描述
数据在传输过程中可能出错,因此接收方收到数据后通常会校验传输的数据是否正确,奇偶校验是经典的校验方式之一。
给定n个非负整数c₁,c₂,...,cₙ代表所传输的数据,它们的校验码取决于这些整数在二进制下1的数量之和的奇偶性。如果这些整数在二进制下共有奇数个1,那么校验码为1;否则校验码为0。你能求出这些整数的校验码吗?
3.1.2 输入格式
第一行,一个正整数n,表示所传输的数据量。
第二行,n个非负整数c₁,c₂,...,cₙ,表示所传输的数据。
3.1.3 输出格式
输出一行,两个整数,以一个空格分隔:
第一个整数表示c₁,c₂,...,cₙ在二进制下1的总数量;
第二个整数表示校验码(0或1)。
3.1.4 样例
3.1.4.1 输入样例1
- 4
- 71 69 83 80
3.1.4.2 输出样例1
- 13 1
3.1.4.3 输入样例2
- 6
- 1 2 4 8 16 32
3.1.4.4 输出样例2
- 6 0
3.1.5 数据范围
对于所有测试点,保证1≤n≤100,0≤cᵢ≤255。
3.2.6 编写程序思路
分析:本题目主要考察位运算,c & 1为1表示c为奇数,c & 1为0表示c为偶数。要统计一个数对应二进制中1的个数,方法有多种,这里给两种。方法一:可以用c & 1获得c对应二进制的最后一位,加c & 1即这位是1则加1,否则加0,然后将该数右移1一位,丢掉最后一位,直至该数为0结束。方法二:可以用 c =c & (c - 1)去掉c中对应二进制中最右边的1,直至c=0结束,能运算c = c & (c - 1)的次数即为c对应二进制中1的个数。
用方法一编程参考程序:
#include <iostream>
using namespace std;
int n, cnt=0;
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
int c;
cin >> c;
while (c) {
cnt += c & 1;
c >>= 1;
}
}
cout << cnt << " " << (cnt & 1) << endl;
return 0;
}
用方法二编程参考程序:
#include <iostream>
using namespace std;
int n, cnt = 0;
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
int c;
cin >> c;
while (c) {
c = c & (c - 1);
cnt++;
}
}
cout << cnt << " " << (cnt & 1) << endl;
return 0;
}
3.2 编程题2
- 试题名称:分糖果
- 时间限制:1.0 s
- 内存限制:512.0 MB
3.2.1 题目描述
有n位小朋友排成一队等待老师分糖果。第i位小朋友想要至少aᵢ颗糖果,并且分给他的糖果数量必须比分给前一位小朋友的糖果数量更多,不然他就会不开心。
老师想知道至少需要准备多少颗糖果才能让所有小朋友都开心。你能帮帮老师吗?
3.2.2 输入格式
第一行,一个正整数 ,表示小朋友的人数。
第二行,n个正整数a₁,a₂,...,aₙ,依次表示每位小朋友至少需要的糖果数量。
3.2.3 输出格式
输出一行,一个整数,表示最少需要准备的糖果数量。
3.2.4 样例
3.2.4.1 输入样例1
- 4
- 1 4 3 3
3.2.4.2 输出样例1
- 16
3.2.4.3 输入样例2
- 15
- 314 15926 53589793 238462643 383279502 8 8 4 1 9 7 1 6 9 3
3.2.4.4 输出样例2
- 4508143253
3.2.5 数据范围
对于所有测试点,保证1≤n≤1000,1≤aᵢ≤10⁹。
3.2.6 编写程序思路
分析:根据题意,第i人,除了至少给该人期望的糖果数,还必须比前一人多(至少多1颗),故第i人应该给的糖果数为两者中大的那个数。算法可以用变量,也可以用数组。
方法一(用变量):第i人应该给的糖果数为max(b+1,a),b为前一人给的糖果数,而a则是该人期望的糖果数(输入的数值)。对第1个人的前一人给的糖果数b为0。
#include <iostream>
using namespace std;
int n, a, b; //初始化a=0,b=0,b为前一人,a为当前人
long long ans; //答案准备糖果数初始化为0
int main() {
cin >> n; //输入人数
for (int i = 1; i <= n; i++) {
cin >> a; //输入当前人期望糖果数
b = max(b + 1, a); //当前人应给糖果数,b也是下一人的前一人
ans += b; //累加当前人应给糖果数
}
cout << ans << endl;
return 0;
}
方法二(用数组):第i人应该给的糖果数a[i]=max(a[i-1]+1,a[i]),右边的a[i-1]为前一人给的糖果数,而a[i]则是该人期望的糖果数(输入的数值)。对第1个人的前一人给的糖果数为0。完整程序如下:
#include <iostream>
using namespace std;
const int N = 1005; //不超过1000,用1005预留防越界
int n, a[N]; //初始化a全为0,a[0]=0
long long ans; //答案准备糖果数初始化为0
int main() {
cin >> n; //输入人数
for (int i = 1; i <= n; i++) {
cin >> a[i]; //输入当前人期望糖果数
a[i] = max(a[i - 1] + 1, a[i]); //前一人糖果数+1与当前人期望糖果数取大者
ans += a[i]; //累加当前人应给糖果数
}
cout << ans << endl;
return 0;
}