C++ 语法细节¶
方法速览¶
| 任务 | 方法 | 口诀 |
|---|---|---|
| 表达式求值 | 先括号/强转,再 % * / 同级左结合,最后加减 |
强转最急、乘模先于加减 |
| 位运算与逻辑混合 | & > ^ > | > && > || |
位高于逻辑 |
| 浮点截断 | (int) 向零截断 |
砍尾巴不四舍五入 |
| int 与 float 混算 | int 提升为浮点 | 见浮点就变浮点 |
表达式求值(S 真题模型)¶
【例】(2019 真题)int a=7; float x=2.5, y=4.7;,求 x + a%3*(int)(x+y)%2:
| 步骤 | 片段 | 演算 | 结果 |
|---|---|---|---|
| 1 | (int)(x+y) |
\(2.5+4.7=7.2\),向零截断 | \(7\) |
| 2 | a%3 |
\(7\bmod 3\) | \(1\) |
| 3 | 1*7%2 |
同级左结合 \(1\times7=7\),\(7\bmod2\) | \(1\) |
| 4 | x+1 |
int 转 float | \(3.5\) |
位运算优先级链¶
【例】(2023 真题)int a=5, b=3, c=4; bool res = a & b || c ^ b && a | c;
加括号顺序:(a & b) || ((c ^ b) && (a | c))
| 片段 | 演算 | 值 |
|---|---|---|
a & b |
\(101 \& 011 = 001\) | \(1\) |
c ^ b |
\(100 \wedge 011 = 111\) | \(7\) |
a | c |
\(101 \| 100 = 101\) | \(5\) |
7 && 5 |
非零 | 真 |
1 || 真 |
见真即真 | true |
中缀转后缀¶
【是什么】 后缀(逆波兰)表达式:运算符放在两个操作数之后,无需括号。
【怎么算】 完全括号法:按优先级补全括号,把每个运算符移到它那对括号的右边,去掉括号。
【例】(2020 真题)a*(b+c)-d:补全 (a*(b+c))-d;bc+ → abc+* → abc+*d-。
练习题目¶
练习 1 · 强转只作用一处¶
题目
(int)(3.9 + 0.9) 的值是( )
- A. \(3\)
- B. \(4\)
- C. \(4.8\)
- D. \(3.9\)
答案与解析
答案:B
先算括号 \(4.8\),再截断 \(4\)。
练习 2 · 强转优先级¶
题目
(int)3.9 + 1 的值是( )
- A. \(3\)
- B. \(4.9\)
- C. \(4\)
- D. \(3.9\)
答案与解析
答案:C
强转只作用于紧邻的 3.9:\(3 + 1 = 4\)——括号位置差一位结果不同。
练习 3 · 混合求值¶
题目
int a=7; float x=2.5; 表达式 x + a % 3 的值( )
- A. \(4.5\)
- B. \(4\)
- C. \(3.5\)
- D. \(5\)
答案与解析
答案:C
% 先于加法:\(7 \bmod 3 = 1\);float 与 int 混算提升:\(2.5 + 1 = 3.5\)。
干扰项思路:A 把 a%3 误算成了 2。
练习 4 · 同级左结合¶
题目
7 - 3 + 2 与 7 % 3 * 2 的值分别是( )
- A. \(2\) 和 \(2\)
- B. \(2\) 和 \(8\)
- C. \(6\) 和 \(8\)
- D. \(6\) 和 \(2\)
答案与解析
答案:D
同级从左到右:\((7-3)+2 = 6\);\((7\bmod3)\times2 = 1\times2 = 2\)——两值 \(6\) 与 \(2\)。
练习 5 · 除法与取模¶
题目
7 / 2 + 7 % 2 的值是( )
- A. \(4.5\)
- B. \(4\)
- C. \(3\)
- D. \(5\)
答案与解析
答案:B
整除 \(3\) + 余数 \(1\) = 4——int 除法先行的信号。
练习 6 · 位与优先¶
题目
5 & 3 的值是( )
- A. \(1\)
- B. \(7\)
- C. \(6\)
- D. \(2\)
答案与解析
答案:A
\(101\&011 = 001\)。
练习 7 · 异或¶
题目
5 ^ 3 的值是( )
- A. \(8\)
- B. \(7\)
- C. \(1\)
- D. \(6\)
答案与解析
答案:D
\(101 \wedge 011 = 110 = 6\)。
练习 8 · 位运算链¶
题目
1 | 2 ^ 3 & 1 的值是( )
- A. \(0\)
- B. \(1\)
- C. \(3\)
- D. \(2\)
答案与解析
答案:C
& 最先:\(1\&1 = 1\);^:\(3\wedge1 = 2\);|:\(1|2 = 3\)——位运算高于逻辑、位内部 & > ^ > |。
练习 9 · 逻辑与位运算混合¶
题目
bool x = (3 & 1) && (2 | 4); 的值是( )
- A.
0 - B.
false - C. 编译错误
- D.
true(\(1\&1=1\)、\(2|4=6\),均非零)
答案与解析
答案:D
位运算先出数值,再作逻辑判断。
练习 10 · 短路¶
题目
int i=0; (i != 0) && (10 / i > 1) 执行后( )
- A. 除零崩溃
- B. 右侧不执行(短路),无崩溃
- C. 结果为真
- D. i 变 1
答案与解析
答案:B
&& 左假即停——右侧的除法根本不跑。
练习 11 · 浮点判等¶
题目
0.1 + 0.2 == 0.3 的结果( )
- A.
true - B.
false(二进制小数误差) - C. 编译错误
- D. 不确定
答案与解析
答案:B
实际存成 \(0.30000\ldots4\);判等用 fabs(a-b) < 1e-9。
练习 12 · char 运算¶
题目
char c = 'A'; cout << c + 2; 输出( )
- A.
C - B. \(67\)
- C.
A2 - D. \(65\)
答案与解析
答案:B
char 提升 int:\(65+2 = 67\);转回 char 才输出 C。
练习 13 · 无符号回绕¶
题目
unsigned x = 0; --x; 后 x 是( )
- A. \(-1\)
- B. 未定义
- C. \(0\)
- D. \(4294967295\)
答案与解析
答案:D
无符号没有负数,回绕到最大值。
练习 14 · sizeof 表达式¶
题目
sizeof(1 + 1.5) 的值是( )
- A. \(8\)(double)
- B. \(4\)
- C. \(12\)
- D. 编译错误
答案与解析
答案:A
表达式类型是 double,sizeof 量结果类型。
练习 15 · 负数取模¶
题目
-7 % 3 的值是( )
- A. \(1\)
- B. \(2\)
- C. \(-1\)
- D. \(-2\)
答案与解析
答案:C
C++ 取模符号跟随被除数:\(-7 = -3\times3 + (-1)\)。
练习 16 · 自增混合¶
题目
int i = 3; int r = (i++) + (++i); 后( )
- A. r = 8, i = 5
- B. r = 7, i = 5
- C. 未定义行为
- D. r = 6, i = 4
答案与解析
答案:C
同一表达式内两次修改 i 无序列点——初赛按“避免这样写”记,考手算时通常按从左到右:i++ 用 3、++i 变 5,r = 3 + 5 = 8。
练习 17 · 移位与加法¶
题目
1 << 2 + 1 的值是( )
- A. \(6\)
- B. \(8\)
- C. \(5\)
- D. \(4\)
答案与解析
答案:B
加法优先级高于移位:\(1 << 3 = 8\)——别先移后加。
练习 18 · 三目结合¶
题目
1 > 0 ? 10 : 2 > 3 ? 20 : 30 的值是( )
- A. \(10\)
- B. \(20\)
- C. \(30\)
- D. 语法错误
答案与解析
答案:A
三目右结合,条件真直接取 10。
练习 19 · 赋值当判等¶
题目
int x = 3; if (x = 0) A(); else B(); 执行( )
- A.
A() - B.
B()(赋值表达式的值是 0 = 假) - C. 都不执行
- D. 死循环
答案与解析
答案:B
= 不是 ==;赋值表达式值为 0。
练习 20 · 整数溢出¶
题目
int 计算 2000000000 + 2000000000 的结果是( )
- A. 溢出为负数(未定义/回绕)
- B. \(4000000000\)
- C. \(0\)
- D. 编译错误
答案与解析
答案:A
超 \(2^{31}-1\) 溢出;上 long long。
练习 21 · 类型提升¶
题目
short s = 32767; s + 1 的类型与效果是( )
- A. int 运算得 \(32768\)(不回绕)
- B. short 回绕到 \(-32768\)
- C. 溢出崩溃
- D. 变 double
答案与解析
答案:A
参与运算先提升为 int;存回 short 才会截断回绕。
练习 22 · && 高于 ||¶
题目
a && b || c 等价于( )
- A. 语法错误
- B.
a && (b || c) - C. 两者都对
- D.
(a && b) || c
答案与解析
答案:D
&& 优先于 ||。
练习 23 · 比较与位与¶
题目
x & 1 == 0 实际是( )
- A.
x & (1 == 0)即x & 0,恒 0 - B.
(x & 1) == 0判偶 - C. 语法错误
- D. x 判奇
答案与解析
答案:A
== 高于 &——判偶必须自己加括号。
练习 24 · 浮点字面值类型¶
题目
3.5 与 3.5f 的类型分别是( )
- A. 都是
double - B. 都是
float - C.
double与float - D.
int与float
答案与解析
答案:C
小数默认 double,后缀 f 才是 float。
练习 25 · 有符号右移¶
题目
负整数在多数编译器上 >> 1 的行为是( )
- A. 算术右移(补符号位)
- B. 逻辑右移(补 0)
- C. 结果为 0
- D. 未定义
答案与解析
答案:A
主流实现补符号位:\(-8 >> 1 = -4\)。
练习 26 · 综合求值¶
题目
2 + 3 * 4 % 5 的值是( )
- A. \(4\)
- B. \(14\)
- C. \(9\)
- D. \(0\)
答案与解析
答案:A
* % 同级左结合:\(3\times4=12\),\(12\bmod5=2\),\(2+2=4\)。
练习 27 · 后缀(基础)¶
题目
a + b 的后缀表达式( )
- A.
ab+ - B.
+ab - C.
a+b - D.
ba+
答案与解析
答案:A
运算符在两操作数之后。
练习 28 · 后缀(含乘)¶
题目
a + b * c 的后缀表达式( )
- A.
abc+* - B.
ab+c* - C.
abc*+ - D.
+a*bc
答案与解析
答案:C
乘优先:bc*,再 a bc* +。
练习 29 · 后缀(含括号)¶
题目
(a + b) * c 的后缀表达式( )
- A.
ab+c* - B.
abc+* - C.
ab*c+ - D.
*+abc
答案与解析
答案:A
括号强制先加:ab+,再乘 c。
练习 30 · 后缀求值¶
题目
后缀 2 3 4 * + 的值是( )
- A. \(20\)
- B. \(10\)
- C. \(24\)
- D. \(14\)
答案与解析
答案:D
\(3\times4 = 12\),\(2+12 = 14\)。
历年真题¶
2019 年 · 第 1 题¶
题目
若有定义:int a=7; float x=2.5, y=4.7;,则表达式 x+a%3*(int)(x+y)%2 的值是:( )
- A.
0.000000 - B.
2.750000 - C.
3.500000 - D.
2.500000
答案与解析
答案:C
四步演算表见教学节:截断 7 → \(1\times7\bmod2 = 1\) → \(2.5+1 = 3.5\)。
2019 年 · 第 5 题¶
题目
设变量 x 为 float 型且已赋值,则以下语句中能将 x 中的数值保留到小数点后两位,并将第三位四舍五入的是( )
- A.
x=(x*100+0.5)/100.0; - B.
x=(x/100+0.5)*100.0; - C.
x=x*100+0.5/100.0; - D.
x=(int)(x*100+0.5)/100.0;
答案与解析
答案:D
放大→加半→int 截断→缩回:以 \(x = 3.14159\) 为例 \(314.159 + 0.5 = 314.659 \to (int)\,314 \to 3.14\);A 缺截断、结果仍带小数。
2020 年 · 第 12 题¶
题目
表达式 a*(b+c)-d 的后缀表达形式为( )。
- A.
abc*+d- - B.
-*+abcd - C.
abcd*+- - D.
abc+*d-
答案与解析
答案:D
(a*(b+c))-d:先 bc+,再 abc+*,最后 abc+*d-(完全括号法演算见“中缀转后缀”节)。
2023 年 · 第 9 题¶
题目
假设有以下 C++ 代码:
请问,res 的值是什么?( )
提示:在 C++ 中,逻辑运算的优先级从高到低依次为逻辑非 !、逻辑与 &&、逻辑或 ||;位运算的优先级从高到低依次为位非 ~、位与 &、位异或 ^、位或 |。双目位运算的优先级高于双目逻辑运算;逻辑非和位非优先级相同,且高于所有双目运算符。
- A.
1 - B.
false - C.
true - D.
0
答案与解析
答案:A
加括号 (a&b) || ((c^b) && (a|c)) = 1 || (7 && 5) = true(逐段演算表见教学节)。
易错小结¶
- 强转只作用于紧邻操作数;整除 / 取模先于加减、同级左结合;
- 位运算链
& > ^ > |,全部高于&&/||(2023 真题); - 移位低于加减:
1 << 2 + 1= 8;比较高于位与:x & 1 == 0恒 0; - 浮点不能判等;
(int)向零截断(负数也朝零);取模符号随被除数; =当==恒取赋值后的真值;int 溢出要 long long;小数字面值默认 double;- float 四舍五入
(int)(x*100+0.5)/100.0(2019 真题);中缀转后缀用完全括号法、符号右移(2020 真题)。