CCF编程能力等级认证GESP—C++3级—20230923
单选题(每题 2 分,共 30 分)
1、⼈们所使用的手机上安装的App通常指的是( )。
A.⼀款操作系统
B.⼀款应用软件
C.⼀种通话设备
D.以上都不对
正确答案:B
A选项:操作系统(如 Android 或 iOS)是手机的基础软件,而 App 是在操作系统上运行的应用程序。
B选项:App 是Application的缩写,意为“应用程序”。在手机上,App 通常指的是可以下载和安装到手机上的各种软件,这些软件提供了各种各样的功能和服务,如社交媒体、游戏、浏览器、支付工具等。
C选项:因为 App 不仅仅用于通话,它们提供了广泛的功能。
D选项:因为我们已经确定了 B 是正确答案。
2、下列流程图的输出结果是?( )
A. 60
B. 20
C. 5
D. 1
正确答案:B
a = 5, s = 1
a >= 4 | s = s * a | a = a - 1 |
---|---|---|
true | s = 5 | a = 4 |
true | s = 20 \color{red}{s = 20} s=20 | a = 3 |
false |
3、已知⼤写字符’A’的ASCII编码的⼗六进制表⽰为0x41 ,则字符’L’的ASCII编码的⼗六进制表⽰为 ( ) 。
A. 4A
B. 4B
C. 4C
D. 52
正确答案:C
字母 | 十六进制 |
---|---|
A | 0x41 |
B | 0x42 |
C | 0x43 |
D | 0x44 |
E | 0x45 |
F | 0x46 |
G | 0x47 |
H | 0x48 |
I | 0x49 |
J | 0x4A |
K | 0x4B |
L | 0x4C |
4、以下哪个不是C++语⾔中的运算符?( )
A. ~
B. ~~
C. <
D. <<
正确答案:B
A选项:是C++中的按位取反运算符。
B选项:不是C++中一个有效的运算符
C选项:是C++中的小于比较运算符。
D选项:是C++中的左移运算符。
5、如果数组定义为long long array[] = {3, 5, 7, 2};,则数组array占⽤的字节数为( )。
A. 32
B. 16
C. 8
D. 4
正确答案:A
一维数组中有4个元素,long long类型每个数字占8个字节,4 * 8 = 32。
6、⼀个数组定义为 double array[3]; ,则可合理访问这个数组的元素的下标最⼤为( )。
A. 2
B. 3
C. 23
D. 24
正确答案:A
数组下标从0开始,3个元素的下标分别是0、1、2
7、以下数组定义 ,符合C++语⾔语法的是( )。
A. double a[];
B. double b[] = {1, 2.0, '3'};
C. double c[3.0];
D. double[] d = new double[3];
正确答案:B
A选项:这个声明是不完整的,因为它没有指定数组的大小。在C++中,当你声明一个数组时,必须指定它的大小。例如,double a[10];
声明了一个包含10个双精度浮点数的数组。
B选项:这个声明是有效的。它定义了一个双精度浮点数数组b
,并用三个值初始化:一个整数1
,一个双精度浮点数2.0
,和一个字符3
。在C++中,字符常量(如3
)可以隐式地转换为整数,然后再转换为双精度浮点数。因此,这个数组将被初始化为{1.0, 2.0, 51.0}
(字符3
的ASCII值是51)。
C选项:这个声明是无效的。在C++中,数组的大小必须是一个整数常量表达式,而3.0
是一个双精度浮点数。
D选项:这个声明使用了C++的动态内存分配。虽然它在语法上是正确的,但它不是数组的定义,而是使用new
关键字动态创建了一个包含3个双精度浮点数的数组,并将其地址赋值给指针d
。这与选项A类似,也是不完整的,因为它没有指定数组的名称。
8、下列关于进制的叙述 ,正确的是( )。
A.只有十进制和二进制能够⽤来表示⼩数 ,八进制和十六进制不可以。
B.常用的进制包括二进制、八进制、⼗进制、十六进制,其他进制在日常⽣活中很少使用。
C.对任意正整数 ,其二进制表示不会⽐它的⼗进制表示更短。
D.正整数的八进制表⽰中 ,每⼀位可能出现的最大数字是8。
正确答案:C
A选项:这个叙述是不正确的。除了十进制和二进制,八进制和十六进制也常用于表示整数。八进制和十六进制都有各自的优点和用途,特别是在计算机科学中。
B选项:这个叙述也是不正确的。虽然二进制、八进制、十进制和十六进制是最常用的进制,但其他进制(如三进制、五进制等)在某些特定领域或应用中也可能被使用,尽管它们在日常生活中的使用频率较低。
C选项:这个叙述是正确的。对于任何正整数,其二进制表示的长度(位数)不会比其十进制表示更短。实际上,对于大多数正整数,其二进制表示通常比其十进制表示要长得多。
D选项:这个叙述是不正确的。在八进制中,每一位可能出现的最大数字是7,因为八进制是基于8的,但它使用0到7的数字来表示值。
9、下列关于C++语⾔中数组的叙述 ,不正确的是( )。
A.可以定义 0 个元素的数组。
B.不能定义-1 个元素的数组。
C.数组下标越界访问会产⽣编译错误。
D.程序运⾏时发⽣数组下标的越界访问 ,程序依然可能正常结束。
正确答案:C
A选项:这是正确的。在C++中,你可以定义一个空数组,即没有元素的数组。例如,int arr[0];
是合法的,但它没有实际用途,因为你不能访问它的任何元素。
B选项:这也是正确的。数组的大小必须是正整数或零。负数的数组大小在C++中是不合法的。
C选项:这是不正确的。在C++中,数组下标越界访问通常不会导致编译错误。编译器通常不会检查数组访问是否越界,因为这会增加编译时间,并且这种检查在运行时可能更加有效。因此,数组下标越界通常会导致运行时错误,而不是编译错误。
D选项:这是正确的。尽管数组下标越界访问是未定义行为(Undefined Behavior),但程序仍然有可能正常结束。未定义行为意味着编译器和运行时环境不对此行为做出任何保证,结果可能因编译器、操作系统或其他因素而异。在某些情况下,越界访问可能只是简单地读取或写入了不应该访问的内存位置,而没有导致程序崩溃或其他明显的错误。然而,这种情况是非常危险的,因为它可能导致难以追踪的错误和安全问题。
10、如果 a是int类型的变量 ,下列哪个表达式的值⼀定为true?( )
A. a + 1000 - 1000 == a
B. a * 2 / 2 == a
C. (a & 1) == 1
D. (a | 1) == a + 1
正确答案:A
a | 选项左侧的值 | 选项的结果 |
---|---|---|
3 | 3 | true |
21 4748 3647 | 越界 | false |
2 | 0 | false |
3 | 3 | false |
11、如果 a和b均为int类型的变量 ,下列表达式不能正确判断“a等于b” 的是( )。
A. ((a >= b) && (a <= b))
B. ((a >> 1) == (b >> 1))
C. ((a + b) == (a + a))
D. ((a ^ b) == 0)
正确答案:B
A选项:这个表达式首先检查a
是否大于或等于b
,然后检查a
是否小于或等于b
。如果a
同时满足这两个条件,那么a
必须等于b
。因此,这个表达式能正确判断“a等于b”。
B选项:这个表达式将a
和b
都右移一位(即除以2并向下取整),然后比较结果是否相等。但是,即使a
和b
不相等,它们的右移一位后的结果也可能相等。例如,如果a = 3
(二进制11
)和b = 2
(二进制10
),右移一位后都变为1
(二进制1
),所以这个表达式不能正确判断“a等于b”。
C选项:这个表达式检查a + b
是否等于2 * a
。如果a
和b
相等,那么a + b
确实等于2 * a
。因此,这个表达式能正确判断“a等于b”。
D选项:这个表达式使用按位异或运算符^
。如果a
和b
相等,那么它们的按位异或结果将是0(因为相同的位异或结果为0)。因此,这个表达式能正确判断“a等于b”。
12、如果 a为char类型的变量 ,下列哪个表达式可以正确判断“a是⼤写字母”?( )
A. a - 'A' <= 26
B. 'A' <= a <= 'Z'
C. 'A' <= 'a' <= 'Z'
D. ('A' <= a) && (a <= 'Z')
正确答案:D
A选项:这个表达式计算a
与A
之间的差值,并检查它是否小于或等于26。然而,这个表达式不能确保a
一定是大写字母,因为任何字符与A
的差值小于或等于26都不能保证它是大写字母。例如,a
与A
的差值也是26,但a
是小写字母。
B选项:这个表达式试图使用类似于数值比较的方式来比较字符,但它实际上是不合法的C++语法。在C++中,你不能像这样链式地比较字符。
C选项:这个表达式同样是不合法的C++语法,并且它尝试比较的是字符常量a
和Z
,而不是变量a
。
D选项:这个表达式首先检查a
是否大于或等于A
,然后检查a
是否小于或等于Z
。如果a
同时满足这两个条件,那么a
一定是一个大写字母。这是正确的方法来判断一个char
类型的变量是否是大写字母。
13、在下列代码的横线处填写( ) ,可以使得输出是“20 10”。
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 20;
a = (a << 8) | b;
________; // 在此处填写代码
cout << a << " " << b << endl;
return 0;
}
A. a = a >> 8; b = a & 0xff;
B. b = a >> 8; a = a & 0xff;
C. a = b; b = a & 0xff;
D. b = a; a = b;
正确答案:B
a = 10, b = 20;
a = (a << 8) | b = 1010 0000 0000 | 1 0100 = 1010 0001 0100 (2580)
选项 | 第一步 | 第二步 |
---|---|---|
A | a = 1010(10) | b = 1010(10) |
B | b = 1010(10) | a = 0001 0100(20) |
C | a = 1 0100(20) | b = 1 0100(20) |
D | b = 1010 0001 0100(2580) | a = 1010 0001 0100(2580) |
14、在下列代码的横线处填写( ) ,可以使得输出是“120”。
#include <iostream>
using namespace std;
int main() {
int array[5] = {1, 2, 3, 4, 5};
int res = 0;
for (int i = 0; i < 5; i++)
________; // 在此处填入代码
cout << res << endl;
return 0;
}
A. res += array[i];
B. res *= array[i]
C. res = array[i]
D. 以上均不对。
正确答案:D
A选项:这个选项会将array[i]
的值加到res
上。由于array
中的元素是1, 2, 3, 4, 5,所以res
的最终值将是这些数字的和,即1 + 2 + 3 + 4 + 5 = 15
。
B选项:这个选项会将res
与array[i]
的当前值相乘,并将结果存回res
。由于res
最初被初始化为0,任何数与0相乘都还是0,所以res
的值将始终保持为0。
C选项:这个选项会将res
的值设置为array[i]
的当前值。由于这个操作在循环中执行了5次,res
的值将会是array
中的最后一个元素,即5。
D选项:由于A、B、C选项都没有得到期望的输出“120”,所以这个选项是正确的。
15、在下列代码的输出是( )。
#include <iostream>
using namespace std;
int main() {
int array[10];
for (int i = 0; i < 10; i++)
array[i] = i;
for (int p = 2; p < 10; p++)
if (array[p] == p)
for (int n = p; n < 10; n += p)
array[n] = array[n] / p * (p - 1);
int res = 0;
for (int n = 1; n < 10; n++)
res += array[n];
cout << res << endl;
return 0;
}
A. 15
B. 28
C. 45
D. 55
正确答案:B
1.通过第一个for循环可以得到array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
2.第二个for循环打表如下:
3.第三个for循环是将数组中的数据求和 array[10] = {0, 1, 1, 2, 2, 4, 2, 6, 4, 6}
p | p < 10 | array[p] == p | n | n < 10 | array[n] = array[n] / p * ( p - 1) | n += p | array[10] |
---|---|---|---|---|---|---|---|
2 | true | true | 2 | true | array[2] = 1 | n = 4 | 0, 1, 1 \color {red}{1} 1, 3, 4, 5, 6, 7, 8, 9 |
4 | true | array[4] = 2 | n = 6 | 0, 1, 1, 3, 2 \color{red}{2} 2, 5, 6, 7, 8, 9 | |||
6 | true | array[6] = 3 | n = 8 | 0, 1, 1, 3, 2, 5, 3 \color{red}{3} 3, 7, 8, 9 | |||
8 | true | array[8] = 4 | n = 10 | 0, 1, 1, 3, 2, 5, 3, 7, 4 \color{red}{4} 4, 9 | |||
10 | false | ||||||
3 | true | true | 3 | true | array[3] = 0 | n = 6 | 0, 1, 1, 2 \color{red}{2} 2, 2, 5, 3, 7, 4, 9 |
6 | true | array[6] = 0 | n = 9 | 0, 1, 1, 2, 2, 5, 2 \color{red}{2} 2, 7, 4, 9 | |||
9 | true | arrat[9] = 1 | 12 | 0, 1, 1, 2, 2, 5, 2, 7, 4, 6 \color{red}{6} 6 | |||
12 | false | ||||||
4 | true | false | |||||
5 | true | true | 5 | true | array[5] = 4 | n = 10 | 0, 1, 1, 2, 2, 4 \color{red}{4} 4, 2, 7, 4, 6 |
10 | false | ||||||
6 | true | false | |||||
7 | true | true | 7 | true | array[7] = 6 | n = 14 | 0, 1, 1, 2, 2, 4, 2, 6 \color{red}{6} 6, 4, 6 |
14 | false | ||||||
8 | true | false | |||||
9 | true | false |
判断题(每题 2 分,共 20 分)
1、二进制数101.101在⼗进制下是5.005。
正确答案:错误
101.101 ( 2 ) = 1 ∗ 2 2 + 1 ∗ 2 0 + 1 ∗ 2 − 1 + 1 ∗ 2 − 3 = 4 + 1 + 0.5 + 0.125 = 5.625 101.101(2) = 1 * 2 ^2 + 1 * 2 ^ 0 + 1 * 2 ^{-1} + 1 * 2 ^ {-3} = 4 + 1 + 0.5 + 0.125 = 5.625 101.101(2)=1∗22+1∗20+1∗2−1+1∗2−3=4+1+0.5+0.125=5.625
2、在C++语⾔中,位运算符也有类似“先乘除、后加减”的优先级规则。因此,使⽤时应注意合理使⽤括号。
正确答案:正确
位运算符的优先级确实低于乘除和加减,因此在使用时确实需要注意使用括号来确保正确的运算顺序。
3、字符常量’3’的值和int类型常量3的值是相同的,只是占⽤的字节数不同。
正确答案:错误
字符常量’3’在ASCII编码中通常表示数字3,其整数值为51(在ASCII表中,'0’是48,'1’是49,依此类推)。而int类型常量3的值为3。所以它们的值是不同的。
4、在C++语⾔中,长度为n的数组,访问下标为n的元素会引起编译错误。
正确答案:错误
不会引起编译错误,使用时可能会产生错误。
5、在C++语⾔中,所有int类型的值,经过若⼲次左移操作(<<)后,它们的值总会变为0。
正确答案:正确
6、在C++语⾔中,数组下标的⼤⼩决定元素在逻辑上的先后顺序,与元素在内存中位置的先后顺序⽆关。
正确答案:错误
在C++中,数组下标的大小确实决定了元素在逻辑上的先后顺序,同时这个顺序也反映了元素在内存中的物理位置。数组元素在内存中是连续存储的,下标小的元素存储在内存的低地址处,下标大的元素存储在内存的高地址处。
7、在C++语⾔中,定义数组时,[]中必须指定元素个数。
正确答案:错误
数组定义方式有很多,正确的也包括: int d[]={1,2,3};这种格式。
8、著名的哥德巴赫猜想:任⼀⼤于2的偶数都可写成两个素数之和。我们可以通过枚举法来证明它。
正确答案:错误
哥德巴赫猜想是一个未解决的数学问题,目前还没有找到一种方法来证明或反驳它。虽然可以通过枚举法来验证该猜想对于某些特定的偶数成立,但这并不能作为证明整个猜想正确性的依据。
9、在C++语⾔中,表达式(0xff == 255) 的值为true。
正确答案:正确
在C++中,0xff是一个十六进制数,它等于十进制的255。因此,表达式(0xff == 255)的值确实是true。
10、如果a为int类型的变量,且表达式((a & 1) == 0) 的值为true,则说明a是偶数。
正确答案:正确
在C++中,位运算符&用于执行按位与操作。表达式(a & 1)将a的最低位与1进行按位与操作。如果结果为0,说明a的最低位是0,这通常意味着a是一个偶数。因为在二进制表示中,偶数的最低位是0,而奇数的最低位是1。
编程题 (每题 25 分,共 50 分)
⼩杨的储蓄
【问题描述】
⼩杨共有 N个储蓄罐,编号从0到N-1。从第1天开始,⼩杨每天都会往存钱罐里存钱。具体来说,第i天他会挑选一个存钱罐ɑi,并存⼊i元钱。过了D天后,他已经忘记每个储蓄罐里都存了多少钱了,你能帮帮他吗?
【输入描述】
输⼊2⾏,第一行两个整数N,D;第二行D个整数,其中第i个整数为ɑi(保证0≤ɑi≤N-1)。
每⾏的各个整数之间⽤单个空格分隔。
保证1≤N≤1000 ;1≤D≤1000
【输出描述】
输出N个用单个空格隔开的整数,其中第i个整数表示编号为i-1的存钱罐中有多少钱(i = 1,…,N)。
【样例输入 1】
2 3
0 1 0
【样例输出 1】
4 2
【样例解释1】
小杨在第1天、第2天、第3天分别向0号、1号、0号存钱罐存了1元钱、2元钱、3元钱,因此0号存钱罐有1+3=4元钱,而1号存钱罐有2元钱。
【样例输入 2】
3 5
0 0 0 2 0
【样例输出 2】
11 0 4
【题目大意】
1.小杨有n个存钱罐,存钱罐的编号是0~n-1。例如他有5天,每天向某个存钱罐存放i元钱,即:第1天,i=1;第2天,i=2,依次类推。
【考纲知识点】
1.基本运算、输入输出语句、一维数组的知识。
【解题思路】
1、按题目要求定义好需要的变量,并实现输入;
2、根据题意,最多有1000个存钱罐,建立存钱数组,数组大小大于等于1000即可。要存d天,存的元数分别是1~d元,循环范围最好写成i=1;i<=d;
3、每次存钱前,先读入要存的存钱罐编号,然后将i累加到该存钱罐中;
4、最后,输出每个存钱罐中的元数。注意存钱罐的编号是0~n-1。__
#include <iostream>
using namespace std;
int jar[1000];
int main() {
int n = 0, d = 0;
cin >> n >> d;
for (int i = 0; i < n; i++)
jar[i] = 0;
for (int i = 1; i <= d; i++){
int a = 0;
cin >> a;
jar[a] += i;
}
cout << jar[0];
for (int i = 1; i < n; i++)
cout << " " << jar[i];
cout << endl;
return 0;
}
进制判断
【问题描述】
N进制数指的是逢N进一的计数制。例如,人们日常生活中大多使用十进制计数,而计算机底层则一般使用二进制。除此之外,八进制和十六进制在一些场合也是常用的计数制(十六进制中,一般使用字母A至F表示十至十五)。现在有N个数,请你分别判断他们是否可能是二进制、八进制、十进制、十六进制。例如,15A6F就只可能是十六进制,而1011则是四种进制皆有可能
【输入描述】
输入的第一行为一个十进制表示的整数N。接下来 N行,每行一个字符串,表示需要判断的数。保证所有字符串均由数字和大写字母组成,且不以0 开头。保证不会出现空行。
保证 1≤N≤1000,保证所有字符串长度不超过10。
【输出描述】
输出N行,每行4个数,用空格隔开,分别表示给定的字符串是否可能表示一个二进制数、八进制数、十进制数十六进制数。使用 1 表示可能,使用0 表示不可能。
例如,对于只可能是十六进制数的 15A6F,就需要输出0001;而对于四者皆有可能的 1011,则需要输出1111。
【样例输入 1】
2
15A6F
1011
【样例输出 1】
0 0 0 1
1 1 1 1
【样例输入 2】
4
1234567
12345678
FF
GG
【样例输出 2】
0 1 1 1
0 0 1 1
0 0 0 1
0 0 0 0
【题目大意】
1.输入多个字符串,每个字符串包括09、‘A’‘Z’这些字符构成,判断能否可能是二进制、八进制、十进制和十六进制,有可能哪个进制都不是。
【考纲知识点】
1.多层循环结构、基本运算、输入输出语句、字符。
【解题思路】
1.根据进制知识,二进制由0和1,构成;八进制由07构成;十进制由09构成;十六进制由09和AF构成。如果字符中有大于1的字符,肯定不能用二进制表示;大于7的,不能用二进制和八进制表示;大于9的,不能用二进制、八进制和十进制表示;大于F的,不能用二进制、八进制、十进制和十六进制表示;
2.找出字符串中最大的那个字符,分别和1,8,9,F比较,如果小于等于,就可以用二进制、八进制、十进制或十六进制表示,否则不能表示。
#include <iostream>
using namespace std;
int main() {
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];
cout << (max <= '1') << " " << (max <= '7') << " " << (max <= '9') << " " << (max <= 'F') << endl;
}
return 0;
}