2024年03月CCF-GESP编程能力等级认证C++编程三级真题

2024年05月13日

一、单选题(每题 2 分,共 30 分)

第1题 整数-5的16位补码表示是( )。

A. 1005
B. 1006
C. FFFA
D. FFFB

答案:D 在 16 位补码表示中,最高位为符号位,0 表示正数,1 表示负数。-5 的二进制表示为 1111 1111 1111 1011。将其转换为十六进制,得到 FFFB。

第2题 如果16位短整数 -2 的二进制是"FFFE",则短整数 -4 的十六进制是( )。

A. FF04
B. FFFA
C. FFFC
D. FFFH

答案:C 给定短整数 -2 的二进制表示为 “FFFE”。由于短整数使用补码表示,我们可以将其转换为正数的二进制形式,然后再转换为十六进制。 将 “FFFE” 转换为正数的二进制形式得到 “0000 0000 0000 0010”。再将其转换为十六进制,得到 “0002”。 短整数 -4 的二进制表示为 “FFFC”。将其转换为十六进制,得到 “FFFC”。

第3题 下面C++代码执行后的输出是( )。

int main()
{
	cout << (3|16) << endl;
	cout << endl;
	return 0;
}
A. 3
B. 16
C. 19
D. 48

答案:C 代码中的 (3|16) 是按位或运算符,它将两个操作数的对应位进行逻辑或运算。在这里,3 的二进制表示是 0011,16 的二进制表示是 0001 0000。按位或运算后,得到 0011,即十进制的 3。

第4题 定义整数 int x=-5 ,则执行C++代码 cout << (x == (x << 1 >> 1)) 输出是( )。

A. 0
B. 1
C. -5
D. 5

答案:B 首先,我们分析 (x << 1 >> 1) 的结果。<< 和 >> 是位移运算符,x << 1 表示将 x 向左位移一位,而 x>>1 表示将 x 向右位移一位。

对于整数 -5,其二进制表示为 1111 1111 1111 1011。将其向左位移一位得到 1111 1111 1111 0110,再向右位移一位得到 1111 1111 1111 1011,即 -5 的二进制表示。

然后,我们比较 x 和 (x << 1 >> 1) 是否相等。由于它们的二进制表示完全相同,所以它们相等。

因此,cout << (x == (x << 1 >> 1)) 输出的结果为 1。

第5题 已知字符 ‘0’ 的ASCII编码的十进制表示为48,则执行下面C++代码后,输出是( )。

int main()
{
	string s="316";
	int n=s.length();
	int x=0;
	for(int i = 0; i < n; i++)
		x += s[i];
	cout << x << endl;
	cout << endl;
	return 0;
}
A. 10
B. 58
C. 154
D. 316

答案:C 在上述的 C++ 代码中,字符串 s 被初始化为 “316”,然后通过循环遍历字符串中的每个字符,并将其对应的 ASCII 值累加到变量 x 中。

对于字符 ‘3’,它的 ASCII 值是 51;对于字符 ‘1’,它的 ASCII 值是 49;对于字符 ‘6’,它的 ASCII 值是 54。

因此,x 的值为 51 + 49 + 54 = 154。

最后,cout << x << endl; 输出的结果为 154。

第6题 下面C++代码执行后数组中大于0的数的特征是( )。

int main()
{
	int a[20],i;
	for(i = 0; i < 20; i++)
		a[i] = i+1;
		
	for(int i = 0; i < 20; i++)
		if((a[i]%2)&&(a[i]%3))
			a[i] = 0;
			
	for(i = 0; i < 20; i++)
		if(a[i])
			cout << a[i] << " ";
			
	cout << endl;
	return 0;
}
A. 2的倍数
B. 3的倍数
C. 能被2或3整除的数
D. 能被2和3同时整除的数

答案:C 在给定的代码中,首先通过循环将数组 a 的元素初始化为 1 到 20。

然后,通过第二个循环遍历数组 a,对于每个元素,如果它既不能被 2 整除也不能被 3 整除,就将其设为 0。

最后,通过第三个循环遍历数组 a,输出不为 0 的元素。

因此,输出的结果是能够被 2 或 3 整除的数

第7题 执行下面C++代码后输出的第一个数是( )。

int main()
{
	int a[20],i;
	for(i = 0; i < 20; i++)
		a[i] = i+1;
		
	for( ; i > 0; i--)
		cout << a[i-1] << " ";
		
	cout << endl;
	return 0;
}
A. 20
B. 19
C. 1
D. 不确定

答案:A

第8题 在下列代码的横线处填写( ),可以使得输出是 GESP IS INTERESTING 。

int main()
{
	string str="gEsP is Interesting";
	int x = str.length();
	
	for(int i = 0; i < x; i++)
		if ((str[i]>='a') && (str[i]<='z'))
			________________________;
	cout << str << endl;
	cout << endl;
	return 0;
}
A. str[i]+=‘a’-‘A’
B. str[i]+=20
C. str[i]+=‘A’-‘a’
D. 无法实现

答案:C 选项 C. str[i] += ‘A’ - ‘a’ 将小写字母转换为对应的大写字母。通过逐个遍历字符串中的字符,如果字符是小写字母,则执行该操作,将其转换为大写字母。

第9题 假设英文句子由若干词构成。下面C++代码统计输出的词数是( )。

int main()
{
	string str="gEsP is Interesting !";
	int x = str.length();
	int nwords = 0;
	for(int i = 0; i < x; i++)
		if (str[i]==' '){
			nwords++;
			while(str[++i]==' ') ;
	}
	cout << nwords << endl;
	cout << endl;
	return 0;
}
A. 1
B. 2
C. 3
D. 4

答案:C 在给定的代码中,字符串 str 被初始化为 “gEsP is Interesting !”,然后通过变量 x 记录字符串的长度。

接下来,使用循环遍历字符串中的每个字符。如果当前字符是空格,则将词数 nwords 加一,并在连续的空格之后找到下一个非空格字符。

在给定的字符串中,有三个空格分隔的词:“gEsP”、“is” 和 “Interesting”。因此,通过统计空格的数量,词数 nwords 的值为 3。

最后,输出词数 nwords 的值为 3。

第10题 C++的字符变量的码值是整数,下面字面量形式的字符码值最大的是( )。

A. 100
B. 075
C. 0x70
D. 0x60

答案:C 在C++中,字符字面量可以用不同的进制表示:

十进制:直接写数字,如 100。 八进制:以 0 开头,后面跟0-7的数字,如 075。 十六进制:以 0x 或 0X 开头,后面跟0-9和A-F(或a-f)的数字,如 0x70 或 0X60。 现在我们来比较这些值的大小:

A. 100(十进制)
B. 075(八进制),转换为十进制是 7*8^1 + 5*8^0 = 56 + 5 = 61
C. 0x70(十六进制),转换为十进制是 7*16^1 + 0*16^0 = 112 + 0 = 112
D. 0x60(十六进制),转换为十进制是 6*16^1 + 0*16^0 = 96 + 0 = 96

比较这些值,最大的一个是C. 0x70,其十进制值为112。

第11题 下面C++程序执行的结果是( )。

int main()
{
	int a[20],i;
	int cnt=0;
	for(i = 0; i < 20; i++)
		a[i] = i+1;
	for( ; i > 1; i--)
		if((a[i-1]+a[i-2])%3)
			cnt++;
	cout << cnt << endl;
	cout << endl;
	return 0;
}
A. 5
B. 6
C. 10
D. 12

答案:D 在给定的程序中,首先通过循环将数组 a 的元素初始化为 1 到 20。

然后,在第一个循环结束后,变量 i 的值将为 20。接下来的第二个循环中,循环条件是 i > 1,并且在每次迭代中,如果前两个数组元素之和不能被 3 整除,则将 cnt 增加 1。

因为前两个数组元素是 20 和 19,它们的和是 39,39 不能被 3 整除,所以 cnt 的值会增加 1。

接着,循环继续进行,每次迭代中,都会检查前两个数组元素之和是否能被 3 整除并更新 cnt 的值。

由于数组 a 中的元素是连续递增的整数,并且每两个相邻元素的和都不能被 3 整除,所以在循环中的每次迭代中,都会将 cnt 的值增加 1。

最终,循环结束时,cnt 的值将为 12。

第12题 定义字符数组 char str[20] = {‘G’, ‘E’, ‘S’, ‘P’}; ,则 str 的字符串长度为( )。

A. 4
B. 5
C. 19
D. 20

答案:A 在这个定义中,字符数组str被初始化为包含字符'G', 'E', 'S', 'P'。由于没有显式地包含空字符'\0'在初始化列表中,并且初始化列表中的元素数量少于数组的大小,剩余的位置将被初始化为0,即空字符'\0'。因此,数组str实际上包含以下内容:

str[0] = 'G'
str[1] = 'E'
str[2] = 'S'
str[3] = 'P'
str[4] = '\0' // 隐式初始化为空字符

字符串长度通常是指从字符串的起始位置到第一个空字符'\0'之间的字符数。因此,字符串str的长度是4,因为它包含4个字符后紧跟一个空字符。

正确答案是 A. 4。

第13题 定义整型变量 int a=3, b=16 ,则 a|b 的值和 a+b 的关系是( )。

A. 大于
B. 等于
C. 小于
D. 等于或小于

答案:B 在给定的代码中,整型变量 a 被初始化为 3,二进制表示为 0011,而整型变量 b 被初始化为 16,二进制表示为 10000。

运算符 | 是按位或运算符,它将两个操作数的对应位进行逻辑或操作。对于每一位,只要其中一个操作数的对应位为 1,结果的对应位就为 1,否则为 0。

所以,执行 a | b 的运算,得到的结果是 10011,即十进制的 19。

而 a + b 的运算结果为 3 + 16,即十进制的 19。

因此,a|b 的值和 a+b 的关系是等于,对应选项 B. 等于。

第14题 小杨的父母最近刚刚给他买了一块华为手表,他说手表上跑的是鸿蒙,这个鸿蒙是( )。

A. 小程序
B. 计时器
C. 操作系统
D. 神话人物

答案:C 鸿蒙(HarmonyOS)是华为公司开发的一款全场景分布式操作系统。它旨在为各种设备提供统一的操作系统平台,包括但不限于智能手机、智能手表、智能电视、智能家居设备等。鸿蒙操作系统具有分布式架构、安全可靠、高性能等特点,并支持多种应用开发模式。

第15题 中国计算机学会(CCF)在2024年1月27日的颁奖典礼上颁布了王选奖,王选先生的重大贡献是( )。

A. 制造自动驾驶汽车
B. 创立培训学校
C. 发明汉字激光照排系统
D. 成立方正公司

答案:C 王选先生是中国著名的计算机科学家,他的重大贡献是发明了汉字激光照排系统,这一技术彻底改变了中国的印刷行业,并为汉字信息化处理做出了巨大贡献。

二、判断题(每题 2 分,共 20 分)

第16题 任意整数 a 的二进制反码与补码都有1位不同。 ( )

答案:错误 对于整数 a,它的二进制反码是将 a 的二进制表示中的每一位取反(0 变为 1,1 变为 0)所得到的结果。而补码是将 a 的二进制表示取反后再加 1 所得到的结果。

当 a 是正数时,它的补码与原码相同,二进制反码与补码都没有不同的位。

当 a 是负数时,它的补码与原码不同,二进制反码与补码一般会有多个位不同。

因此,对于任意整数 a,其二进制反码与补码的不同位数取决于 a 的正负性。所以,这个判断题是错误的。

第17题 对整型变量 int a = 3 ,执行C++代码 a << 2 将把2输出到 a 中。( )

答案:错误 在C++中,<< 是左移运算符,用于将二进制表示的整数向左移动指定的位数。左移运算符将所操作的数的二进制表示向左移动指定的位数,并在右侧用零填充。

对于整型变量 int a = 3;,其二进制表示为 0000 0011。执行 a << 2 的操作将 a 的二进制表示向左移动两位,得到的结果为 0000 1100,即十进制的 12。

所以,执行 C++ 代码 a << 2 不会将 2 输出到 a 中,而是将 a 的值左移两位得到 12。

因此,这个判断题是错误的。

第18题 下面C++代码可以计算1到100的累加和,采用的是穷举法。

int main()
{
	int i,sum=0;
	for(int i = 1; i <= 100 ; i++)
		sum += i;
	cout << sum << endl;
	cout << endl;
	return 0;
}

答案:错误 对于给定的代码,它可以计算1到100的累加和,但并不是采用穷举法。

穷举法通常是指通过逐个尝试所有可能的情况来解决问题。在这个代码片段中,并没有进行逐个尝试所有可能情况的操作。

相反,该代码使用了一个简单的循环来迭代从1到100的整数,并使用累加操作将它们相加。这是一种常见的计算累加和的方法,而不是穷举法。

第19题 一个 int 类型变量 a ,执行操作 (a << 2 >> 2) 后的值一定是 a 。( )

答案:错误 左移操作 << 将变量 a 的二进制表示向左移动指定的位数,而右移操作 >> 则将其向右移动指定的位数。

在一般情况下,对于有符号整数类型,右移操作 >> 会根据符号位进行填充,而左移操作 << 则会填充零。

然而,当 a 的值为负数时,右移操作 >> 的结果是依赖于具体的编译器实现的。有些编译器会进行算术右移,保留符号位,而有些编译器会进行逻辑右移,填充零。

因此,对于负数 a,执行 (a << 2) >> 2 后的结果不一定是 a。

第20题 在C++语言中, (010 << 1) 执行结果是 100 。( )

答案:错误 在C++中,以 “0” 开头的整数字面量表示的是八进制数。所以,010 表示的是八进制数 10,对应的二进制表示为 0010。

对于位运算符 <<,它将操作数的二进制表示向左移动指定的位数,右侧用零填充。在此例中,(010 << 1) 将 0010 向左移动 1 位,得到的结果是 0100,即十进制的 4。

因此,(010 << 1) 的执行结果是 4,而不是 100。

所以,这个判断题是错误的。

第21题 执行下面C++代码后将输出 2 。( )

int main()
{
	string str="gEsP is Interesting";
	int x = str.find("s");
	cout << x << endl;
	cout << endl;
	return 0;
}

答案:正确 给定的代码中,使用了字符串类 string 的 find 函数来查找子字符串 “s” 在字符串 “gEsP is Interesting” 中的位置。

find 函数返回子字符串第一次出现的位置,如果找不到则返回 string::npos。在这个例子中,“s” 第一次出现在位置 2(从 0 开始计数)。

因此,执行给定的代码后,会输出 2。

第22题 在C++语言中,字符数组被定义时,它的大小可以调整。( )

答案:错误 在C++中,字符数组的大小在定义时就被确定,并且无法调整。一旦定义了字符数组的大小,它的大小是固定的,无法动态改变。

第23题 对定义的数组 int a[7]={2,0,2,4,3,1,6} ,可以用简单循环就找到其中最小的整数。( )

答案:正确 以下是一种可能的实现方式:

int minVal = a[0]; // 假设第一个元素为最小值

for (int i = 1; i < 7; i++) {
    if (a[i] < minVal) {
        minVal = a[i]; // 更新最小值
    }
}

cout << "最小值:" << minVal << endl;

在这个代码片段中,我们假设数组的第一个元素 a[0] 为最小值,然后使用循环逐个比较数组中的元素,将较小的值更新为当前的最小值。

经过循环遍历后,变量 minVal 将保存数组中最小的整数值。

所以,这个判断题是正确的。可以使用简单循环来找到给定数组中的最小整数。

第24题 小杨今年春节回奶奶家了,奶奶家的数字电视要设置ip地址并接入到WIFI盒子才能收看节目,那这个WIFI盒子具有路由器的功能。( )

答案:正确 根据题目描述,奶奶家的数字电视需要设置IP地址并接入到WIFI盒子才能收看节目。在这种情况下,这个WIFI盒子具有路由器的功能。

路由器是一种网络设备,它能够将数据包从一个网络转发到另一个网络。它通常具有多个网络接口和路由表,用于确定数据包的最佳路径。

WIFI盒子在这种情况下充当了路由器的角色,负责将数字电视连接到局域网,并通过设置IP地址和连接到WIFI盒子的方式,使得数字电视能够接入网络并收看节目。

第25题 任何一个 for 循环都可以转化为等价的 while 循环( )。

答案:正确

三、编程题(每题 25 分,共 50 分)

第26题 字母求和

第27题 完全平方数