- Admin 的博客
2023年12月 C++二级真题解析
- 2025-9-18 9:56:14 @
一、单选题解析
第 1 题 答案:C
- 解析:C++变量名必须以字母或下划线开头,不能以数字开头。
5Star
以数字5
开头,因此是非法的变量名。FiveStar
、fiveStar
、Star5
都是合法的。
第 2 题 答案:A
- 解析:原循环
for(int i= 10; i< 20; i+=2)
会输出10, 12, 14, 16, 18
。- 选项A
for(int i= 10; i< 19; i+=2)
同样输出10, 12, 14, 16, 18
,因为当i=18
时,18<19
为真,执行后i
变为20,循环结束。 - 选项B从11开始,输出
11, 13, 15, 17
。 - 选项C条件是
i<21
,会多输出一个20
。
- 选项A
第 3 题 答案:D
- 解析:要找出N的所有因数,需要从1遍历到N(包含N),因为N本身也是它的一个因数。选项D
int i= 1; i< N+1; i++
等价于i
从1到N。选项Bi< N
会漏掉N这个因数。
第 4 题 答案:D
- 解析:这段代码的思路是将数字N反转,然后与原数比较。但在循环
while(N>0)
中,N的值被不断改变(N/=10
),循环结束后N的值变为0。因此,最后if(N==reverseN)
永远是比较0 == reverseN
,无法达到判断对称数的目的。
第 5 题 答案:D
- 解析:判断质数需要检查从2到
sqrt(N)
的所有数。代码中检查到N/2
,对于某些合数(如4),N/2=2
,循环会执行,4%2==0
,能正确判断4不是质数。但对于9,N/2=4.5
,在整数循环中i
最大到4,9%3==0
会在i=3
时被检测到。真正的漏洞在于边界:如果N是一个大于2的质数,且其最小因数大于N/2
,这种情况不存在,因为最小因数不会大于sqrt(N)
。更严谨的边界是i <= N/2
或i*i <= N
。选项D提到改为N/2+1
是为了确保包含N/2
这个边界值(当N为偶数时),虽然N/2+1
对于质数判断来说范围过大,但确实能保证不错判。原代码在i < N/2
时,对于偶数N,会漏掉N/2
这个因数。例如N=4,N/2=2
,循环条件i<2
,i
从2开始就不满足条件,循环不执行,导致错误地认为4是质数。所以,将<
改为<=
或者将边界改为N/2+1
可以修复这个漏洞。
第 6 题 答案:A
- 解析:这是一个逗号表达式
a=1, b=2, c=0
。逗号表达式的值是最后一个表达式的值,所以if
的条件是c=0
,其值为0(false),因此不执行if
内的c++
。接着执行cout<< a<< "#" << b<< "#" << c;
,输出1#2#0
。注意,a=1, b=2, c=0
这三个赋值都会执行,所以a、b、c的值确实被改变了。
第 7 题 答案:D
- 解析:
int a=4, b=8;
初始化。a= (b=4, b+4);
这是一个逗号表达式。先执行b=4
,此时b的值变为4;然后计算b+4
得到8;最后将8赋值给a。所以执行后,a=8, b=4。cout<< a<< "#" << b;
输出8#4
。但根据答案选项,正确答案是D(4#4),这与分析不符。可能是题目或答案有误。根据标准C++语义,此处应输出8#4
。但如果题目代码或上下文有其他未显示部分,可能会导致不同结果。按照给定答案,我们标记为D。
第 8 题 答案:C
- 解析:这是一个递归函数。
f(10)
调用f(9) + 10
f(9)
调用f(8) + 9
- ...
f(1)
返回1。 所以,f(10) = 1 + 2 + 3 + ... + 10 = 55
。
第 9 题 答案:D
- 解析:函数
f(a, b)
的作用是交换两个变量的值(通过指针)。- 第一次调用
f(&x, &y)
:x=1, y=10。交换后,x=10, y=1。输出x,y
即10,1
。 - 第二次调用
f(&x, &z)
:此时x=10, z=12。交换后,x=12, z=10。输出x,z
即12,10
。 注意,输出语句是cout<< x<< "," << y<< endl;
和cout<< x<< "," << z<< endl;
,所以总输出是两行:10,1
和12,10
。但选项中没有直接匹配的。根据答案B(1,3)和D(1,10,12),推测题目或选项可能有排版错误。最接近逻辑的答案是D,可能意指输出了1, 10, 12这几个数字。
- 第一次调用
第 10 题 答案:B
- 解析:这是一个递归函数,计算从1累加到n的和。
sum(4)
调用sum(3) + 4
sum(3)
调用sum(2) + 3
sum(2)
调用sum(1) + 2
sum(1)
返回1。 所以,sum(4) = 1 + 2 + 3 + 4 = 10
。
第 11 题 答案:C
- 解析:要判断
i
是否为完全平方数,可以计算其平方根sqrt(i)
,然后取整。如果i
是完全平方数,那么(int)sqrt(i)
的平方应该等于i
。选项Cint(sqrt(i)) * int(sqrt(i)) == i
正是这个逻辑。选项A是赋值而非判断。选项B比较的是整数和浮点数,不严谨。选项D的逻辑是错误的。
第 12 题 答案:D
- 解析:题目要求实现一个左图效果(通常是某种矩阵或图案,每行结束后需要换行)。代码中有一个外层循环控制行数,内层循环控制列数。在每一行的字符输出完毕后,需要输出一个换行符
endl
来开始新的一行。根据选项描述,D选项“与第9行下面填入一行:cout<< endl;”最符合这个逻辑,即在内层循环结束后、外层循环下一次迭代开始前换行。
第 13 题 答案:C
- 解析:题目问的是“完成选路所必须的”。选路是指规划从起点到终点的路线。
- 麦克风 (A):用于接收乘客的语音指令(目的地),是必需的。
- 扬声器 (B):用于向乘客告知选择的路线,是必需的。
- 传感器 (D):用于感知环境(如障碍物、路况),对安全驾驶和路线微调是必需的。
- 油量表 (C):用于监测燃油量,虽然对车辆运行很重要,但它并不直接参与“选择一条优化路线”的计算过程。系统可以在不知道当前油量的情况下,仅根据地图和交通状况计算出理论最优路线。因此,油量表不是选路所必须的。
第 14 题 答案:B
- 解析:现代计算机普遍采用的是“冯·诺依曼体系结构”,其核心特点是“存储程序”,即程序和数据都存储在内存中,由CPU依次读取并执行。
第 15 题 答案:B
- 解析:要找出所有相邻的因数对
(i, i+1)
,即i
和i+1
都是N的因数。- 选项A:
i
从1到N-1,可以找到所有可能的相邻对,包括(1,2)。 - 选项B:
i
从2开始,会漏掉第一对可能的因数对(1,2)。例如N=6,因数对有(1,2)、(2,3)。选项B从i=2开始,只能找到(2,3),漏掉了(1,2)。 - 选项C和D:通过调整循环变量和判断条件,也能找到所有对。C是判断
(i-1, i)
,D是判断(i, i+1)
且i
只循环到N/2
(因为相邻因数对中较小的那个不会超过N/2)。
- 选项A:
二、判断题解析
第 1 题 答案:√ (正确)
- 解析:在C++中,两个整数相除,结果是整数,向零取整。
-7 / 2
的结果是-3
。
第 2 题 答案:× (错误)
- 解析:字符
'9'
的ASCII码值是57。int('9')
的结果是57。所以2 * 57 * 2 = 228
,不是36。
第 3 题 答案:× (错误)
- 解析:C++中运算符优先级:算术运算符
+
、-
优先级高于逻辑运算符&&
。所以表达式等价于(3+2) && (5-5)
,即5 && 0
。非零值为true,零为false,所以是true && false
,结果为false
。题目说“值为false”,这是正确的,但答案标记为错误(×),这可能是题目或答案有误。根据标准C++,该表达式值确实是false。我们按给定答案标记为错误。
第 4 题 答案:√ (正确)
- 解析:
srand(0)
用固定的种子0初始化随机数生成器。之后每次调用rand()
生成的伪随机数序列是完全相同的。因此,连续两次调用rand()
得到的结果必然相等。
第 5 题 答案:× (错误)
- 解析:
while(1){...}
是合法的C++语法。1
会被隐式转换为布尔值true
,表示无限循环。这不是语法错误。
第 6 题 答案:× (错误)
- 解析:代码
int a=1; a=a<<2; cout<< a;
。a<<2
是将a的二进制值左移两位。1
的二进制是0001
,左移两位变成0100
,即十进制的4。所以输出是4,不是0。
第 7 题 答案:× (错误)
- 解析:C++支持运算符重载,允许为不同类型定义运算符的行为。此外,C++有隐式类型转换规则,当运算符两边类型不同时,编译器会自动进行类型转换(如int和double相加,int会转为double)。所以,运算符并非只能处理相同类型。
第 8 题 答案:× (错误)
- 解析:C++是静态类型语言。一个变量在声明时确定了其数据类型,在其生命周期内,只能存储该类型的值(或可以隐式/显式转换为该类型的值)。不能随意改变其类型。例如,
int a; a = 5; a = 3.14;
是合法的,因为3.14
会被转换为int
类型的3赋给a,但a的类型始终是int
。
第 9 题 答案:× (错误)
- 解析:Dev C++ 是一个集成开发环境(IDE),它包含了代码编辑器、编译器(如GCC)、调试器等工具。它不是一个操作系统。操作系统(如Windows, Linux, macOS)是管理计算机硬件与软件资源的系统软件。
第 10 题 答案:√ (正确)
- 解析:
while
循环和for
循环在功能上是等价的,可以相互转换。while(condition) { ... }
可以转换为for(; condition; ) { ... }
。for(init; condition; update) { ... }
可以转换为{ init; while(condition) { ... update; } }
。
三、编程题解析
3.1 小杨做题
解题思路:
这是一个类斐波那契数列问题。我们需要模拟小杨每天做题的过程,从第1天和第2天开始,从第3天起,每天的题量是前一天和前两天之和。同时,有一个停止条件:如果某一天做题量 >= m
,则从第二天开始停止做题。我们需要计算前 n
天内(考虑停止条件)的总题量。
关键点:
- 使用循环从第3天遍历到第n天。
- 在循环内计算当天的题量
c = a + b
。 - 将当天题量加到总和
ans
中。 - 更新
a
和b
为下一天做准备(a = b; b = c;
)。 - 检查停止条件:如果
c >= m
,则用break
跳出循环,后续天数不再做题。 - 注意,第1天和第2天的题量在循环前就已经加到
ans
中了。
参考代码分析: 提供的参考代码逻辑正确:
- 读入
a
(第1天),b
(第2天),m
(停止阈值),n
(总天数)。 - 初始化
ans = a + b
,包含了前两天。 - 从第3天(
i=3
)循环到第n天(i<=n
)。 - 计算当天题量
c = a + b
。 - 累加
ans += c
。 - 更新
a = b; b = c;
。 - 如果
c >= m
,则break
。 - 输出
ans
。
3.2 小杨的 H字矩阵
解题思路: 需要打印一个n x n的字符矩阵,其中:
- 第1列和第n列:所有行都是字符
|
。 - 第
(n+1)/2
行(中间行):从第2列到第n-1列都是字符-
。 - 其余位置:都是字符
a
。
关键点:
- 将输出分为三部分:中间行以上的行、中间行、中间行以下的行。
- 对于每一行,先输出左边的
|
。 - 然后输出中间的
n-2
个字符(根据行号判断是a
还是-
)。 - 最后输出右边的
|
并换行。 - 计算中间行的行号:
mid = (n+1)/2
。
参考代码分析: 提供的参考代码逻辑清晰:
- 读入
n
。 - 上半部分:循环
i
从1到(n+1)/2 - 1
。- 输出
|
- 循环
j
从2到n-1
,输出a
- 输出
|
并换行。
- 输出
- 中间行:
- 输出
|
- 循环
j
从2到n-1
,输出-
- 输出
|
并换行。
- 输出
- 下半部分:循环
i
从(n+1)/2 + 1
到n
。- 输出
|
- 循环
j
从2到n-1
,输出a
- 输出
|
并换行。
- 输出