简介:2024年3月GESP C++一级真题(docx版)是一份面向GESP一级考生的完整备考复习资料,适用于刚接触C++语言的初学者,也适合需要检验基础、熟悉考试题型的学习者。真题由15道选择题、10道判断题和2道编程大题组成,编程题为“小杨买书”和“找因数”,覆盖表达式求值与优先级、运算符结合性、cin/cout标准输入输出、if/else条件分支、for循环、while循环、数组累加、显式类型转换、质数判断等核心考点,并在每道题后给出简要解析,便于对照思考。编程大题部分还给出了输入输出格式说明,有助于考生规范作答。选题中还包括‘能否被3和7整除’等分支输出逻辑,以及循环边界、步长变化等易错易混点,能帮助考生快速查漏补缺。文档还整理了Dev C++编译可执行程序的流程、鸿蒙操作系统基础常识、王选汉字激光照排系统等计算机内容,有助于补齐非编程知识盲区。整份资源只有1个docx文件,压缩包大小约133KB,内容精炼,方便打印或导入手机随时刷题。目前已有1536人学习下载,对备考GESP C++一级、进行考前查漏补缺具有很高的参考价值。
1. GESP C++ 一级真题:把“入门语法”考成了一面照妖镜
2024 年 3 月的 GESP C++ 一级真题,是我见过最典型的“看着不难、写时翻车”的一套卷子。它不考高难度算法,就围绕表达式求值、cin/cout、printf/scanf、if/for/while、整除与取余这些入门知识点来回考,15 道选择、10 道判断,加上 2 道编程题,表面上是给刚学完 C++ 的初学者准备的摸底测试。可真正上手拆题会发现,每道题都在验证你的代码习惯:输出格式对不对、循环边界准不准、类型差异清不清楚。适合刚学完一轮语法、想靠真题检查漏洞的人,也适合准备信奥赛入门场、想控制低级失误的老手。我拆完这套题最直观的感受是:它不是在难倒你,而是在提醒你哪些习惯会在考场上拖后腿。
2. 选择与判断里的语法考点:表达式、输入输出与控制流
2.1 表达式求值与运算符优先级:先括号,再乘除,后加减
第 1 题(3 - 2) * 3 + 5的答案是 8。这个没什么好争论的,但值得展开的是它背后的优先级链:括号优先级最高,所以先算出 1;然后*和+混合时,*优先级高于+,于是1 * 3 = 3,最后3 + 5 = 8。如果去掉括号,3 - 2 * 3 + 5就完全不同:2 * 3先算,得到3 - 6 + 5 = 2。GESP 一级很喜欢拿这种“差一个括号就差一个答案”的题做基础辨析。
#include <iostream> using namespace std; int main() { int a = (3 - 2) * 3 + 5; // 括号优先,乘除优先于加减 int b = 3 - 2 * 3 + 5; // 没有括号时,乘法先算 cout << a << " " << b << endl; // 输出 8 2 return 0; }这段代码把两种写法的结果同时输出,方便对比。a对应真题答案 8,b是去掉括号后的 2。做这类题时拿不准优先级就加括号,考试时括号合法而且免费。取模运算%在 C++ 里的优先级和*、/同级,所以5 % 2会和乘法一样优先于加减计算。
第 2 题cout << "5%2=" << 5 % 2,关键在区分两个%:一个在双引号里,是字符串内容,原样输出“5%2=”;另一个在表达式里,才是取模运算符,5 % 2 = 1,整体输出是5%2=1。不少初学者选错,是把字符串里的%和运算符%混在一起。对这种题,我一般先圈出双引号范围,把字符串部分单独看待,再去算表达式值,最后看拼接结果。
2.2 cin 输入行为:读的是“格式化数据”而不是“整行文字”
第 3 题问cin >> a时输入5+2会怎样。正确答案是:依赖于变量 a 的类型;如果 a 没定义,会编译错误。很多人以为 cin 会把整段文字读进去并解析出 7,实际上 cin 按变量类型去匹配输入:如果 a 是 int,它只读取第一个合法整数 5,遇到+就停下来,剩下的+2留在缓冲区里,不会自动把5+2求值成 7。
#include <iostream> using namespace std; int main() { int a; // 先定义变量 cin >> a; // 输入 5+2 时,a 只会拿到 5 cout << a << endl; // 输出 5 return 0; }这里有个长期有效的好习惯:用cin之前先看变量有没有定义。真题第 3 题专门用“如果没有定义,会有编译错误”做干扰项,就是在提醒“变量必须先声明再使用”是 C++ 最基本规则。另外,变量是 int 时,不能指望 cin 帮我们做表达式求值,它是按类型读取,不是按数学公式读取。想读5+2并算出 7,要先读字符串再解析,这不是一级考点。还有一点值得注意:真题选项里出现了类似input()的描述,那是把 Python 的输入习惯混进 C++ 里干扰思路,看到要直接排除。
2.3 控制流里的隐藏考点:else if 的执行顺序与循环次数
第 6 题是分支结构里特别典型的“只看第一个命中”的题。N 输入 21,先判断N % 3 == 0,21 能被 3 整除,条件成立,直接输出“能被3整除”,后面的else if (N % 7 == 0)和else都不再执行。这个执行路径是 if-else if-else 结构默认的:从上往下找第一个条件为真的分支,找到一个就结束判断。
#include <iostream> using namespace std; int main() { int N; cin >> N; if (N % 3 == 0) cout << "能被3整除 "; else if (N % 7 == 0) cout << "能被7整除 "; else cout << "不能被3和7整除 "; cout << endl; return 0; }参数说明:N % 3 == 0是整除判断,等于 0 表示余数为 0。如果把两个判断条件对调,结果会完全不同。21 同时满足两个条件,但第一个命中后就不再往下走,可见顺序在这个结构里很重要。实际排错时如果发现走错了分支,第一反应不是看输出函数,而是看前面几个条件是不是把路“截胡”了。
第 7 题for(int i=-10; i<10; i++)总共执行 20 次。不能拿 10 减负 10 就完事,要数生成的整数序列:-10、-9、……、9,一共 20 个数。我做这类题第一反应是先写出首项和末项,再算9 - (-10) + 1 = 20。
第 8 题考if(i%3 && i%7)的布尔语义。i%3当 i 能被 3 整除时是 0,0 在条件里表示假;i%7同理。整个&&要求两边都是真,也就是 i 既不能被 3 整除,也不能被 7 整除。0 到 9 里满足的是 1、2、4、5、8,求和是 20。注意 i 从 0 开始,0 % 3和0 % 7都为 0,条件为假,所以 0 不参与求和。这个细节很容易漏。
#include <iostream> using namespace std; int main() { int tnt = 0; for (int i = 0; i < 10; i++) if (i % 3 && i % 7) // 既不能被3整除,也不能被7整除 tnt += i; cout << tnt << endl; // 输出 20 return 0; }第 10 题的质数判断填空要填N % i == 0。因为计数逻辑是“记录 N 被整除的次数”,只有余数为 0 才能算一次整除。填N % i的话,i 等于 1 时余数为 0,后续大量非整除情况会被误计入,逻辑直接崩。这类填空只要理解“%的结果是余数,余数 0 才代表整除”,基本就是送分。除了这些,还有几道不写代码也能做的常识题,比如某国产智能手表上运行的“鸿蒙”属于操作系统,以及汉字激光照排系统相关的计算机人物贡献题。这类题和 C++ 语法无关,但等级考试里会作为计算机素养出现,平时有点积累就能稳住分数。
3. 编程题实战:买书与找因数的标准实现
3.1 小杨买书:一次除法配一次取余
题面:书本单价 13 元,输入零用钱金额 N,输出两行,第一行购买本数,第二行剩余零用钱。这是典型的“除法得数量、取余得余额”组合。买几本用整除:books = N / 13;剩多少钱用取余:rest = N % 13。
#include <iostream> using namespace std; int main() { int N; // 零用钱 cin >> N; int books = N / 13; // 最多购买书本数 int rest = N % 13; // 剩余零用钱 cout << books << endl; cout << rest << endl; return 0; }逻辑说明:第一步读入 N,第二步分别计算整除和取余,第三步按题面要求输出两行。注意输出不能用任何提示文字,直接输出数字。受限于一级考察范围,N 是普通整数,不会超 int。照题面样例验证:输入 13 输出1和0;输入 14 输出1和1;输入 26 输出2和0。如果写成浮点数计算再转换,反而容易引入精度问题,一级编程题尽量用整数运算。
参数与边界:当 N 小于 13 时,books = 0,rest = N,程序要能正常输出,不用额外加特判。很多初学者在这里会写if (N < 13)单独处理,其实没必要,整除和取余天然覆盖这个情况,多加分支反而增大出错面。另一个容易翻车的地方是忘记换行,题目要求两行输出,endl就是为这个准备的。
3.2 找因数:从 1 到 N 的穷举输出
题面:输入一个正整数 N,从小到大输出 N 的所有因数,每行一个。一级不要求优化到根号级别,最稳的做法是从 1 枚举到 N,逐个判断N % i == 0。
#include <iostream> using namespace std; int main() { int N; cin >> N; for (int i = 1; i <= N; i++) { if (N % i == 0) { // 余数为0说明i能整除N cout << i << endl; } } return 0; }逻辑说明:循环变量 i 从 1 开始,到 N 结束,全部尝试一遍。N % i == 0成立就输出 i,这样天然保证从小到大的顺序。题面给的数据范围到 1991 左右,循环两千次左右在判题环境里没有任何压力。如果 N 很大,可以优化到只枚举到 sqrt(N) 再补因数,但一级题不要求,写复杂反而容易出错。这类题最常见的错误是输出顺序不对,或者漏掉 N 本身,根因是把循环结束条件写成i < N而不是i <= N。
真题同时强调“常规程序中输入输出提供提示是好习惯,但本场考试由于系统限定,请不要在输入输出中附带任何提示信息”。因此cin前不能写类似“请输入”的 cout 输出。上一题的买书也一样。考级编程题的输出是判题的唯一依据,多余字符全按错处理。我见过不少本地运行正常、提交零分的情况,追查到最后就是多了一行提示文字。
3.3 样例驱动的验证顺序
两道题写完,先别急着交,按“题面样例 → 边界值 → 特殊值”的顺序验证。题面样例验证常规路径;边界值验证整除和取余的极端情况,比如买书输入 1、13、14;特殊值验证因数题的 1 和质数,输入 1 时只有 1 一个因数,输入 7 时输出 1 和 7。样例对了不能说明代码没问题,边界值才是真正抓 bug 的地方。调试时我习惯拿一张纸把输入输出对照写好,再逐行看代码是不是真的按这个逻辑走。
4. 从源码到可执行程序:编译、运行与调试的最小闭环
4.1 编译不是“保存一下”,而是生成可执行文件的一步
真题第 13 题问在 Dev C++ 中对写好的 C++ 源文件要生成可执行程序需要执行哪个处理步骤,答案是编译。初学阶段,很多人把“写完代码 → 点运行 → 看到输出”当成一个整体,没意识到中间隔着编译这一步。编译器把 C++ 源文件翻译成机器指令,链接器再把它拼成可执行程序。
g++ main.cpp -o main.exe ./main.exe参数说明:main.cpp是源文件;-o main.exe指定输出文件名;如果不写-o,Windows 平台默认生成a.exe,Linux 平台默认生成a.out。然后用./main.exe运行。熟悉命令行编译有个好处:报错信息里会出现文件行号和错误类型,比 IDE 里点按钮更直观。比如类型错误、变量未定义、函数名拼错,都能在报错里看到。
实际常见场景是:在 Dev C++ 里按 F11 一键编译运行,它背后做的就是上面两行命令的图形化封装。编译失败时,错误出现在下方消息区,双击错误信息可以跳到对应行,这是调试入口,不是重新开始写代码的信号。很多新手编译报错后第一反应是重写整份代码,其实多数编译错误只是拼写或类型问题,定位一行改一行就行。Edit 是编辑,Create 是新建文件,Debug 是调试,只有编译负责把源文件变成可执行程序,这四个词在一级选择里是老熟脸。
4.2 预处理、编译、链接:哪一步报错决定你怎么查
严格说,从源文件到可执行程序要经过预处理、编译、汇编、链接。一级考试不会考到这么深,但理解“哪一步报错”能帮你快速定位问题。变量未定义、语法写错,通常在编译阶段报;函数找不到实现、多文件拼接时符号冲突,通常在链接阶段报。GESP 考场常用 Dev C++ 这类集成环境,它把预处理、编译、汇编、链接全部封装在“编译运行”按钮里,所以报错信息层级不会分得太清楚,但核心思想不变。
#include <iostream> using namespace std; int main() { int a = 1; printf("a+1=%d\n", a + 1); // printf 用 %d 占位输出整数 cout << "a+1= " << a + 1 << endl; // cout 自动按类型输出,注意字符串里的空格 return 0; }这段代码同时演示 printf 和 cout 两种输出方式。真题里分别用它们输出a+1,区别集中在格式控制:printf 用%d占位符,cout 自动按类型输出。a+1的结果是整数 2,所以正确答案要看字符串里等号后有没有空格:"a+1= "后面带一个空格,输出是a+1= 2;"a+1="后面没有空格,输出是a+1=2。这个空格差异是 GESP 一级反复出现的易错点,它不考算法,考的是眼睛够不够细。这类空格问题在程序里极难用肉眼在终端里发现,但判题系统会严格区分。平时练习可以把输出重定向到文件,再用编辑器打开看行尾和空格。
5. 避坑与常见问题:GESP 一级里最容易错的五个点
5.1 scanf 参数的本质被误判
现象:判断题“scanf() 必须含有参数,且其参数为字符串型字面量,其功能是提示输入”被判对,实际答案是错。原因:scanf 的参数由格式字符串和变量地址组成,格式字符串确实是字符串字面量,但它不是“提示输入”,而是告诉程序按什么格式解析输入。解决:把这句记成“格式串 + 地址列表”,地址列表靠&取地址,比如scanf("%d", &a)。如果只看第一个参数,以为 scanf 只能有一个参数,后面学多变量输入还会再栽跟头。
5.2 字符串和整数不能直接相乘
现象:判断题“C++ 表达式"10"*2执行时将报错,因为"10"是字符串类型而 2 是整数类型,数据类型不同,不能在一起运算”有人判错。原因:"10"是字符串字面量,C++ 语法层面没有定义字符串与整数的乘法,所以编译阶段早早就报错,不会等到运行。解决:字符串数字想参与运算,先转成整数,比如stoi("10") * 2,或者直接写10 * 2。这提醒表达式运算的操作数类型要匹配。
5.3 死循环不只是 while 的专利
现象:判断“while 可能是死循环,而 for 循环不可能是死循环”被判对。原因:for 的三个表达式都可以省略,for(;;)没有任何终止条件,同样是死循环。while 只有条件判断,更新变量的语句要写在循环体里;for 把初始化、条件、更新集中在头部,看起来更容易终止,但语法上完全允许写空条件。解决:判断会不会死循环,不要看循环是 for 还是 while,而是看退出条件有没有可能在某一刻成立。while(true)和for(;;)殊途同归。
5.4 3.0 和 3 类型不同,存储空间不同
现象:判断“3.0 和 3 的值相等,所以占用存储空间也相同”有人判对。原因:3.0 是浮点类型 double,3 是整数类型 int,在常见编译器里 double 占 8 字节,int 占 4 字节,值相等不等于类型相同。解决:任何语言里都要先确认变量类型再谈存储。这个坑到二级还会延伸出浮点数精度问题,一级先把“字面量的类型由写法决定”记住:有小数点是浮点,没小数点是整数。
5.5 编程题输出多一个空格就被判错
现象:买书或找因数的代码在本地跑得很正常,提交后判分却是 0 分。原因:判题按输出逐字符匹配,多一个空格、少一个换行、多一句“请输入”,都会导致结果不匹配。解决:把题面给的输入样例复制到程序里,再把输出和标准输出逐字符对比。我一般会写一行临时对比逻辑,或者用文本编辑器查看行尾差异。检查顺序固定为:行数对不对、每行内容对不对、行尾有没有多余空格、最后一行有没有换行。
6. 用真题做自测:建立你自己的易错点检查清单
6.1 把错题反向整理成检查清单
不要满足于“知道答案”,要把错题的原因反向记到清单里。比如你错在输出空格,就在清单第一行写“所有输出先看题面,等号后有没有空格”;错在循环次数,就写“先列首项和末项,再加一”。每次做题前把清单扫一遍,会明显降低低级失误。这个清单不用很长,五到八条足够,关键是每条都要对应一个真实错因。我见过太多人反复做同一套题、反复错同一个点,就是因为没有把错因抽象成一句话。
6.2 用边界输入验证编程题
准备一个小表格,对应两道编程题分别输入边界值验证输出。买书题输入 0、1、13、26;找因数题输入 1、2、3、16、17。这样能同时覆盖“不够买”“恰好一本”“质数”“合数”四类情况。
| 场景 | 输入 | 预期输出 |
|---|---|---|
| 买书-不足一本 | 5 | 第一行 0,第二行 5 |
| 买书-恰好一本 | 13 | 第一行 1,第二行 0 |
| 买书-超过一本 | 26 | 第一行 2,第二行 0 |
| 找因数-最小正整数 | 1 | 1 |
| 找因数-质数 | 7 | 1 和 7,各占一行 |
| 找因数-合数 | 12 | 1、2、3、4、6、12,各占一行 |
从那以后,我每次做考级真题都会强制自己先写一张“输出了几行、有没有多余空格、换行符在哪”的检查单,再把代码跑起来对照。看似麻烦,实际上省下了大量调格式的时间。希望帮到你。
本文还有配套的精品资源,点击获取