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。

六、总结 #

优先级要点 #

  1. 括号最高
  2. 单目高于双目
  3. 算术高于关系
  4. 关系高于逻辑
  5. 赋值最低

最佳实践 #

  • 使用括号明确优先级
  • 分解复杂表达式
  • 避免依赖记忆

常见陷阱 #

表达式 实际含义 可能意图
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