プログラミング リファレンス - C 演算子の優先順位

次の表に、C 演算子の優先順位と結合性を示します。演算子は上から下の順に優先順位が低くなります。

優先順位

オペレーター

説明

結合性

1

++ --

接尾辞/接尾辞のインクリメントとデクリメント

左から右へ

()

関数呼び出し

[]

配列の添字付け

構造体と共用体のメンバーへのアクセス

->

ポインタを介した構造体および共用体のメンバーへのアクセス

(タイプ){リスト}

複合リテラル(C99)

2

++ --

プレフィックスのインクリメントとデクリメント

右から左に

+ -

単項プラスとマイナス

論理 NOT とビットごとの NOT

(タイプ)

キャスト

*

間接化 (逆参照)

&

住所

のサイズ

のサイズ

_アリグノフ

アライメント要件(C11)

3

* / %

乗算、除算、剰余

左から右へ

4

+ -

加減

5

<< >>

ビット単位の左シフトと右シフト

6

< <=

関係演算子 < と ≤ の場合

> >=

関係演算子 > と ≥ の場合

7

== !=

関係 = と ≠ の場合はそれぞれ

8

&

ビットごとの AND

9

^

ビットごとの XOR (排他的論理和)

10

|

ビット単位の OR (包含的 OR)

11

&&

論理積

12

||

論理和

13

?:

3項条件

右から左に

14

=

単純な割り当て

+= -=

和と差による代入

*= /= %=

積、商、余りによる代入

<<= >>=

ビット単位の左シフトと右シフトによる代入

&= ^= |=

ビット単位の AND、XOR、OR による代入

15

コンマ

左から右へ

述べる:

  1. ++ および -- の接頭辞が付いたオペランドは型変換できません。このルールは構文的に、意味的に無効な一部の式を許可しません。一部のコンパイラはこのルールを無視し、その無効性を意味的にチェックします。

    (プレフィックス++と--のオペランドは型キャストできません。このルールは文法的に、意味的に無効となる一部の表現を禁止します。一部のコンパイラはこの規則を無視し、意味的に無効性を検出します。)

  2. sizeof 的操作数不能是类型转换:表达式 sizeof (int) * p 可以明确地解释为 (sizeof(int)) * p,但不能解释为 sizeof((int)*p) 。* 而不是 sizeof((int)*p)。 (The operand of sizeof can't be a type cast: the expression sizeof (int) * p is unambiguously interpreted as (sizeof(int)) * p, but not sizeof((int)*p).)

  3. 条件运算符中间(?和:之间)的表达式被当作括号来解析:它相对于?:的优先级被忽略。(The expression in the middle of the conditional operator (between ? and :) is parsed as if parenthesized: its precedence relative to ?: is ignored.)

  4. 赋值运算符的左操作数必须是一元表达式(第二级运算符,不包括cast运算符)。这条规则在语法上禁止了一些在语义上无效的表达式。许多编译器会忽略这条规则,而从语义上检测其无效性。例如,e = a < d ? a++ : a = d 就是一个因该规则而无法解析的表达式。然而,许多编译器会忽略这条规则,将其解析为 e = ( ((a < d) ? (a++) : a) = d ),然后给出一个错误,因为它在语义上是无效的。

    (Assignment operators' left operands must be unary (level-2 non-cast) expressions. This rule grammatically forbids some expressions that would be semantically invalid anyway. Many compilers ignore this rule and detect the invalidity semantically. For example, e = a < d ? a++ : a = d is an expression that cannot be parsed because of this rule. However, many compilers ignore this rule and parse it as e = ( ((a < d) ? (a++) : a) = d ), and then give an error because it is semantically invalid.)

在解析表达式时,列在某一行的运算符将比列在其下一行的运算符与其参数绑定得更紧(就像用括号绑定一样)。例如,表达式 *p++ 将被解析为 *(p++),而不是 (*p)++。

(When parsing an expression, an operator which is listed on some row will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it. For example, the expression *p++ is parsed as *(p++), and not as (*p)++.)

同一单元格中的运算符(一个单元格中可能列出多行运算符)按给定的方向以相同的优先级进行运算。例如,表达式 a=b=c 被解析为 a=(b=c),而不是 (a=b)=c,这是因为从右到左的关联性。

(Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression a=b=c is parsed as a=(b=c), and not as (a=b)=c because of right-to-left associativity.)

说明(Notes)

优先级和关联性与计算顺序无关。(Precedence and associativity are independent from order of evaluation.)

标准本身并没有规定优先级。它们是从语法中派生出来的。(The standard itself doesn't specify precedence levels. They are derived from the grammar.)

在 C++ 中,条件运算符( conditional operator,即a?b:c )的优先级与赋值运算符相同,前缀 ++,-- 和赋值运算符对操作数没有限制。(In C++, the conditional operator has the same precedence as assignment operators, and prefix ++ and -- and assignment operators don't have the restrictions about their operands.)

关联性规范对于一元操作符来说是多余的,只是为了完整起见才显示出来:一元前缀操作符总是从右向左关联(sizeof ++*p 就是 sizeof(++(*p))),而一元后缀操作符总是从左向右关联(a[1][2]++ 是 ((a[1])[2])++ )。请注意,关联性对于成员访问运算符是有意义的,即使它们与一元后缀运算符组合在一起:a.b++ 被解析为 (a.b)++ 而不是 a.(b++)。

(Associativity specification is redundant for unary operators and is only shown for completeness: unary prefix operators always associate right-to-left (sizeof ++*p is sizeof(++(*p))) and unary postfix operators always associate left-to-right (a[1][2]++ is ((a[1])[2])++). Note that the associativity is meaningful for member access operators, even though they are grouped with unary postfix operators: a.b++ is parsed (a.b)++ and not a.(b++).)

常用运算符

Common operators

assignment

increment

decrement

arithmetic

logical

comparison

member

access

other

a = b

a += b

a -= b

a *= b

a /= b

a %= b

a &= b

a |= b

a ^= b

a <<= b

a >>= b

++a

--a

a++

a--

+a

-a

a + b

a - b

a * b

a / b

a % b

~a

a & b

a | b

a ^ b

a << b

a >> b

!a

a && b

a || b

a == b

a != b

a < b

a > b

a <= b

a >= b

a[b]

*a

&a

a->b

a.b

a(...)

a, b

(type) a

a ? b : c

sizeof

_Alignof

(since C11)

References

* C17 standard (ISO/IEC 9899:2018):

* A.2.1 Expressions

* C11 standard (ISO/IEC 9899:2011):

* A.2.1 Expressions

* C99 standard (ISO/IEC 9899:1999):

* A.2.1 Expressions

* C89/C90 standard (ISO/IEC 9899:1990):

* A.1.2.1 Expressions

参考:

1,C Operator Precedence

C Operator Precedence - cppreference.com

おすすめ

転載: blog.csdn.net/guoqx/article/details/132575095