计算的优先级和顺序Precedence and Order of Evaluation

C 运算符的优先级和结合性将影响表达式中操作数的分组和计算。The precedence and associativity of C operators affect the grouping and evaluation of operands in expressions. 仅当存在优先级较高或较低的其他运算符时,运算符的优先级才有意义。An operator's precedence is meaningful only if other operators with higher or lower precedence are present. 首先计算带优先级较高的运算符的表达式。Expressions with higher-precedence operators are evaluated first. 也可以通过“绑定”一词描述优先级。Precedence can also be described by the word "binding." 优先级较高的运算符被认为具有更严格的绑定。Operators with a higher precedence are said to have tighter binding.

下表总结了 C 运算符的优先级和结合性(计算操作数的顺序),并按照从最高优先级到最低优先级的顺序将其列出。The following table summarizes the precedence and associativity (the order in which the operands are evaluated) of C operators, listing them in order of precedence from highest to lowest. 如果几个运算符一起出现,则其具有相同的优先级并且将根据其结合性对其进行计算。Where several operators appear together, they have equal precedence and are evaluated according to their associativity. 后缀运算符开头的部分描述了表中的运算符。The operators in the table are described in the sections beginning with Postfix Operators. 此部分的其余部分提供了有关优先级和结合性的常规信息。The rest of this section gives general information about precedence and associativity.

C 运算符的优先级和结合性Precedence and Associativity of C Operators

Symbol1Symbol1 运算类型Type of Operation 结合性Associativity
. -> 后缀 ++ 和后缀 -- . -> postfix ++ and postfix -- ExpressionExpression 从左到右Left to right
前缀 ++ 和前缀 -- sizeof & * + - ~ !prefix ++ and prefix -- sizeof & * + - ~ ! 一元Unary 从右到左Right to left
typecaststypecasts 一元Unary 从右到左Right to left
* / %* / % 乘法Multiplicative 从左到右Left to right
+ -+ - 加法Additive 从左到右Left to right
<< >> 按位移动Bitwise shift 从左到右Left to right
< > <= >=< > <= >= 关系Relational 从左到右Left to right
== !=== != 相等Equality 从左到右Left to right
& 按位“与”Bitwise-AND 从左到右Left to right
^ 按位“异或”Bitwise-exclusive-OR 从左到右Left to right
|| 按位“与或” Bitwise-inclusive-OR
&& 逻辑“与”Logical-AND 从左到右Left to right
&#124;&#124; 逻辑“或”Logical-OR 从左到右Left to right
? :? : 条件表达式Conditional-expression 从右到左Right to left
= *= /= %== *= /= %=

+= -= <<= >>=&=+= -= <<= >>=&=

^= |=^= |=
简单和复合 assignment2Simple and compound assignment2 从右到左Right to left
, 顺序计算Sequential evaluation 从左到右Left to right
  1. 运算符按优先级的降序顺序列出。Operators are listed in descending order of precedence. 如果多个运算符出现在同一行或一个组中,则它们具有相同的优先级。If several operators appear on the same line or in a group, they have equal precedence.

  2. 所有简单的和复合的赋值运算符都有相同的优先级。All simple and compound-assignment operators have equal precedence.

    表达式可以包含优先级相同的多个运算符。An expression can contain several operators with equal precedence. 当多个具有相同级别的这类运算符出现在表达式中时,计算将根据该运算符的结合性按从右到左或从左至右的顺序来执行。When several such operators appear at the same level in an expression, evaluation proceeds according to the associativity of the operator, either from right to left or from left to right. 计算的方向不影响在相同级别包括多个乘法 (\)、加法 (+) 或二进制按位 (& | ^) 运算符的表达式结果。The direction of evaluation does not affect the results of expressions that include more than one multiplication (**), addition (+), or binary-bitwise (& | ^**) operator at the same level. 语言未定义运算的顺序。Order of operations is not defined by the language. 如果编译器可以保证一致的结果,则编译器可以按任意顺序随意计算此类表达式。The compiler is free to evaluate such expressions in any order, if the compiler can guarantee a consistent result.

    只有顺序计算()、逻辑“与”(&&)、逻辑“或” (||)、条件表达式 (? :) 和函数调用运算符构成序列点,因此,确保对其操作数的计算采用特定顺序。Only the sequential-evaluation (,), logical-AND (&&), logical-OR (||), conditional-expression (? :), and function-call operators constitute sequence points and therefore guarantee a particular order of evaluation for their operands. 函数调用运算符是一组紧跟函数标识符的圆括号。The function-call operator is the set of parentheses following the function identifier. 确保顺序计算运算符 (,) 按从左到右的顺序计算其操作数。The sequential-evaluation operator (,) is guaranteed to evaluate its operands from left to right. (请注意,函数调用中的逗号运算符与顺序计算运算符不同,且不提供任何此类保证。)有关详细信息,请参阅序列点(Note that the comma operator in a function call is not the same as the sequential-evaluation operator and does not provide any such guarantee.) For more information, see Sequence Points.

    逻辑运算符还确保按从左至右的顺序计算操作数。Logical operators also guarantee evaluation of their operands from left to right. 但是,它们会计算确定表达式结果所需的最小数目的操作数。However, they evaluate the smallest number of operands needed to determine the result of the expression. 这称作“短路”计算。This is called "short-circuit" evaluation. 因此,无法计算表达式的一些操作数。Thus, some operands of the expression may not be evaluated. 例如,在下面的表达式中For example, in the expression

x && y++  

仅当 y++ 为 true(非零)时,才计算第二操作数 (x)。the second operand, y++, is evaluated only if x is true (nonzero). 因此,如果 y 为 false (0),则 x 不增加。Thus, y is not incremented if x is false (0).

示例Examples

以下列表显示编译器如何自动绑定多个示例表达式:The following list shows how the compiler automatically binds several sample expressions:

ExpressionExpression 自动绑定Automatic Binding
a & b &#124;&#124; c (a & b) &#124;&#124; c
a = b &#124;&#124; c a = (b &#124;&#124; c)
q && r &#124;&#124; s-- (q && r) &#124;&#124; s--

在第一个表达式中,按位“与”运算符 (&) 的优先级高于逻辑“或”运算符 (||) 的优先级,因此,a & b 构成了逻辑“或”运算的第一操作数。In the first expression, the bitwise-AND operator (&) has higher precedence than the logical-OR operator (||), so a & b forms the first operand of the logical-OR operation.

在第二个表达式中,逻辑“或”运算符 (||) 的优先级高于简单赋值运算符 (=) 的优先级,因此,b || c 在赋值中分组为右操作数。In the second expression, the logical-OR operator (||) has higher precedence than the simple-assignment operator (=), so b || c is grouped as the right-hand operand in the assignment. 请注意,赋给 a 的值为 0 或 1。Note that the value assigned to a is either 0 or 1.

第三个表达式显示可能会生成意外结果的格式正确的表达式。The third expression shows a correctly formed expression that may produce an unexpected result. 逻辑“与”运算符 (&&) 的优先级高于逻辑“或”运算符 (||) 的优先级,因此,将 q && r 分组为操作数。The logical-AND operator (&&) has higher precedence than the logical-OR operator (||), so q && r is grouped as an operand. 由于逻辑运算符确保按从左到右的顺序计算操作数,因此 q && r 先于 s-- 被计算。Since the logical operators guarantee evaluation of operands from left to right, q && r is evaluated before s--. 但是,如果 q && r 计算的结果为非零值,则不计算 s--,并且 s 不会减少。However, if q && r evaluates to a nonzero value, s-- is not evaluated, and s is not decremented. 如果 s 未减少会导致程序出现问题,则 s-- 应显示为表达式的第一操作数,或者在单独的运算中应减少 sIf not decrementing s would cause a problem in your program, s-- should appear as the first operand of the expression, or s should be decremented in a separate operation.

以下表达式是非法的并会在编译时生成诊断消息:The following expression is illegal and produces a diagnostic message at compile time:

非法表达式Illegal Expression 默认分组Default Grouping
p == 0 ? p += 1: p += 2 ( p == 0 ? p += 1 : p ) += 2

在此表达式中,相等运算符 (==) 的优先级最高,因此,将 p == 0 分组为操作数。In this expression, the equality operator (==) has the highest precedence, so p == 0 is grouped as an operand. 条件表达式运算符 (? :) 具有下一个最高级别的优先级。The conditional-expression operator (? :) has the next-highest precedence. 其第一操作数是 p == 0,第二操作数是 p += 1Its first operand is p == 0, and its second operand is p += 1. 但是,条件表达式运算符的最后一个操作数被视为 p 而不是 p += 2,因为与复合赋值运算符相比,p 的匹配项将更紧密地绑定到条件表达式运算符。However, the last operand of the conditional-expression operator is considered to be p rather than p += 2, since this occurrence of p binds more closely to the conditional-expression operator than it does to the compound-assignment operator. 由于 += 2 没有左操作数,因此发生语法错误。A syntax error occurs because += 2 does not have a left-hand operand. 您应使用括号以防止此类错误发生并生成可读性更高的代码。You should use parentheses to prevent errors of this kind and produce more readable code. 例如,可以按如下所示使用括号来更正和阐明前面的示例:For example, you could use parentheses as shown below to correct and clarify the preceding example:

( p == 0 ) ? ( p += 1 ) : ( p += 2 )  

另请参阅See Also

C 运算符C Operators