2023年6月GESP C++ 四级试卷解析

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

1.高级语言编写的程序需要经过以下( )操作,可以生成在计算机上运行的可执行代码。

A.编辑

B.保存

C.调试

D.编译

【答案】D

【考纲知识点】编程环境(一级)

【解析】本题属于考察计算机基础知识中的编辑、编译、解释、调试的概念;其中编辑是编写修改代码,保存是将代码保存下来,调试是测试运行代码,而编译是将源程序翻译成可执行代码,所以本题正确答案为D。

2.排序算法是稳定的(Stable Sorting),就是指排序算法可以保证,在待排序数据中有两个相等记录的关键字R和S(R出现在S之前),在排序后的列表中R也一定在S前。下面关于排序稳定性的描述,正确的是( )。

A.冒泡排序是不稳定的。

B.插入排序是不稳定的。

C.选择排序是不稳定的。

D.以上都不正确。

【答案】C

【考纲知识点】排序算法(四级)

【解析】本题属于考察排序的基本概念;冒泡排序、,插入排序一般是稳定的,而选择排序一般是不稳定的,所以本题正确答案为C。

3.下列关于C++语言中指针的叙述,不正确的是( )。

A.指针变量中存储的是内存地址。

B.定义指针变量时必须指定其指向的类型。

C.指针变量只能指向基本类型变量,不能指向指针变量。

D.指针变量指向的内存地址不一定能够合法访问。

【答案】C

【考纲知识点】指针(四级)

【解析】本题属于考察指针的基本概念;指针变量不仅可以指向基本类型的变量也可以指向其它的指针变量,所以本题正确答案为C。

4.下列关于C++语言中数组的叙述,不正确的是( )。

A.一维数组在内存中一定是连续存放的。

B.二维数组是一维数组的一维数组。

C.二维数组中的每个一维数组在内存中都是连续存放的。

D.二维数组在内存中可以不是连续存放的。

【答案】D

【考纲知识点】二维及多维数组(四级)

【解析】本题属于考察二维数组的基本概念;数组(包括多维数组)在内存中必须要连续存放,所以本题正确答案为D。

5.下列关于C++语言中函数的叙述,正确的是( )。

A.函数必须有名字。

B.函数必须有参数。

C.函数必须有返回值。

D.函数定义必须写在函数调用前。

【答案】A

【考纲知识点】函数(四级)

【解析】本题属于考察函数的基本概念;函数可以没有参数和返回值, 同时函数定义可以在调用之后,只需要在调用前要加函数声明,但是函数必须要有名字,所以本题正确答案为A。

注:如果了解“匿名函数”概念(该概念超出考纲范围),应注意区分:匿名函数,正式名称为“表达式”,是一种可捕捉参数变量的无命名函数对象,属于“函数对象”的一种,并不属于“函数”范畴。函数对象与函数在使用时经常可以自动相互转换,但二者在实现机制上完全不同。

6.下列关于C++语言中变量的叙述,正确的是( )。

A.变量定义后可以一直使用。

B.两个变量的变量名不能是相同的。

C.两个变量的变量名可以相同,但它们的类型必须是不同的。

D.两个变量的变量名可以相同,但它们的作用域必须是不同的。

【答案】D

【考纲知识点】全局/局部作用域(四级)

【解析】本题属于考察变量定义域的基本概念; 在C++中两个变量可以取相同的变量名,只要它们在不同的作用域下即可,所以本题正确答案为D。

7.一个二维数组定义为double array[3][10];,则这个二维数组占用内存的大小为( )。

A. 30

B. 60

C. 120

D. 240

【答案】D

【考纲知识点】二维及多维数组(四级)

【解析】本题属于考察内存的基本概念;double类型的数据占用内存是8字节位,array数组共使用了30个double类型的数据,占用内存为30*8=240位字节。所以本题正确答案为D。

8.一个变量定义为int *p = nullptr;,则下列说法正确的是( )。

A.该指针变量的类型为int。

B.该指针变量指向的类型为int。

C.该指针变量指向的内存地址是随机的。

D.访问该指针变量指向的内存会出现编译错误。

【答案】B

【考纲知识点】指针(四级)

【解析】本题属于考察指针的基本概念。; 指针变量的类型为int *,A选项错误;nullptr指向的是一个变量固定的内存地址0,C选项错误;nullptr指向的内存位置通常不存放有效数据,因此常用来表示未指向有效数据,是固定的,也可以进行访问它可能出现运行时错误,但不会出现编译错误,D选项错误。所以选项ACD错误,所以本题正确答案为B。

9.一个二维数组定义为int array[5][3];,则array[1][2]和array[2][1]在内存中的位置相差多少字节?( )

A. 2字节。

B. 4字节。

C. 8字节。

D.无法确定。

【答案】C

【考纲知识点】二维及多维数组(四级)

【解析】本题属于考察内存地址的基本概念;array[1][2]和array[2][1]中间差了array[2][0],相当于差了2个int,也就是8字节位,所以本题正确答案为C。

10.如果a为int类型的变量,且a的值为6,则执行a &= 3;之后,a的值会是( )。

A. 3

B. 9

C. 2

D. 7

【答案】C

【考纲知识点】位运算(三级)

【解析】本题属于考察位运算的基本概念;a &= 3;等价于a = a & 3;。&为按位与运算,a的原值为6,要计算6 & =3,先把6和3都转换为二进制,也就是110&11,得到的结果为10,也就是2。所以本题正确答案为C。

11.一个数组定义为int a[5] = {1, 2, 3, 4, 5};,一个指针定义为int * p = &a[2];,则执行a[1] = *p;后,数组a中的值会变为( )。

A. {1, 3, 3, 4, 5}

B. {2, 2, 3, 4, 5}

C. {1, 2, 2, 4, 5}

D. {1, 2, 3, 4, 5}

【答案】A

【考纲知识点】指针(四级)

【解析】本题属于考察指针的基本概念;首先让指针p指向变量a[2]的内存地址,然后让a[1]=*p,也就是让a[1]=a[2],所以a数组变为{1, 3, 3, 4, 5}。所以本题正确答案为A。

12.以下哪个函数声明在调用时可以传递二维数组的名字作为参数?( )

A. void BubbleSort(int a[][4]);

B. void BubbleSort(int a[3][]);

C. void BubbleSort(int a[][]);

D. void BubbleSort(int ** a);

【答案】A

【考纲知识点】函数、指针、二维及多维数组(四级)

【解析】本题属于考察函数参数的基本概念。; 当把数组作为函数的一个参数时,实际上只是传递了数组第一个参数的的首指针。于是,传递,多维数组时,所以并不关心数组的行数,只关心数组的列数只有形式参数的第一维的长度可以省略,形式参数的其他维的长度都不能省略。所以本题正确答案为A。

13.在下列代码的横线处填写( ),可以使得输出是“20 10”。

图片

A. int x, int y

B. int * x, int * y

C. int a, int b

D. int & a, int & b

【答案】B

【考纲知识点】函数、指针(四级)

【解析】本题属于考察指针的基本概念; 题目要求输出20 10,也就是把a和b进行交换,参数中传递了a和b的内存地址,需要使用相应类型的指针来存放,所以本题正确答案为B。

14.执行以下C++语言程序后,输出结果是( )。

图片

A. 3

B. 30

C. 33

D.无法确定。

【答案】D

【考纲知识点】全局/局部作用域(四级)

【解析】本题属于考察变量初始化相关概念;因为sum是在函数内部定义的,所以sum的初始值并不一定是0,而是任意的一个数,也就无法确定最终的输出了,所以本题正确答案为D。

15.在下列代码的横线处填写( ),完成对有n个int类型元素的数组array由小到大排序。

图片

A. array[min] > array[j]

B. array[min] > array[i]

C. min > array[j]

D. min > array[i]

【答案】A

【考纲知识点】排序算法(四级)

【解析】本题属于考察选择排序算法;选择排序每次会从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,也就是对于所有的i+1<=j<n,找到最小的array[j],所以本题正确答案为A。

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

1.域名是由一串用点分隔的名字来标识互联网上一个计算机或计算机组的名称,CCF编程能力等级认证官方网站的域名是gesp.ccf.org.cn,其中顶级域名是gesp。

【答案】 错

【考纲知识点】计算机存储与网络(二级)

【解析】本题属于考察域名相关概念,域名是由两个或两个以上的词构成,中间用点号分隔开,最右边的那个词称为顶级域名,顶级域名是cn,所以本题错误。

2.数列1, 1, 2, 3, 5, 8 ... 是以意大利数学家列昂纳多·斐波那契命名的数列,从第三个数开始,每个数是前面两项之和。如果计算该数列的第n项(其中n>3)fib(n),我们采用如下方法:① 令 fib(1)=fib(2)=1 ②用循环for i=3 to n 分别计算f(i) ③输出fib(n)。这体现了递推的编程思想。

【答案】

【考纲知识点】递推算法(四级)

【解析】本题属于考察递推相关概念,递推是按照一定的规律来计算序列中的每个项,本题中规律是从第三个数开始,每个数是前面两项之和,且我们按照从小到大的顺序依次计算数列中的每个项,这和递归的编程思想一致,所以本题正确。

3.在C++语言中,函数的参数默认以引用传递方式进行传递。

【答案】

【考纲知识点】函数(四级)

【解析】本题属于考察函数相关概念,函数的参数默认以形式值传递参数的方式进行传递,所以本题错误。

4.在C++语言中,可以定义四维数组,但在解决实际问题时不可能用到,因为世界是三维的。

【答案】

【考纲知识点】二维及多维数组(四级)

【解析】本题属于考察数组相关概念。实际问题中, 我们是有可能使用到思四维甚至更多维数组的,所以本题错误。

5.在C++语言中,一个函数没有被调用时,它的参数不占用内存。

【答案】

【考纲知识点】函数(四级)

【解析】本题属于考察函数相关概念,。函数的参数只有在当一个函数没有被调用时才会在调用栈上分配对应内存,并在函数返回时回收,这也形成了函数参数的生命周期。因此,函数的参数在没有被调用时就不会定义相关参数,所以不会占用内存,所以本题正确。

6.在C++语言中,如果一个函数可能抛出异常,那么一定要在try子句里调用这个函数。

【答案】

【考纲知识点】异常处理(四级)

【解析】本题属于考察异常处理相关概念,即使一个函数可能抛出异常,我们也不一定要在try子句里调用这个函数。,可以进行调试查找错误可正常调用,异常会向调用更上层抛出,如上层调用在try子句中,则可以在上层捕获处理。。所以本题错误。

7.如果希望记录10个最长为99字节的字符串,可以将字符串数组定义为char s[100][10];。

【答案】

【考纲知识点】二维及多维数组(四级)

【解析】本题属于考察数组相关概念。最长为99个字节的字符串,应申请100个char的数组;,要定义10个最长为99字节的字符串,应该将字符串数组定义为char s[10][100],所以本题错误。

8.字符常量'0'和'\0'是等价的。

【答案】

【考纲知识点】字符串(三级)

【解析】本题属于考察字符串相关概念,'0'是一个字符常量,它的ASCIIascii码值为48;,而'\0'也是一个字符常量,它的ASCII码值为0,通常用来是表示字符串或字符数组的结束标志。可见,它们不等价,所以本题错误。

9. >=和>>=都是C++语言的运算符。

【答案】

【考纲知识点】基本运算(一级),位运算(三级)

【解析】本题属于考察运算符相关概念。,>=是关系比较运算符大于等于;,>>=是复合位运算符右移赋值等于运算符,a >>= b;等价于a = a >> b;。所以本题正确。

10.由于文件重定向操作,程序员在使用C++语言编写程序时无法确定通过cout输出的内容是否会被输出到屏幕上。

【答案】

【考纲知识点】文件操作(四级)

【解析】本题属于考察文件操作相关概念。, 使用文件重定向操作后,cout输出的内容可能被写入文件而不是屏幕上。,这是由程序用户决定的,编写程序的程序员无法确定,所以本题正确。

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

1.幸运数

【问题描述】

小明发明了一种“幸运数”。一个正整数,其偶数位不变(个位为第1位,十位为第2位,以此类推),奇数位做如下变换:将数字乘以7,如果不大于9则作为变换结果,否则把结果的各位数相加,如果结果不大于9则作为变换结果,否则(结果仍大于9)继续把各位数相加,直到结果不大于9,作为变换结果。变换结束后,把变换结果的各位数相加,如果得到的和是8的倍数,则称一开始的正整数为幸运数。

例如,16347:第1位为7,乘以7结果为49,大于9,各位数相加为13,仍大于9,继续各位数相加,最后结果为4;第3位为3,变换结果为3;第5位为1,变换结果为7。最后变化结果为76344,对于结果76344其各位数之和为24,是8的倍数。因此16347是幸运数。

【输入描述】

输入第一行为正整数N,表示有N个待判断的正整数。约定 1<N<20。

从第2行开始的N行,每行一个正整数,为待判断的正整数。约定这些正整数小于 10的12次方。

【输出描述】

输出N行,对应N个正整数是否为幸运数,如是则输出'T',否则输出'F'。

提示:不需要等到所有输入结束在依次输出,可以输入一个数就判断一个数并输出,再输入下一个数。

【样例输入1】

图片

【样例输出1】

图片

【题目大意】

对正整数的奇数位进行乘以7,进行若干次数位求和小于等于9之后,再与偶数位求和,判断结果是否能被8整除。

【解题思路】

1. 首先读入所有待判断的正整数,并依次进行判断,注意使用long long类型。

2. 接着通过将一个数不停整除10来得到它的每一位。

3. 对其中的奇数位按照题目的要求进行变换,偶数位则不变。奇数位的变换可以按题目文字循环处理,也可以找到等价的更简洁的表达式。

4. 累加每一位并判断总和是否能被8整除。

注意在解题过程中合理设计和调用函数,可以使得思路更清晰。

【考纲知识点】模拟法(三级),函数的定义与调用(四级)

【参考程序】

#include <iostream>

using namespace std;



// 奇数位要做的数字变换

int trans(int t) {

    if (t == 0)

        return 0;

    return (t * 7 - 1) % 9 + 1;

}

// 判断是否为幸运数

bool judge(long long x) {

    int sum = 0;

    for (int d = 1; x > 0; d++, x /= 10) {

        int t = (int)(x % 10);

        if (d % 2 == 0)

            sum += t;

        else

            sum += trans(t);

    }

    return (sum % 8 == 0);

}

int main() {

    int N = 0;

    cin >> N;

    for (int n = 0; n < N; n++) {

        long long x = 0;

        cin >> x;

        if (judge(x))

            cout << "T" << endl;

        else

            cout << "F" << endl;

    }

    return 0;

}

2.图像压缩

【问题描述】

图像是由很多的像素点组成的。如果用0表示黑,255表示白,0和255之间的值代表不同程度的灰色,则可以用一个字节表达一个像素(取值范围为十进制0-255、十六进制00-FF)。这样的像素组成的图像,称为256级灰阶的灰度图像。

现在希望将256级灰阶的灰度图像压缩为16级灰阶,即每个像素的取值范围为十进制0-15、十六进制0-F。压缩规则为:统计出每种灰阶的数量,取数量最多的前16种灰阶(如某种灰阶的数量与另外一种灰阶的数量相同,则以灰阶值从小到大为序),分别编号0-F(最多的编号为0,以此类推)。其他灰阶转换到最近的16种灰阶之一,将某个点灰阶数与16种灰阶种的一种相减,绝对值最小即为最近,如果绝对值相等,则编号较小的灰阶更近。

【输入描述】

输入第1行为一个正整数N,表示接下来有N 行数据组成一副256级灰阶的灰度图像。约定 10,<N<20。

第2行开始的N行,每行为长度相等且为偶数的字符串,每两个字符用十六进制表示一个像素。约定输入的灰度图像至少有16种灰阶。约定每行最多20个像素。

【输出描述】

第一行输出压缩选定的16种灰阶的十六进制编码,共计32个字符。

第二行开始的N行,输出压缩后的图像,每个像素一位十六进制数表示压缩后的灰阶值。

【样例输入1】

图片

【样例输出1】

图片

【样例解释1】

灰阶‘AB’、‘CF’和‘FF’出现14次,‘00’出现10次,‘CB’出现9次,‘09’出现7次,‘AC’出现6次,‘07’出现5次,‘10’、‘11’和‘98’出现4次,‘01’、‘1B’、‘67’、‘76’和‘FC’出现3次。

【题目大意】

先根据输入将输入的十六进制两两成对转换为十进制0~255之间的数,再取出现次数较多的前16个数作为标准“灰阶”,将其他的数根据与标准“灰阶”作差的绝对值大小就近转换为对应“灰阶”,最后再将灰阶转换为16进制输出。

【解题思路】

1. 模拟题,我们按照题目的要求进行模拟即可,首先将数据输入,并把16进制转换为10进制。

2. 接着我们找出出现次数最多的16种灰阶,并给它们编号为0-F。

3. 然后遍历所有的灰阶,找出距离它们各自最近的16种灰阶之一。

4. 先输出出现次数最多的16种灰阶,记得转换为16进制,再输出压缩后的图像,即所有的灰阶都输出距离它们各自最近的16种灰阶之一。

【考纲知识点】多层循环(二级),模拟法(三级),函数的定义与调用(四级)

【参考程序】

#include <iostream>

#include <cstring>

using namespace std;

int image[20][20];

int cpimg[20][20];

int his[256];

int color[16];

// 一位十六进制字符转换为数字

int trans(char a) {

    if (a <= '9')

        return (a - '0');

    return (a - 'A' + 10);

}

// 十进制数字转换为十六进制数字

char itrans(int n) {

    if (n >= 10)

        return (char)(n - 10 + 'A');

    return (char)(n + '0');

}

// 寻找离c最近的灰阶

int compress(int c) {

    int dis = 256, res = -1;

    for (int i = 0; i < 16; i++) {

        int d = c - color[i];

        if (d < 0)

            d = -d;

        if (d < dis) {

            dis = d;

            res = i;

        }

    }

    return res;

}

int main() {

    int N = 0, M = 0;

    cin >> N;

    // 灰阶计数,初始化为-1

    for (int i = 0; i < 256; i++)

        his[i] = -1;

    // 输入图像,并对灰阶计数

    for (int i = 0; i < N; i++) {

        char line[50];

        cin >> line;

        M = strlen(line) / 2;

        for (int j = 0; j < M; j++) {

            int c = trans(line[j * 2]) * 16 + trans(line[j * 2 + 1]);

            image[i][j] = c;

            his[c]++;

        }

    }

    // 选取出现次数最多的16个灰阶

    for (int c = 0; c < 16; c++) {

        int max = 0, max_id = -1;

        for (int i = 0; i < 256; i++)

            if (his[i] > max) {

                max = his[i];

                max_id = i;

            }

        color[c] = max_id;

        his[max_id] = -1;

    }

    // 将image的灰阶压缩为cpimg

    for (int i = 0; i < N; i++)

        for (int j = 0; j < M; j++)

            cpimg[i][j] = compress(image[i][j]);

    // 输出选取的16个灰阶

    for (int c = 0; c < 16; c++)

        cout << itrans(color[c] / 16) << itrans(color[c] % 16);

    cout << endl;

    // 输出压缩后的图像

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j++)

            cout << itrans(cpimg[i][j]);

        cout << endl;

    }

    return 0;

}

水平有限,以上答案仅供参考,对答案有异议,微  makytony  欢迎探讨  。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星卯教育tony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值