C Operator Precedence
C 运算符优先级
下表列出了 C 运算符的优先级和关联性。运营商从上到下排列,优先级递减。
Precedence | Operator | Description | Associativity |
---|---|---|---|
1 | ++ -- | Suffix/postfix increment and decrement | Left-to-right |
() | Function call | ||
[] | Array subscripting | ||
. | Structure and union member access | ||
-> | Structure and union member access through pointer | ||
(type){list} | Compound literal(C99) | ||
2 | ++ -- | Prefix increment and decrement | Right-to-left |
- | Unary plus and minus | ||
! ~ | Logical NOT and bitwise NOT | ||
(type) | Type cast | ||
* | Indirection (dereference) | ||
& | Address-of | ||
sizeof | Size-of | ||
_Alignof | Alignment requirement(C11) | ||
3 | * / % | Multiplication, division, and remainder | Left-to-right |
4 | - | Addition and subtraction | |
5 | << >> | Bitwise left shift and right shift | |
6 | < <= | For relational operators < and ≤ respectively | |
= | For relational operators > and ≥ respectively | ||
7 | == != | For relational = and ≠ respectively | |
8 | & | Bitwise AND | |
9 | ^ | Bitwise XOR (exclusive or) | |
10 | | | Bitwise OR (inclusive or) | |
11 | && | Logical AND | |
12 | || | Logical OR | |
13note 1 | ?: | Ternary conditionalnote 2 | Right-to-Left |
14 | = | Simple assignment | |
+= -= | Assignment by sum and difference | ||
*= /= %= | Assignment by product, quotient, and remainder | ||
<<= >>= | Assignment by bitwise left shift and right shift | ||
&= ^= |= | Assignment by bitwise AND, XOR, and OR | ||
15 | , | Comma | Left-to-right |
- 虚构的优先级别,请参阅下面的注释
解析表达式时,某行上列出的运算符将被绑定得比它下面一行中列出的任何运算符更紧密(就像通过括号一样)。例如,表达式*p++
被解析为*(p++)
,而不是(*p)++
。
位于同一单元格中的运算符(单元格中列出的可能有多行运算符)在给定方向上以相同的优先级进行评估。例如,表达式a=b=c
被解析为a=(b=c)
,而不是(a=b)=c
由于从右到左的关联性。
笔记
优先级和关联性与评估顺序无关。
Ct语言标准没有指定运算符优先级。它指定语言语法,并从中派生优先级表以简化理解。有一部分语法不能用优先表来表示:赋值表达式不允许作为条件运算符的右手操作数,所以e = a < d ? a++ : a = d是不能被解析的表达式,因此是条件和赋值的相对优先级运营商不容易描述。
但是,许多 C 编译器使用非标准表达式语法,其中?:指定更高的优先级=,因为它解析该表达式e = ( ((a < d) ? (a++) : a) = d ),然后由于语义限制而无法编译:?:从不是左值,并且=需要在左边有可修改的左值。这是在此页面上呈现的表格。
请注意,这在 C ++中是不同的,其中条件运算符具有与赋值相同的优先级。
一元运算符的关联性规范是多余的,并且只显示完整性:一元前缀运算符总是从右到左(sizeof ++*p
是sizeof(++(*p))
)和一元后缀运算符总是从左到右(a[1][2]++
是((a[1])[2])++
)相关联。请注意,关联性对于成员访问操作符是有意义的,即使它们与一元后缀操作符分组在一起:a.b++
被解析(a.b)++
而不是a.(b++)
。
参考
- C11 standard (ISO/IEC 9899:2011):