CCF-GESP 2026年3月认证 C++ 三级真题解析
GESP(编程能力等级考试)是由中国计算机学会(CCF)主办的青少年编程能力认证项目。本文为2026年3月C++三级考试的完整真题及逐题详细解析,涵盖15道单选题、10道判断题和2道编程题,满分100分。三级核心考点包括位运算、补码表示、数组操作、进制转换、枚举与凯撒密码。
获取 202603gesp3级完整真题及详细解析.pdf
请关注状元编程公众号,回复 202603gesp3
一、单选题(每题2分,共30分)
第1题
题目: 关于字符 '1' 的ASCII值,以下说法正确的是?
答案:C
解析: 字符 '1' 的ASCII值是49,不是1。可以通过 (int)'1' 验证。
#include<iostream>usingnamespace std;intmain(){char _1='1'; cout<<(int)_1; // 输出49}⚠️ 易错点: 字符
'1'和数字1是不同的,字符'1'的ASCII码为49,而数字1的值就是1。
第2题
题目: 以下哪种方式可以实现两个变量交换且不使用临时变量?
答案:B
解析: 使用异或位运算实现交换,这是经典的面试题技巧:
a = a ^ b;b = a ^ b; // 此时 b = 原aa = a ^ b; // 此时 a = 原b异或运算的性质:a ^ a = 0,a ^ 0 = a,利用这个性质可以在不借助临时变量的情况下完成交换。
第3题
题目: 以下两种字符数组定义的区别是什么?
char str1[] = "Hello"; // 方式一char str2[] = {'H','e','l','l','o'}; // 方式二答案:C
解析:str1 使用字符串字面量初始化,结尾会自动添加 '\0'(空字符),而 str2 使用逐个字符初始化,结尾没有 '\0'。
cout << "str1的长度: " << sizeof(str1) << endl; // 输出6(含'\0')cout << "str2的长度: " << sizeof(str2) << endl; // 输出5(不含'\0')cout << (int)str1[5] << endl; // 输出0('\0'的ASCII值)cout << (int)str2[4] << endl; // 输出111('o'的ASCII值)⚠️
str2缺少'\0'终止符,使用cout << str2输出时会越界访问内存,产生乱码。
第4题
题目:cout << (x++ + ++x) (x初始为10)的输出是?
答案:B
解析:
x++是后置递增,先使用x的当前值10,然后x变为11++x是前置递增,先将x从11递增到12,再使用值12所以结果为 10 + 12 = 22
⚠️ 注意: 这种写法在不同编译器中行为可能不同(未定义行为),仅用于考试分析。
第5题
题目: -15的8位补码表示是?
答案:D
解析: 负数补码的推导过程:
-15:原码:1000 1111 符号位为1,其余位为15的二进制反码:1111 0000 除符号位外,全部取反补码:1111 0001 在反码基础上+1💡 记忆口诀: 原码 → 反码(符号位不变,其余取反) → 补码(反码+1)
第6题
题目: 三进制数 2102 转换为十进制是多少?
答案:B(65)
解析: 按权重相乘求和:
2×3³ + 1×3² + 0×3¹ + 2×3⁰= 2×27 + 1×9 + 0×3 + 2×1= 54 + 9 + 0 + 2= 65第7题
题目: 补码 1011 0101 对应的十进制数是多少?
答案:B(-75)
解析: 补码转原码的逆过程:
补码:1011 0101反码:1011 0100 补码-1原码:1100 1011 反码除符号位取反十进制:-(64+8+2+1) = -75第8题
题目:15 << 3 的结果是?
答案:D(120)
解析: 左移运算,低位补0:
0000 1111 << 3 结果为:0111 1000转十进制:64 + 32 + 8 + 4 = 120💡 左移n位等价于乘以2ⁿ,
15 × 2³ = 15 × 8 = 120。
第9题
题目: 以下关于按位取反 ~ 的说法,正确的是?
答案:B
解析: 逐项验证:
~5 == -6 | ~5-6 的补码一致 | ||
~0 == 0 | ~00xFFFFFFFF = 2³¹-1,不是0 | ||
~(-3) == 2 | -30000...0010 = 2 | ||
~8 == -9 | ~8-9 的补码一致 |
💡 规律:
~x = -(x+1),即取反等于加1后取负。
第10题
题目: 关于进制转换,以下正确的是?
答案:A
解析: 进制转换中,A选项的枚举范围最小、枚举对象最少,是最优选择。
第11题
题目:sizeof(arr) / sizeof(arr[0]) 的结果是多少?(arr为含6个int的数组)
答案:B(6)
解析:
sizeof(arr) : 6个int × 4字节 = 24sizeof(arr[0]) : 1个int = 4字节结果 = 24 / 4 = 6💡 这是计算数组长度的经典公式:
数组总字节数 / 单个元素字节数 = 元素个数
第12题
题目:char s[10] = "Hello"; 中 sizeof(s) - strlen(s) 的值是?
答案:B(5)
解析:
sizeof(s) : 数组所占内存 = 10 × 1 = 10strlen(s) : 字符串长度 = 5(不含'\0')a - b = 10 - 5 = 5⚠️ sizeof vs strlen:
sizeof返回数组总大小(含'\0'),strlen返回字符串长度(不含'\0')。
第13题
题目: 某枚举程序的问题在于?
答案:C
解析: 缺少了枚举条件,导致枚举范围过大或逻辑不完整。
第14题
题目: 优化枚举效率的关键是?
答案:A
解析: 枚举范围少、枚举对象少是提高效率的关键。缩小搜索空间可以大幅减少计算量。
第15题
题目: 凯撒密码加密中,字母向后偏移3位,超过'z'时如何处理?
答案:D
解析: 超过'z'时需要回绕到'a'重新开始:
if (str[i] + 3 > 'z') { str[i] = 'a' + (str[i] + 3 - 'z') - 1; // 从a开始算}例如:'x' → 'a','y' → 'b','z' → 'c'。
二、判断题(每题2分,共20分)
第1题
题目:int arr[5] = {1,2,3}; 则 arr[3] 和 arr[5] 的值都是0。
答案:错误(×)
解析:arr[3] 结果为0(部分初始化时,未初始化的元素自动置0),但 arr[5]越界访问,行为未定义,不是0。
第2题
题目: 局部数组 int arr[10]; 未初始化时,所有元素默认值为0。
答案:错误(×)
解析: 局部变量未初始化时,默认值是随机数(内存中的垃圾值)。只有全局变量和静态变量才会自动初始化为0。
第3题
题目:int arr[3]; 占用12个字节的内存。
答案:正确(√)
解析: 数组存放3个int,每个int占4个字节,3 × 4 = 12 字节。
第4题
题目: 以下代码计算 1+2+...+10 的和。
答案:正确(√)
解析: 循环从1到10累加,结果为55。
第5题
题目: 通过不断减2可以求余数。
答案:正确(√)
解析: 不断用被除数减去除数,直到不够减为止,剩余的值就是余数。例如 7 % 3:7-3=4,4-3=1,1 < 3,余数为1。
第6题
题目:'A' 的ASCII值转十六进制为 0x41,'m' 的ASCII值转八进制为 0155。
答案:正确(√)
解析:
'A' 的ASCII值:65 → 十六进制 0x41'm' 的ASCII值:109 → 八进制 0155第7题
题目: 宏定义可以实现长方形周长计算 (a+b)*2。
答案:正确(√)
解析: 使用带参数的宏定义:
#define PERIMETER(a, b) ((a) + (b)) * 2第8题
题目: 字符 '1' 的ASCII值等于数字 1。
答案:错误(×)
解析: 字符 '1' 的ASCII值是49,数字 1 的值是1,两者不相等。
第9题
题目:0xf0 + 0x15 = 0x105 是错误的。
答案:错误(×)
解析:0xf0 = 240,0x15 = 21,240 + 21 = 261 = 0x105。计算是正确的,题目说"错误"本身是错误的。
⚠️ 十六进制加法:
0xf0 + 0x15 = 0x105,注意进位。
第10题
题目: 偶数与3和1做按位与运算,结果为0。
答案:正确(√)
解析: 偶数的最低位为0:
a: ??????0 (偶数最低位为0)3: 00000111: 0000001a & 3 & 1: ??????0 0000011& 0000001---------- 0000000 结果为0💡 规律: 偶数
& 1恒为0,奇数& 1恒为1,这是判断奇偶的经典方法。
三、编程题(每题25分,共50分)
编程题1:二进制回文串
题目描述:
对于一个正整数 n,将其转换为不含前导零的二进制表示,如果这个二进制序列从左向右读与从右向左读完全相同,则称该数为二进制回文数。例如,9 的二进制表示为 (1001)₂,是二进制回文数;12 的二进制表示为 (1100)₂,不是二进制回文数。
任务: 给定正整数 n,计算 1 到 n 范围内二进制回文数的数量。
输入格式: 一行,包含一个正整数 n
输出格式: 一行,包含一个数,表示二进制回文数的数量
样例:
15 | 6 |
数据范围: 1 ≤ n ≤ 10⁵
解题思路:
遍历1到n的每个数 将每个数转换为二进制字符串 反转字符串,判断是否与原字符串相同 统计回文数个数
参考代码:
#include<bits/stdc++.h>usingnamespace std;intmain(){int n; cin >> n;int ans = 0;for(int i = 1; i <= n; i++){// 转为二进制字符串int copy = i; string binary = "";while(copy != 0){char temp = copy % 2 + '0'; binary = temp + binary; // 反向拼接 copy /= 2; }// 判断是否为回文 string r_binary = "";int len = binary.size();for(int j = len - 1; j >= 0; j--) r_binary += binary[j];if(r_binary == binary) ans++; } cout << ans;return0;}编程题2:凯撒密码
题目描述:
凯撒密码是一种替换加密技术,明文中的所有字母在字母表上按照固定数目偏移后被替换成密文。例如偏移量为3时,A→D,B→E,...,W→Z,X→A,Y→B,Z→C。
任务: 给定已破解的明文与密文(用于确定偏移量),以及待破解的密文,输出对应的明文。
输入格式: 三行,分别为明文、密文、待破解密文
输出格式: 一行,待破解密文对应的明文
样例:
ABCDEFGVWXYZ | THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG |
DEFGHIJYZABC | |
WKHTXLFNEURZQIRAMXPSVRYHUWKHODCBGRJ |
样例解释: 通过已破解的密码得出偏移量为 'D' - 'A' = 3,对密文逆向偏移3位即可得到明文。
数据范围: 密码长度不超过1000,所有字符串由大写字母组成
解题思路:
通过明文和密文的第一个字符计算偏移量 对待破解密文的每个字符进行逆向偏移 处理回绕情况(偏移后超过'A'时回绕到'Z')
参考代码:
#include<bits/stdc++.h>usingnamespace std;intmain(){ string s1, s2, s3; cin >> s1 >> s2 >> s3;// 计算偏移量(密文-明文)int move = s1[0] - s2[0];// 构建三倍字母表避免越界 string ans = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";// 逐字符解密int len = s3.size();for(int i = 0; i <= len - 1; i++){ cout << ans[s3[i] - 'A' + 26 + move]; }return0;}💡 技巧: 使用三倍字母表(78个字符)可以避免手动处理回绕,通过索引偏移直接获取正确字符。
📊 考点分布分析
| 位运算(补码、取反、左移、异或) | |||
| 进制转换(二进制、三进制、十六进制) | |||
| 数组(sizeof、strlen、初始化) | |||
| 字符与ASCII码 | |||
| 字符数组与字符串'\0' | |||
| 前置/后置递增 | |||
| 枚举优化 | |||
| 凯撒密码加密 | |||
| 编程题(二进制回文+凯撒密码解密) |
💡 备考建议
位运算是三级核心:本套试卷位运算相关题目占5道,务必熟练掌握原码/反码/补码转换、按位取反
~、左移<<、异或^的运算规则。掌握补码转换三部曲:原码 → 反码(符号位不变取反) → 补码(反码+1)。逆向转换:补码 → 反码(补码-1) → 原码(反码符号位不变取反)。
记住取反公式:
~x = -(x+1),例如~5 = -6,~0 = -1,~8 = -9,这是快速判断的利器。sizeof vs strlen 要分清:
sizeof是运算符,返回数组总大小(含'\0');strlen是函数,返回字符串长度(不含'\0')。字符数组初始化注意'\0':字符串字面量
"Hello"自动添加'\0',逐字符初始化{'H','e','l','l','o'}不会添加。进制转换要熟练:任意进制转十进制用按权展开法,十进制转任意进制用除基取余法。十六进制加法注意进位。
编程题注重字符串处理:二进制回文需要掌握数制转换+字符串反转,凯撒密码需要掌握字符偏移+回绕处理。使用三倍字母表技巧可以简化回绕逻辑。