ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

C++期末A卷考点拆解:读程序占60分,掌握6类陷阱与5大易错点

C++期末A卷考点拆解:读程序占60分,掌握6类陷阱与5大易错点

简介:这份资源是华南理工大学《C++程序设计基础》A卷期末试卷的PDF电子版,面向正在学习C++语法、准备课程考试或需要刷题巩固基础的高校学生。试卷为闭卷形式,满分100分、考试时间120分钟,共四大题,覆盖常量与变量、逻辑与自增运算符、条件与循环控制、switch语句、函数原型与重载、const引用、数组与指针、字符串及结构体等核心考点,并附有逐题知识点解析,便于对照理解易错点。包内共1个PDF文件,约288KB,内容为完整试卷与答案解析,可直接打印或在线查阅。目前已有116人学习下载。读者可借助这份真题熟悉考试题型与命题风格,通过单选题与程序结果分析题检验语法掌握程度,并对照解析梳理自增自减、指针调用、函数重载等高频失分点,适合作为期末冲刺阶段的模拟练习与查漏补缺材料。

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

很多人复习 C++ 期末,第一反应是翻教材目录,从变量、运算符一路看到文件流,结果上了考场发现卷子根本不按目录出牌。这份 16-17(1) 的 C++ 程序设计基础 A 卷就是典型:四大题、100 分、120 分钟闭卷,单选 20 分、程序结果 30 分、填空 30 分、编程 20 分。分值分布已经把话说得很明白——读程序的能力占 60 分,写代码只占 20 分。也就是说,这场考试不是考你会不会从零写一个系统,而是考你能不能在 30 秒内看穿一段代码的副作用、短路求值、指针偏移和递归回溯。适合谁?适合正在刷历年卷、想把「看得懂但做不对」变成「一眼定答案」的备考人。下面按考点模块拆,每章都落到能直接背、直接练的题上。

2. 单选高频考点:20 道题里反复出现的 6 类陷阱

单选题每题 1 分,看着便宜,实际是整张卷子的「概念体检」。20 道题里,常量合法性、短路求值、逻辑表达式等价变形、自增自减合法性、循环次数判断、switch 穿透,这六类几乎年年换皮重来。把这六类吃透,单选基本能稳在 16 分以上。

2.1 常量与表达式合法性:先看「能不能编译」

第 1 题问哪个是不合法常量,选项里0xab是十六进制、"student"是字符串字面量、618E3是科学计数法浮点,count是标识符不是常量。这类题的答题思路是:先分类,再排除。常量只有四种面孔——整型、浮点、字符、字符串,凡是「看起来像变量名」的直接判非法。

第 4 题更阴:++(a++)、a++++b、++(++a)、++a++b哪个正确。这里考的是自增运算符的操作数必须是左值,而a++返回的是右值,所以++(a++)和++a++b都翻车;a++++b是词法歧义,编译器会拆成(a++)++b,同样不合法。只有++(++a)合法,因为++a返回左值引用。面试官最想听的是你能说出「前置返回引用、后置返回值」这句,而不是背答案。

int a = 1; ++(++a); // 合法:++a 返回左值引用,可再自增 // ++(a++); // 非法:a++ 返回右值,不能作为 ++ 的操作数

代码里注释那句就是判分点。参数说明:前置++的返回类型是T&,后置是T,这是所有自增合法性题的根。

2.2 短路求值与逻辑表达式:别急着算右边

第 2 题int a=1,b=1; --a && --b;执行后 a、b 各是多少。很多人手一快就写「都减 1 得 0、0」,错。&&是短路与,左边--a先执行,a 变成 0,结果为假,右边--b根本不执行,所以 b 还是 1,答案是 a=0、b=1。这类题的标准答法是:先标出短路点,再只算被执行的半边。

第 3 题「大于 2 或小于 -2」的逻辑表达式,正确写法是a>2 || a<-2,但选项里给的是!(a>=-2 && a<=2),这是德摩根律的等价变形,也对。答题时先写出自然语言对应的区间,再用德摩根律验证选项,两个方向对上了才选。

提示:短路求值题里,只要右边有++、--、函数调用,先问一句「左边能不能决定结果」,能决定就整段跳过。

2.3 循环与 switch:数次数不如数「条件什么时候假」

第 6 题for(i=10; i=count; i--)循环几次。注意中间是赋值不是比较,i=count把 count 的值赋给 i,表达式值就是 count,count 初值 1,非零为真,但循环体里count--让 count 变 0,下一轮i=0为假退出。所以实际执行 1 次。这类题翻车的血泪经验是:把=看成==。

第 8 题 switch 没有 break,m=2从 case 2 一路穿透到 default,输出2default。答这类题就在草稿上画箭头,从匹配的 case 开始往下划,遇到 break 才停。

int m = 2; switch (m) { case 1: cout << "1"; // 不匹配,跳过 case 2: cout << "2"; // 从这里进入 default: cout << "default"; // 无 break,继续穿透 } // 输出:2default

逻辑说明:switch 只决定「入口」,不决定「出口」,出口由 break 控制。参数上没有任何玄学,就是穿透规则。

2.4 函数原型与 const:默认参数和引用是重灾区

第 9 题问哪个函数原型错误,Func(int a, b, c);错在 b、c 没写类型,C++ 不允许这种省略。第 10 题const int MAX传给func能编译,原型必须是int func(const int&),因为 const 对象不能绑定到非 const 引用。第 11 题const double&配int*,选项fun1(&PI, *x)把 const 地址传给非 const 指针、把 int 值当指针,双重错。

这类题的答题模板:先看实参类型,再看形参能不能接住。const 引用能接常量、能接临时量;非 const 引用只能接左值;指针要看 const 修饰在哪一层。

2.5 指针与数组:地址和元素差一层解引用

第 15 题int a[2][2]里不能表示a[0][0]地址的是*a。a[0]是行首地址、&a[0][0]是元素地址、*(a[0])等价a[0][0]的值不是地址,*a是a[0]即行地址。第 18 题pAry+1是指针不是元素值,不能表示数组元素。第 19 题int x[3][4], *p;正确赋值是p=*x,因为*x等价x[0],是int*类型。

答题思路固定成三步:这个表达式是什么类型 → 它指向哪 → 加星号后是什么。三步走完,指针题基本不丢分。

2.6 字符串与 strlen:转义字符要一个一个数

第 16 题char *str="\nThank\10you,\0sir! ";求 strlen。\n一个字符,\10是八进制转义一个字符,\0是字符串结束符,strlen 数到\0停。所以有效字符是\n、T、h、a、n、k、\10、y、o、u、,共 11 个,答案 11。这类题的唯一办法是把转义序列当单个字符逐个标号,别用眼睛估。

3. 程序结果题:30 分靠「手跑一遍」的固定套路

第二道大题 6 小题、每题 5 分,是整张卷子性价比最高的部分——不需要写代码,只需要按执行顺序把变量值记下来。但每年失分也最集中,因为大家习惯「看个大概」而不是「逐行记账」。这一章给三类高频程序:嵌套循环、递归、结构体指针链。

3.1 嵌套循环与图形输出:先定行列再定边界

第 1 题双层 for,i从 1 到 5,j从 1 到 5,条件是i==1||i==n||j==1||j==n输出a,否则输出空。这就是打印 5×5 的边框。答题时先在纸上画 5 行 5 列,把满足条件的格子涂黑,一眼看出是空心方框。执行结果就是五行,每行首尾是a,中间三个空格。

for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) if (i == 1 || i == n || j == 1 || j == n) cout << "a "; else cout << " "; // 注意这里是两个空格,保持对齐 cout << endl; }

逻辑说明:外层控制行,内层控制列,边界条件用「或」连接四个边。参数上n=5决定规模,改 n 就是改方框大小。易错点是 else 分支的空格数,少一个就错位,判卷按字符比对会扣分。

3.2 递归与字符变换:画出调用栈再回溯

第 3 题MysteryFun读字符,小写 a–u 加 5,v–z 减 21,遇到.停止递归,然后倒序输出。输入stud.,调用顺序是 s→t→u→d→.,.不满足任何变换且不递归,开始回溯输出:d 变 i、u 变 z、t 变 y、s 变 x,最终输出izy x(按实际变换逐个算)。这类题的标准动作是画一棵调用树,叶子是.,然后从叶子往上写输出。

注意:递归题里「先递归后输出」和「先输出后递归」结果正好相反,看准 cout 在递归调用前还是后。

3.3 结构体与指针链:顺着 q 指针走三跳

第 6 题Node a[] = {{"China",a+1},{"France",a+2},{"USA",a}},p=a,然后p->s、p->q->s、p->q->q->s、p->q->q->q->s。第一跳 China,第二跳 France,第三跳 USA,第四跳又回到 China,形成环。输出China France USA China。答题时把三个结点画成三角形,箭头标清楚,跟着走就行。

struct Node { char* s; Node* q; }; Node a[] = { {"China", a+1}, {"France", a+2}, {"USA", a} }; Node* p = a; cout << p->s; // China cout << p->q->s; // France cout << p->q->q->s; // USA cout << p->q->q->q->s; // 回到 China

逻辑说明:a+1是数组第二个元素的地址,q存的是结点指针,所以p->q->q是两次解引用再取成员。参数上没有任何隐藏,关键是别把->和.混用。

3.4 数组传参与引用回填:av 是怎么算出来的

第 5 题fun1(ary, size, av),函数里累加t,最后a = double(t)/size。ary是{10,20,30,40},和 100,size 4,av=25。这题考的是数组名退化为指针、double& 回填结果两个点。答题时注意sizeof(ary)/sizeof(int)在主函数里算才是 4,传进函数后sizeof(p)只是指针大小,这是经典坑。

4. 填空与编程题:30+20 分怎么拿稳

第三大题 15 空、每空 2 分,第四大题两小题各 10 分。这部分不是考你发明算法,而是考你把给定的框架补完整。框架已经给了 80%,你要补的是初始化、循环条件、函数指针形参、排序比较这几类「关节」。

4.1 加密程序填空:先看输出样例反推变量

加密规则是每位加 7 模 10 再逆置。空 (1) 是k=n,把输入存到工作变量;(2) 是k或k!=0,控制逐位处理;(3) 是k/=10,砍掉最低位。答题思路:拿样例1234手跑,看每一步 m 和 k 应该是什么,空自然就出来了。

k = n; m = 0; while (k) { // (2) 非零继续 t = k % 10; m = m * 10 + (t + 7) % 10; k /= 10; // (3) 去掉最低位 }

逻辑说明:m = m*10 + 新位是「边取位边逆置」的标准写法,比先存数组再倒序省空间。参数上(t+7)%10保证结果仍是 0–9。

4.2 函数指针作形参:trap 的签名怎么定

梯形法求积分,trap要接收被积函数。空 (5) 是double (*fun)(double),空 (6) 是t += (*fun)(a + i*h),空 (7) 是t3 = trap(f3, 0, 3.14159, 10000)。这类空的关键是形参类型必须和实参 f1/f2/f3 的签名一致:都是double(double)。

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

逻辑说明:梯形公式首尾各取一半,中间全加,最后乘 h。参数上n=10000是等分数,越大越准。函数指针的写法(*fun)(x)和fun(x)等价,但前者更能体现「指针」语义,判卷通常都认。

4.3 随机数去重与素数判断:两个循环条件别写反

第 3 题产生 10 个互不相同的两位数并输出素数。空 (8) 是p[i]==num,检查重复;空 (9) 是p[i]%j==0,找到因子就 break;空 (10) 是check(a,i,x),重复就重摇;空 (11) 是print(a,10)。这题最容易错的是 (10) 写成!check,逻辑正好反了——要的是「只要重复就继续摇」,所以while(check(a,i,x)) x=rand();。

4.4 结构体排序与动态数组:比较方向和内存释放

第 4 题按薪水降序,空 (12) 是p = new Employee[total],空 (13) 是Output(p,total),空 (14) 是all[j].salary > all[t].salary(降序用大于),空 (15) 是t != i。第四大题第 2 小题动态数组逆置,核心是adverse里首尾交换:

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; } }

逻辑说明:只走到n/2,否则换两次等于没换。参数上p是new int[n]的堆数组,函数内不需要 delete,释放责任在 main。这类题面试官最想听的是「谁申请谁释放」这句话。

5. 易错点:这 5 个坑每年都有人踩

5.1 把赋值当比较

for(i=10; i=count; i--)和if(a=1)都是赋值。错在把=当==读,编译器只给警告不报错,运行时逻辑全变。答对的办法:看到循环/条件里的单个等号,先停三秒,确认左边是不是被赋值。

5.2 短路求值多算一步

--a && --b里 b 不该减。错在从左到右无脑执行。答对的办法:先判断左边真假,假就整段跳过,草稿上给没执行的变量打叉。

5.3 const 引用绑定错层

const int MAX传给int&形参编译不过。错在忽略 const 的传染性。答对的办法:实参带 const,形参必须带 const,指针还要看 const 在*左还是右。

5.4 二维数组地址与元素混淆

*a是行地址不是元素值,*(a[0])才是a[0][0]。错在解引用层数没数清。答对的办法:给每个表达式标类型,int(*)[2]和int*和int分三栏写。

5.5 递归输出顺序反了

MysteryFun先递归后 cout,输出是倒序。错在按输入顺序写答案。答对的办法:画调用栈,cout 在递归调用之后就从栈顶往下写。

6. 考场时间分配与押题思路:120 分钟怎么切

这张卷子的时间账要提前算好:单选 20 题控制在 25 分钟,程序结果 6 题给 35 分钟,填空 15 空给 30 分钟,编程 2 题留 25 分钟,最后 5 分钟检查。很多人栽在程序结果题上死磕,结果编程题没写完——20 分的编程题写个框架就有过程分,比抠一道 5 分的结果题划算。

押题方向上,从这份 A 卷能看出命题偏好非常稳定:指针与数组的关系、函数指针作形参、结构体排序、递归回溯、短路求值这五块几乎必出。复习时不要平均用力,把这几块的历年变体各刷三遍,比通读教材有效得多。填空题的关节位置也有规律——初始化、循环条件、函数签名、比较方向,四个位置覆盖了 80% 的空。

题型分值建议用时拿分策略
单选2025 分钟先分类再排除,不纠结
程序结果3035 分钟逐行记账,画栈画表
填空3030 分钟拿样例反推,先易后难
编程2025 分钟先写框架再补细节

答题技巧上再补一条:程序结果题写完答案后,用「反向验证」——把答案代回代码,看能不能自洽。比如算出 av=25,就回去看 100/4 是不是 25,对上了再落笔。这个习惯看着笨,但能拦住大部分手滑。

我当年第一次做这类卷子,程序结果题六道错了四道,全是「看着像」就写答案,没手跑。从那以后我每次做读程序题都强制走一遍「标变量、记初值、逐行改、画栈」四步,哪怕题再简单也不跳。希望帮到你。

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

返回列表