C语言运算符优先级 #
一、优先级概述 #
1.1 什么是优先级 #
优先级决定表达式中运算符的计算顺序。优先级高的先计算。
1.2 什么是结合性 #
当优先级相同时,结合性决定计算方向:
- 左结合:从左向右计算
- 右结合:从右向左计算
二、优先级表 #
2.1 完整优先级表 #
| 优先级 | 运算符 | 名称 | 结合性 |
|---|---|---|---|
| 1 | () [] -> . | 后缀运算符 | 左 |
| 2 | ++ – + - ! ~ * & sizeof | 单目运算符 | 右 |
| 3 | * / % | 乘除 | 左 |
| 4 | + - | 加减 | 左 |
| 5 | << >> | 移位 | 左 |
| 6 | < <= > >= | 关系 | 左 |
| 7 | == != | 相等 | 左 |
| 8 | & | 按位与 | 左 |
| 9 | ^ | 按位异或 | 左 |
| 10 | | | 按位或 | 左 |
| 11 | && | 逻辑与 | 左 |
| 12 | || | 逻辑或 | 左 |
| 13 | ?: | 条件 | 右 |
| 14 | = += -= *= /= %= &= ^= |= <<= >>= | 赋值 | 右 |
| 15 | , | 逗号 | 左 |
2.2 记忆口诀 #
text
括号成员第一;
全体单目第二;
乘除余三,加减四;
移位五,关系六;
等于不等排第七;
位与异或位或八九十;
逻辑与或十一十二;
条件十三,赋值十四;
逗号十五最低.
三、常见优先级问题 #
3.1 算术运算符 #
c
#include <stdio.h>
int main() {
int a = 2, b = 3, c = 4;
printf("a + b * c = %d\n", a + b * c);
printf("(a + b) * c = %d\n", (a + b) * c);
printf("a * b + c = %d\n", a * b + c);
printf("a * (b + c) = %d\n", a * (b + c));
return 0;
}
输出:
text
a + b * c = 14
(a + b) * c = 20
a * b + c = 10
a * (b + c) = 14
乘除优先于加减。
3.2 关系运算符 #
c
#include <stdio.h>
int main() {
int a = 1, b = 2, c = 3;
printf("a < b < c = %d\n", a < b < c);
printf("(a < b) && (b < c) = %d\n", (a < b) && (b < c));
return 0;
}
输出:
text
a < b < c = 1
(a < b) && (b < c) = 1
a < b < c 先计算 a < b 得到1,然后 1 < c 得到1。
3.3 逻辑运算符 #
c
#include <stdio.h>
int main() {
int a = 1, b = 0, c = 1;
printf("a || b && c = %d\n", a || b && c);
printf("(a || b) && c = %d\n", (a || b) && c);
return 0;
}
输出:
text
a || b && c = 1
(a || b) && c = 1
&& 优先级高于 ||。
3.4 位运算与逻辑运算 #
c
#include <stdio.h>
int main() {
int a = 2, b = 4;
printf("a & b == 0: %d\n", a & b == 0);
printf("(a & b) == 0: %d\n", (a & b) == 0);
return 0;
}
输出:
text
a & b == 0: 0
(a & b) == 0: 1
== 优先级高于 &。
3.5 赋值运算符 #
c
#include <stdio.h>
int main() {
int a, b, c;
a = b = c = 10;
printf("a = %d, b = %d, c = %d\n", a, b, c);
return 0;
}
赋值是右结合,从右向左赋值。
四、使用括号 #
4.1 明确优先级 #
c
int result = (a + b) * (c - d);
使用括号明确计算顺序,提高可读性。
4.2 避免歧义 #
c
if ((a & b) == c) {
}
不依赖记忆,使用括号明确意图。
4.3 复杂表达式 #
c
int result = ((a + b) * c - d) / e;
分解复杂表达式:
c
int temp1 = a + b;
int temp2 = temp1 * c;
int temp3 = temp2 - d;
int result = temp3 / e;
五、常见错误 #
5.1 位运算与比较 #
c
if (a & b == c) {
}
应改为:
c
if ((a & b) == c) {
}
5.2 移位与加减 #
c
int a = 1 << 2 + 3;
应改为:
c
int a = (1 << 2) + 3;
或:
c
int a = 1 << (2 + 3);
5.3 指针与自增 #
c
*p++;
(*p)++;
*p++ 先取值,后移动指针。
(*p)++ 先取值,值加1。
六、总结 #
优先级要点 #
- 括号最高
- 单目高于双目
- 算术高于关系
- 关系高于逻辑
- 赋值最低
最佳实践 #
- 使用括号明确优先级
- 分解复杂表达式
- 避免依赖记忆
常见陷阱 #
| 表达式 | 实际含义 | 可能意图 |
|---|---|---|
| a & b == c | a & (b == c) | (a & b) == c |
| a << b + c | a << (b + c) | (a << b) + c |
| a < b < c | (a < b) < c | (a < b) && (b < c) |
下一步,让我们学习控制流!
最后更新:2026-03-26