运算符优先级是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

右结合(从右到左计算)

只有三种情况是右结合:

  1. 单目运算符!a 先算 a,再取反
  2. 条件运算符a ? b : c ? d : e 等价于 a ? b : (c ? d : e)
  3. 赋值运算符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;

解析:

  1. % 和 * 同级,从左到右:(a % b) * c = (5%3)*2 = 2*2 = 4
  2. /a / b = 5/3 = 1
  3. +4 + 1 = 5

答案:5


例题2

int x = 10, y = 3, z = 2;
int result = x / y * z + x % y;
cout << result;

解析:

  1. / 和 * 同级左结合:(x/y)*z = (10/3)*2 = 3*2 = 6
  2. %x % y = 10 % 3 = 1
  3. +6 + 1 = 7

答案:7


例题3(逻辑短路)

int a = 1, b = 2, c = 3;
if (a > b && b++ > c) { ... }
cout << b;

解析:

  1. a > b 为 1 > 2,结果为 false
  2. && 短路:前面为 false,后面的 b++ > c 不执行
  3. b 仍为 2

答案:2


例题4(复合赋值)

int a = 5;
a += a *= 3;
cout << a;

解析:

  1. 赋值运算符是右结合:a += (a *= 3)
  2. 先算 a *= 3:a = 5*3 = 15
  3. 再算 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;

解析:

  1. ?: 是右结合:a > b ? a : (b > c ? b : c)
  2. a > b 为假,执行 (b > c ? b : c)
  3. 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
(低)
= += -=
*= /= %=
&= ^= |=
<<= >>=

八、记忆关键点(只记这些就够了)

  1. 括号第一() [] 最高
  2. 单目第二! ~ ++ -- - * & sizeof
  3. 乘除加减* / % > + -
  4. 移位关系<< >> > < <= > >=
  5. 相等== !=
  6. 按位先与后或& > ^ > |
  7. 逻辑与或&& > ||
  8. 赋值最低= 和 , 垫底

最后建议: 做题时如果遇到不确定优先级的表达式,不要靠记忆硬背,而是直接加括号明确顺序。实际上,CSP-J的程序阅读题中,99%的优先级考察都集中在上面8个关键点。把这8个记住,考试就够用了。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐