【C++语言基础】C/C++ 运算符优先级
·
运算符优先级是CSP-J中必考的基础知识点,经常出现在程序阅读题中(如判断复杂表达式的值),同时在你自己写代码时也能避免很多错误。下面我按从高到低的顺序整理了一份完整的优先级表,并附上记忆口诀和经典陷阱题。
一、完整优先级表(从高到低)
| 优先级 | 运算符 | 名称/含义 | 结合性 |
|---|---|---|---|
| 1 | () [] -> . |
函数调用、数组下标、结构体成员访问 | 左→右 |
| 2 | ++ -- + - ! ~ * & (type) sizeof |
单目运算符(后缀除外) | 右→左 |
| 3 | * / % |
乘、除、取模 | 左→右 |
| 4 | + - |
加、减 | 左→右 |
| 5 | << >> |
左移、右移 | 左→右 |
| 6 | < <= > >= |
关系运算符(小于、大于等) | 左→右 |
| 7 | == != |
等于、不等于 | 左→右 |
| 8 | & |
按位与(AND) | 左→右 |
| 9 | ^ |
按位异或(XOR) | 左→右 |
| 10 | | |
按位或(OR) | 左→右 |
| 11 | && |
逻辑与 | 左→右 |
| 12 | || |
逻辑或 | 左→右 |
| 13 | ?: |
条件运算符(三目运算符) | 右→左 |
| 14 | = += -= *= /= %= &= ^= |= <<=>>= |
赋值运算符 | 右→左 |
| 15 | , |
逗号运算符 | 左→右 |
二、记忆口诀(考场上快速回忆)
括号下标最优先,单目次之排第二。
乘除取模加加减,移位紧跟关系连。
等于不等于两旁,按位与或异或忙。
逻辑与或条件算,赋值最后逗号完。
口诀逐句解析:
| 口诀 | 对应优先级 | 说明 |
|---|---|---|
| 括号下标最优先 | 优先级1 | () [] . -> 最高 |
| 单目次之排第二 | 优先级2 | ! ~ ++ -- - * & sizeof |
| 乘除取模加加减 | 优先级3-4 | * / % 然后 + - |
| 移位紧跟关系连 | 优先级5-6 | << >> 然后 < <= > >= |
| 等于不等于两旁 | 优先级7 | == != |
| 按位与或异或忙 | 优先级8-10 | & 先于 ^ 先于 | |
| 逻辑与或条件算 | 优先级11-13 | && 先于 || 先于 ?: |
| 赋值最后逗号完 | 优先级14-15 | = 和 , 最低 |
三、结合性的理解
左结合(从左到右计算)
大多数双目运算符都是左结合,如 a + b - c 等价于 (a + b) - c
右结合(从右到左计算)
只有三种情况是右结合:
- 单目运算符:
!a先算 a,再取反 - 条件运算符:
a ? b : c ? d : e等价于a ? b : (c ? d : e) - 赋值运算符:
a = b = 3等价于a = (b = 3)
四、CSP-J 经典陷阱题
陷阱1:逻辑与 && 和按位与 & 混淆
int a = 2, b = 3;
int x = a & b; // 按位与:2 & 3 = 2
int y = a && b; // 逻辑与:2 && 3 = 1(true)
记忆: & 比 && 优先级高(&在第8级,&&在第11级)
陷阱2:== 和 = 混用
int a = 5;
if (a = 3) { ... } // 赋值操作,a变成3,条件为真(3≠0)
if (a == 3) { ... } // 比较操作,判断a是否等于3
CSP-J常考: if (x = 0) 永远不会进入,因为赋值后 x=0,条件为假。
陷阱3:算术运算符优先级高于移位运算符
int x = 5 + 3 << 2; // 等价于 (5+3) << 2 = 8 << 2 = 32
int y = 5 + (3 << 2); // 等价于 5 + 12 = 17
陷阱4:位运算优先级关系
int x = 1 | 2 & 3; // & 优先于 |:2&3=2,1|2=3
int y = (1 | 2) & 3; // 加括号后:(1|2)&3 = 3&3 = 3
优先级顺序: & > ^ > |
陷阱5:关系运算符优先级高于赋值
int a = 5, b = 10;
int c = a > b; // 等价于 c = (a > b),c = 0(false)
陷阱6:逗号运算符
int a = (1, 2, 3); // a = 3(逗号表达式返回最后一个值)
int b = 1, 2, 3; // 编译错误!(=优先级高于逗号,等价于 (b=1),2,3)
陷阱7:递增/减运算符
以下代码的输出是?
intx = 3;
cout << (x++ + ++x);
|
A6 |
B7 |
|
C8 |
D未定义行为 |
解析:D。同一表达式中对同一变量多次自增是未定义行为(UB),不同编译器结果不同。
五、复杂表达式实战演练
例题1(CSP-J 2018 真题改编)
int a = 5, b = 3, c = 2;
int x = a % b * c + a / b;
cout << x;
解析:
%和*同级,从左到右:(a % b) * c = (5%3)*2 = 2*2 = 4/:a / b = 5/3 = 1+:4 + 1 = 5
答案:5
例题2
int x = 10, y = 3, z = 2;
int result = x / y * z + x % y;
cout << result;
解析:
/和*同级左结合:(x/y)*z = (10/3)*2 = 3*2 = 6%:x % y = 10 % 3 = 1+:6 + 1 = 7
答案:7
例题3(逻辑短路)
int a = 1, b = 2, c = 3;
if (a > b && b++ > c) { ... }
cout << b;
解析:
a > b为1 > 2,结果为false&&短路:前面为 false,后面的b++ > c不执行- b 仍为 2
答案:2
例题4(复合赋值)
int a = 5;
a += a *= 3;
cout << a;
解析:
- 赋值运算符是右结合:
a += (a *= 3) - 先算
a *= 3:a = 5*3 = 15 - 再算
a += 15:a = 15+15 = 30
答案:30
例题5(条件运算符嵌套)
int a = 3, b = 4, c = 5;
int x = a > b ? a : b > c ? b : c;
cout << x;
解析:
?:是右结合:a > b ? a : (b > c ? b : c)a > b为假,执行(b > c ? b : c)b > c为假,结果为 c = 5
答案:5
六、特殊情况与易错点总结
| 情况 | 优先级/结合性 | 结果 |
|---|---|---|
*p++ |
* 和 ++ 同级,右结合 |
先取 *p,再 p++ |
*p-- |
同上 | 先取 *p,再 p-- |
++*p |
右结合 | 先取 *p,再++ |
a << b + c |
+ 高于 << |
a << (b + c) |
a & b | c |
& 高于 | |
(a & b) | c |
a == b && c |
== 高于 && |
(a == b) && c |
x = y = z |
右结合 | x = (y = z) |
七、速查卡(考前看一眼)
| 优先级 | 算术运算符 | 关系/比较运算符 | 逻辑运算符 | 位运算符 | 赋值运算符 |
|---|---|---|---|---|---|
| 1 (高) |
|||||
| 2 | + - 正负号++ --* & 指针(type) 强制转换sizeof |
! 逻辑非 |
~ 按位取反 |
||
| 3 | * / %(乘、除、取模) |
||||
| 4 | + -(加、减) |
||||
| 5 | << >>(左移、右移) |
||||
| 6 | < <=> >= |
||||
| 7 | == != |
||||
| 8 | &(按位与) |
||||
| 9 | ^(按位异或) |
||||
| 10 | |(按位或) |
||||
| 11 | &&(逻辑与) |
||||
| 12 | ||(逻辑或) |
||||
| 13 | ?:(条件运算符) |
||||
| 14 (低) |
= += -=*= /= %=&= ^= |=<<= >>= |
八、记忆关键点(只记这些就够了)
- 括号第一:
()[]最高 - 单目第二:
!~++---*&sizeof - 乘除加减:
* / %>+ - - 移位关系:
<< >>>< <= > >= - 相等:
== != - 按位先与后或:
&>^>| - 逻辑与或:
&&>|| - 赋值最低:
=和,垫底
最后建议: 做题时如果遇到不确定优先级的表达式,不要靠记忆硬背,而是直接加括号明确顺序。实际上,CSP-J的程序阅读题中,99%的优先级考察都集中在上面8个关键点。把这8个记住,考试就够用了。
更多推荐


所有评论(0)