優先順位 と結合順序 という 2 つの 演算子の特性によって、オペランドが演算子とグループ化される方法が決まります。 優先順位は、型が異なる演算子をオペランドとグループ化させるときの優先順位です。 結合順序は、オペランドを、同じ優先順位の演算子にグループ化するときの左から右、 または右から左の順序です。 演算子の優先順位は、より高いまたは低い優先順位の他の演算子がある場合にのみ、意味があります。 より高い優先順位の演算子を持つ式が、最初に評価されます。 小括弧を使用して、強制的にオペランドをグループ化することができます。
例えば、次のステートメントでは、値 5 は、= 演算子の 右から左への結合順序を使用して 、a と b の両方に代入されます。最初に値 c が b に代入され、 次に値 b が a に代入されます。
b = 9; c = 5; a = b = c;
副次式の評価順序が指定されていないので、小括弧を使用して、 演算子付きのオペランドのグループ化を明示的に強制することができます。
次の式では、
a + b * c / d
優先順位により、+ 演算の前に、* および / 演算が実行されます。 結合順序により、b は d によって除算される前に、c と乗算されます。
次の表に、C および C++ 言語の演算子を優先順位の順序でリストし、 各演算子の結合順序の方向を示します。
C++ スコープ・レゾリューション演算子 (::)
には、最も高い優先順位が付けられています。
コンマ演算子には、最も低い優先順位が付けられます。
同位にある演算子には、同じ優先順位が付けられています。
C および C++ 演算子の優先順位と結合順序 | |||
ランク | 右結合 ? | 演算子関数 | 使用法 |
---|---|---|---|
1 | はい |
![]() | :: name_or_qualified name |
1 |
|
![]() | class_or_namespace :: member |
2 |
| メンバー選択 | object . member |
2 |
| メンバー選択 | pointer -> member |
2 |
| 添え字 | pointer [ expr ] |
2 |
| 関数呼び出し | expr ( expr_list ) |
2 |
| 値生成 | type ( expr_list ) |
2 |
| 後置増分 | lvalue ++ |
2 |
| 後置減分 | lvalue -- |
2 | はい |
![]() | typeid ( type ) |
2 | はい |
![]() | typeid ( expr ) |
2 | はい |
![]() | static_cast < type > ( expr ) |
2 | はい |
![]() | dynamic_cast < type > ( expr ) |
2 | はい |
![]() | reinterpret_cast < type > ( expr ) |
2 | はい |
![]() | const_cast < type > ( expr ) |
3 | はい | オブジェクトのサイズ (バイト) | sizeof expr |
3 | はい | 型のサイズ (バイト) | sizeof ( type ) |
3 | はい | 接頭部増分 | ++ lvalue |
3 | はい | 接頭部減分 | -- lvalue |
3 | はい | ビット単位否定 | ~ expr |
3 | はい | 否定 | ! expr |
3 | はい | 単項負 | - expr |
3 | はい | 単項正 | + expr |
3 | はい | 〜のアドレス | & lvalue |
3 | はい | 間接または間接参照 | * expr |
3 | はい |
![]() | new type |
3 | はい |
![]() | new type ( expr_list ) type |
3 | はい |
![]() | new type ( expr_list ) type ( expr_list ) |
3 | はい |
![]() | delete pointer |
3 | はい |
![]() | delete [ ] pointer |
3 | はい | 型変換 (キャスト) | ( type ) expr |
4 |
| メンバー選択 | object .* ptr_to_member |
4 |
| メンバー選択 | object ->* ptr_to_member |
5 |
| 乗算 | expr * expr |
5 |
| 除法 | expr / expr |
5 |
| モジュロ (剰余) | expr % expr |
6 |
| 2 項加算 | expr + expr |
6 |
| 2 項減算 | expr - expr |
7 |
| 左へのビット単位シフト | expr << expr |
7 |
| 右へのビット単位シフト | expr >> expr |
8 |
| より小さい | expr < expr |
8 |
| より小さいまたは等しい | expr <= expr |
8 |
| より大きい | expr > expr |
8 |
| より大きいまたは等しい | expr >= expr |
9 |
| 等しい | expr == expr |
9 |
| 等しくない | expr != expr |
10 |
| ビット単位 AND | expr & expr |
11 |
| ビット単位排他 OR | expr ^ expr |
12 |
| ビット単位包含 OR | expr | expr |
13 |
| 論理 AND | expr && expr |
14 |
| 論理包含 OR | expr || expr |
15 |
| 条件式 | expr ? expr : expr |
16 | はい | 単純代入 | lvalue = expr |
16 | はい | 乗算および代入 | lvalue *= expr |
16 | はい | 除法および代入 | lvalue /= expr |
16 | はい | モジュロおよび代入 | lvalue %= expr |
16 | はい | 加算および代入 | lvalue += expr |
16 | はい | 減算および代入 | lvalue -= expr |
16 | はい | 左へのシフトおよび代入 | lvalue <<= expr |
16 | はい | 右へのシフトおよび代入 | lvalue >>= expr |
16 | はい | ビット単位 AND および代入 | lvalue &= expr |
16 | はい | ビット単位排他 OR および代入 | lvalue ^= expr |
16 | はい | ビット単位包含 OR および代入 | lvalue |= expr |
17 | はい |
![]() | throw expr |
18 |
| コンマ (順序付け) | expr , expr |
関数呼び出しの引き数または 2 項演算子のオペランドの評価順序は、指定されていません。 次のようなあいまいな式は作成しないようにしてください。
z = (x * ++y) / func1(y); func2(++i, x[i]);
上記の例では、すべての C 言語インプリメンテーション で、++y と func1(y) が同じ順序で 評価されるとは限りません。最初のステートメントの前に、y に値 1 が指定されている場合は、 値 1 または値 2 が func1() に渡されるかどうかはわかりません。式が評価される前に、2 番目のステートメントで、 i に値 1 が指定されている場合は、 x[1] または x[2] が func2() への 2 番目の引き数として渡されるかどうかはわかりません。
関連参照