C++期末A卷考点全解析:从选择题陷阱到编程题满分策略

发布时间:2026/11/2 9:53:56
C++期末A卷考点全解析:从选择题陷阱到编程题满分策略

简介:这份资源是华南理工大学《C++程序设计基础》A卷期末试卷的PDF电子版,面向正在学习C++语法、准备课程考试或需要刷题巩固基础的高校学生。试卷为闭卷形式,满分100分、考试时间120分钟,共四大题,覆盖常量与变量、逻辑运算符、自增自减、条件运算符、for与while循环、switch分支、函数原型与重载、const引用、数组与指针、字符串处理及结构体等核心考点,能帮助读者检验对基础语法的掌握程度并定位薄弱环节。压缩包内仅含1个PDF文件,约288KB,即完整试卷正文,含单项选择题与程序结果分析等题型,题面清晰、可直接打印练习。目前已有116人学习浏览。借助这份真题,读者可对照题目逐项梳理易错点,如非法常量判断、短路求值、循环次数分析与指针调用方式,配合参考答案思路完成自测与查漏补缺。

1. 一张 A 卷把 C++ 基础考点全暴露了

C++ 程序设计基础这门课,期末卷面最能拉开差距的从来不是“会不会写类”,而是那些看起来不起眼、错一个就丢一分的选择题和读程序题。这份 16-17(1) 的 A 卷结构很典型:单选 20 分、读程序写结果 30 分、程序填空 30 分、编程 20 分,120 分钟闭卷。它考的不是你背了多少语法条目,而是运算符优先级、短路求值、指针与数组的等价写法、函数原型合法性这些“一考就翻车”的细节。如果你正在准备同类 C++ 基础考试,或者拿这份卷子做自测,下面按考点模块把高频题、答题思路和易错点拆开讲,照着练就能把分数抠回来。

2. 选择题高频考点:常量、运算符与表达式陷阱

选择题 20 小题每题 1 分,看似零碎,其实集中在四类:常量合法性、逻辑运算短路、自增自减与条件表达式、循环条件写法。这四类几乎每年换汤不换药,把这批题吃透,选择题基本能稳住 16 分以上。

2.1 常量与标识符:什么样的写法不合法

第 1 题问“不合法常量”,选项里0xab是十六进制整型常量,"student"是字符串常量,618E3是科学计数法浮点常量,而count是标识符不是常量。这类题的答题思路是:先判断每个选项属于哪一类字面量,再看该类字面量的书写规则。十六进制必须以0x或0X开头且后面至少一位十六进制数字;浮点科学计数法E前后必须有数字;字符串必须带双引号。面试官或出题人最想看你能否一眼区分“变量名”和“常量字面量”,因为这是后面所有表达式题的地基。

提示:遇到0x、E、引号三件套,先分类再判断,不要凭感觉。

2.2 短路求值与逻辑表达式

第 2 题int a=1,b=1; --a && --b;考的是&&的短路特性:左边--a先执行,a 变成 0,结果为假,右边--b根本不执行,所以 a=0、b=1,选 B。第 3 题“大于 2 或小于 -2”的正确写法是a>2 || a<-2,但选项里给的是!(a>=-2 && a<=2),这是德摩根律的等价变形,选 D。这类题的标准答法是:先写出自然语言对应的逻辑式,再用德摩根律或区间补集去匹配选项,不要逐项试。

// 短路求值演示:左边为假时右边不执行 int a = 1, b = 1; --a && --b; // --a 得 0,短路,--b 不执行 // 结果 a=0, b=1

代码里关键点是&&的求值顺序从左到右,一旦确定整体结果就停止。参数上注意前置--先减再用,和后置a--的时机不同,这是第 5 题条件表达式x>y? x++ : y++的坑:x=1、y=2,条件为假走y++,y 变 3,x 仍 1,x+y得 4,选 B 而不是 A。

2.3 自增自减与表达式合法性

第 4 题问“正确表达式”,++(a++)、a++++b、++a++b都不合法,因为自增运算符作用于左值,a++的结果是右值不能再自增,且++不能和+直接连写产生歧义。合法写法只能是++a + b这类。答题时记住一条:++/--的操作数必须是可修改的左值,括号包住右值再自增一律非法。这类题面试官常用来筛“是否真理解左值右值”,答的时候把“左值”两个字点出来就够。

2.4 循环条件与死循环判断

第 6 题for(i=10; i=count; i--)中间是赋值i=count而不是比较i==count,赋值表达式值为 count(非零为真),循环条件恒真但循环体里 count 递减,最终 count 变 0 时条件为假退出,所以不是无限循环,选 A 的 1 次需要结合 count 初值 1 看:第一次 i=1 为真执行,count 减到 0,第二次条件 i=0 为假退出,实际执行 1 次。第 7 题逐个看:A 的while(a){a++;}中 a 从 10 一直增大永不为 0,死循环;B 的 do-while 会正常结束;C 的for(i=0;i=3;i++)条件恒为 3 真,死循环;D 在i=i%10后if(i>10)break永远不成立但 i 会变 0 后while(1)仍真,也是死循环。正确答案是 B。这类题的血泪经验是:先找条件里的=和==混用,再看循环变量是否真的在向终止条件靠近。

3. 读程序写结果:手算执行轨迹的固定套路

第二大题 6 小题共 30 分,是整张卷子性价比最高的部分——不需要写完整程序,只要按执行顺序把变量值一步步推出来。但每年翻车最多的也是这里,因为递归、switch 穿透、指针链表这三类题一旦看错一行,后面全错。

3.1 嵌套循环与图形输出

第 1 题双层 for 打印 5×5 方框,条件i==1||i==n||j==1||j==n成立时输出a,否则输出空。手算时不要逐格画,先确定边界:第一行、最后一行、第一列、最后一列全是a,中间是空格。答案就是一个 5 行 5 列的边框。答题思路是先找“什么时候输出非空字符”,把条件翻译成“边界”,再数行列。

3.2 do-while 与 break 的配合

第 2 题i=0,j=5,do 循环里i++、j--,然后if(!(i%3)) break;。第一轮 i=1,j=4,1%3=1 不 break;第二轮 i=2,j=3,2%3=2 不 break;第三轮 i=3,j=2,3%3=0 取非为真,break。输出i=3、j=2。这类题的关键是 break 发生在自增自减之后,别提前跳。

3.3 递归函数的输出顺序

第 3 题输入stud.,函数先读字符,满足小写 a-u 就加 5,v-z 就减 21,然后递归,最后cout<<ch。因为是“先递归后输出”,输出顺序和输入相反。s加 5 得x,t加 5 得y,u加 5 得z,d加 5 得i,.不处理直接输出。逆序输出为.izyx。答题时画一个调用栈,把每层变换后的字符写在栈帧上,从栈底往栈顶读就是输出顺序。

void MysteryFun() { char ch; cin >> ch; if (ch >= 'a' && ch <= 'u') ch += 5; if (ch >= 'v' && ch <= 'z') ch -= 21; if (ch != '.') MysteryFun(); // 先递归 cout << ch; // 后输出,形成逆序 }

代码里两个 if 是并列的,不是 else if,所以一个字符最多被变换一次(加 5 后不会落入 v-z 区间再减)。参数说明:输入以.作为递归终止标记,.本身也会被输出。失败时先检查是否把两个 if 误看成互斥分支。

3.4 switch 穿透与 continue

第 4 题遍历"Hello!",case 'e'输出 e 后没有 break,会继续执行case 'i'输出 i 再 break;case 'o'输出 o 后 continue 直接进入下一轮,跳过末尾的cout<<'#'<<endl;其他字符落到 switch 外输出#换行。手算时把每个字符对应的输出列成表,特别注意continue跳过的是循环剩余部分而不是 switch。这类题的易错点是以为continue只影响 switch,实际上它作用于外层 for。

3.5 数组传参与引用返回

第 5 题fun1用指针接收数组、用double&接收平均值,循环累加后a=double(t)/size。数组{10,20,30,40}求和 100,size 为 4,av=25。输出av=25。这题考的是“数组名退化为指针”和“引用形参能带回结果”,答题时点明sizeof(ary)/sizeof(int)求元素个数这个惯用法即可。

3.6 结构体指针链表绕圈

第 6 题三个 Node 的q分别指向 a+1、a+2、a,形成环。p=a,p->s是 China,p->q->s是 France,p->q->q->s是 USA,p->q->q->q->s又回到 China。输出China France USA China。答题思路是画三个方框和箭头,按->链逐跳走,别被“环”吓到。

4. 程序填空:函数指针、随机数与结构体排序

第三大题 15 空 30 分,是整张卷子最能体现“是否真写过代码”的部分。四段程序分别考加密算法、梯形法积分配函数指针、随机数去重加素数判断、结构体数组降序排序。填空的答题套路是:先读题目描述确定功能,再顺着变量用途反推缺失语句,最后检查类型是否匹配。

4.1 数字加密:取位与逆置

加密程序要求每位数字加 7 对 10 取模后逆置。空 (1) 是把 n 备份到 k,填k=n;空 (2) 是 while 条件,只要 k 还有位就继续,填k(或k!=0);空 (3) 是去掉已处理的最低位,填k/=10。这类题的关键是分清n是原始输入、k是工作变量、m是结果累加器。常见错误是把 (3) 写成k%=10,那样 k 永远不变,循环死掉。

4.2 梯形法积分与函数指针形参

空 (4) 需要包含数学函数sqrt、sin,填#include<cmath>;空 (5) 是trap的第一个形参,接收函数指针,填double (*fun)(double);空 (6) 是累加中间点函数值,填t += (*fun)(a + i*h);空 (7) 是第三次调用,填t3 = trap(f3, 0, 3.14159, 10000)(对应 sin 在 0 到 π 的积分)。函数指针的写法是这类题的固定考点:返回类型(*名字)(参数类型列表),调用时(*fun)(x)或fun(x)都行。

double trap(double (*fun)(double), double a, double b, long n) { double t, h; int i; t = ((*fun)(a) + (*fun)(b)) / 2.0; // 两端点 h = (b - a) / n; for (i = 1; i <= n - 1; i++) t += (*fun)(a + i * h); // 累加内部节点 t *= h; return t; }

参数说明:fun是函数指针,a、b是积分上下限,n是等分数。逻辑是先算梯形两端点平均,再累加所有内部点,最后乘步长 h。失败时先看h是否在循环前算好,以及t是否在循环后才乘 h。

4.3 随机数去重与素数输出

空 (8) 是检查 num 是否已出现,填p[i]==num;空 (9) 是素数判断中能被整除就跳出,填p[i]%j==0;空 (10) 是产生互不相同随机数,填check(a,i,x);空 (11) 是调用输出素数函数,填print(a,10)。这题把“数组查重”和“试除法判素数”两个基础算法缝在一起,答题时先确认每个函数的职责边界:check 只查重、print 只输出素数、main 负责生成。

4.4 结构体数组按薪水降序排序

空 (12) 是动态分配职工数组,填p = new Employee[total];空 (13) 是输出排序结果,填Output(p, total);空 (14) 是选择排序找最大值的比较,填all[j].salary > all[t].salary;空 (15) 是发现更大值就交换下标,填t != i。选择排序的骨架是外层定位置、内层找极值、最后交换,填空时盯住t的角色——它存的是当前最大值的下标,不是值本身。

注意:new出来的数组记得配对delete[],虽然这份卷子没考,但面试追问内存管理时这是送分点。

5. 编程题与易错点:两道 10 分题怎么拿满

第四大题两道编程各 10 分,一道结构体数组找最低分,一道动态数组逆置。题目已经给了 main 和部分函数声明,实际只需补函数定义,所以评分点集中在“函数签名对不对、循环边界对不对、指针用法对不对”。

5.1 结构体数组找最低分

searchMin(data*, int, data&)的第三个参数是引用,用来把结果带回 main。实现时先假设第一个元素最小,再遍历比较,遇到更小就整体赋值。注意data结构体里有char name[12],赋值时用结构体整体赋值即可,不要手动逐字符拷贝。

void searchMin(data *stu, int n, data &min) { min = stu[0]; // 假设第一个最小 for (int i = 1; i < n; i++) if (stu[i].score < min.score) min = stu[i]; // 结构体整体赋值 }

参数说明:stu是结构体数组首地址,n是元素个数,min是引用形参用于返回。逻辑上从下标 1 开始比较,避免自己和自己比。常见错误是把min写成值传递,结果 main 里拿不到最低分。

5.2 动态数组逆置

adverse(int *p, int n)用双指针从两端向中间交换,循环条件i < n/2。注意new int[n]之后要delete[] p,虽然题目 main 里没写,但完整程序应补上。

void adverse(int *p, int n) { for (int i = 0; i < n / 2; i++) { int t = p[i]; p[i] = p[n - 1 - i]; p[n - 1 - i] = t; } }

参数说明:p指向动态数组首元素,n是长度。循环只走到一半,否则交换两次等于没换。失败时检查n/2是否写成了n,以及下标n-1-i是否越界。

5.3 易错点:五个反复失分的地方

错在哪:把for(i=10; i=count; i--)当成比较。为什么错:=是赋值不是判断,条件值取决于 count 而非 i 与 count 的关系。怎么答对:先圈出条件里的单个等号,改写成i==count再判断原意。

错在哪:--a && --b认为两边都执行。为什么错:忽略&&短路,左边为假右边不跑。怎么答对:先算左边布尔值,为假直接停。

错在哪:递归题按输入顺序输出。为什么错:cout在递归调用之后,输出天然逆序。怎么答对:画调用栈,从最深层往外读。

错在哪:函数指针形参写成double *fun(double)。为什么错:那是返回指针的函数声明,不是函数指针。怎么答对:记住(*fun)的括号不能省。

错在哪:结构体排序比较时交换了值却没更新下标。为什么错:选择排序靠下标t定位极值,直接交换值会打乱后续比较。怎么答对:内层只更新t,外层结束再交换。

6. 考场时间分配与押题思路

120 分钟四大题,合理节奏是单选 20 分钟、读程序 30 分钟、填空 35 分钟、编程 25 分钟,留 10 分钟回查。单选遇到短路和自增题不要恋战,先标记跳过,因为后面读程序的分值更高。读程序题一律在草稿纸上画变量表,每执行一行更新一次,递归题画栈、指针题画箭头,这比心算靠谱得多。填空题先通读整段程序确定功能,再逐空填,填完把值代回去跑一遍边界。编程题先写函数签名再写循环,签名错等于零分。

押题方向上,这份卷子暴露的高频模块很稳定:运算符优先级与短路、循环条件写法、函数原型与默认参数、const 引用传参、数组指针等价、结构体指针、函数指针、动态内存。复习时不要平均用力,把“指针与数组的四种等价写法”和“函数指针声明”这两块练到能默写,基本覆盖 60% 的易错分。面试追问常落在const int&为什么能接常量、new/delete与malloc/free的区别、结构体传参值传递和引用传递的差别,提前准备三句话答案即可。

我当年第一次做这类卷子,读程序题全靠心算,结果 switch 穿透那题漏了一个#,整题 5 分全丢。从那以后我每次做读程序题都强制在草稿纸上画变量表,一行一行更新,再简单的题也不省这一步。希望帮到你。

本文还有配套的精品资源,点击获取