C语言中包含算术、关系、逻辑、赋值等多种类型的运算符,不同运算符在表达式中参与计算的先后顺序由优先级决定,优先级高的运算符会优先被计算,当多个运算符优先级相同时,则按照结合性规则确定计算方向。

C语言运算符优先级总览表
下表按照优先级从高到低的顺序排列了常用C语言运算符,优先级数值越高表示优先级越高:
| 优先级 | 运算符 | 名称 | 结合性 |
|---|---|---|---|
| 1 | () [] -> . | 括号、数组下标、结构体成员访问 | 从左到右 |
| 2 | ! ~ ++ -- + - * & (type) sizeof | 逻辑非、按位取反、自增自减、正负号、指针解引用、取地址、类型转换、长度计算 | 从右到左 |
| 3 | * / % | 乘法、除法、取余 | 从左到右 |
| 4 | + - | 加法、减法 | 从左到右 |
| 5 | << >> | 左移、右移 | 从左到右 |
| 6 | < <= > >= | 关系比较运算符 | 从左到右 |
| 7 | == != | 等于、不等于 | 从左到右 |
| 8 | & | 按位与 | 从左到右 |
| 9 | ^ | 按位异或 | 从左到右 |
| 10 | | | 按位或 | 从左到右 |
| 11 | && | 逻辑与 | 从左到右 |
| 12 | || | 逻辑或 | 从左到右 |
| 13 | ?: | 条件运算符 | 从右到左 |
| 14 | = += -= *= /= %= &= ^= |= <<= >>= | 赋值运算符 | 从右到左 |
| 15 | , | 逗号运算符 | 从左到右 |
优先级与结合性的实际影响
我们可以通过具体的代码示例来理解优先级规则的作用,以下是一段包含多种运算符的C语言代码:
#include <stdio.h>
int main() {
int a = 5, b = 3, c = 2;
// 乘法优先级高于加法,先计算b*c,再和a相加
int result1 = a + b * c;
printf("a + b * c = %dn", result1); // 输出 5 + 3*2 = 11
// 自增运算符优先级高于乘法,先计算++a,再乘以b
a = 5;
int result2 = ++a * b;
printf("++a * b = %dn", result2); // a先自增为6,6*3=18
// 赋值运算符优先级较低,先计算右侧表达式,再赋值给变量
int d;
d = a + b * c; // 先算b*c=6,再算a+6=12,最后赋值给d
printf("d = a + b * c = %dn", d);
// 逻辑与优先级高于逻辑或,先计算a>0 && b>0,再和c>0做逻辑或
int result3 = a > 0 && b > 0 || c > 0;
printf("a>0 && b>0 || c>0 = %dn", result3); // 结果为1(真)
return 0;
}
容易混淆的优先级场景
有一些运算符的优先级容易让用户产生误解,需要特别注意:
==(等于)的优先级高于&&(逻辑与)和||(逻辑或),比如a == 1 && b == 2会先比较a和1、b和2,再做逻辑与运算,符合多数人的预期。sizeof是运算符不是函数,它的优先级很高,sizeof a + b会先计算sizeof a,再加上b,而不是计算sizeof (a + b)。- 按位运算符(&、^、|)的优先级低于关系运算符,
a & 0x0f == 0会先比较0x0f == 0,再做按位与,这通常不符合预期,需要写成(a & 0x0f) == 0。
实际编写表达式的建议
虽然记住优先级规则很重要,但在实际编写代码时,不建议过度依赖优先级记忆,对于复杂的表达式,最好使用括号明确运算顺序,这样既能避免出错,也能让代码可读性更高。比如(a + b) * c比a + b * c在需要优先计算加法时更清晰,即使后者符合优先级规则,括号也能让其他阅读代码的人快速理解运算逻辑。
注意:C语言标准没有规定所有运算符的优先级,部分不常用的运算符优先级需要参考对应标准文档,日常开发中常用的运算符优先级掌握上述表格内容即可满足大部分需求。