C言語

C言語 演算子優先順位 完全ガイド【公式表と比較】

ⓘ本ページはプロモーションが含まれています

スポンサードリンク

演算子優先順位の全体像

C 言語では 「数値が小さいほど高い優先度」 として規格上で定義されています(※実装側はこの相対関係だけを保証し、数値そのものは任意です)。
同じ優先度に属する演算子は 結合規則(Associativity) に従って評価順が決まります。

  • 左結合 (left‑to‑right) : 同レベルの演算子が左から右へ結びつく
  • 右結合 (right‑to‑left) : 同レベルの演算子が右側から先に評価される
  • 非結合 (none) : 後置・前置演算子など、結合方向が定義されないもの

以下の表は規格で明示された 10 個の優先度階層(C11/C17 では同一)を、理解しやすいように「1 が最高」形式で数値化したものです。


公式表

優先度 演算子・構文例(左結合 / 右結合 / 非結合) 説明
1 ()
[]
.
->
後置演算子 – 関数呼び出し、配列添字、構造体・共用体メンバアクセス。
結合規則:左結合
2 ++ (後置)
-- (後置)
(type){...} (複合リテラル)
後置インクリメント/デクリメント、複合リテラル
結合規則:左結合
3 ++ (前置)
-- (前置)
+ (単項正)
- (単項負)
! (論理否定)
~ (ビット NOT)
* (間接参照)
& (アドレス演算子)
sizeof
_Alignof
単項前置演算子
結合規則:右結合
4 *
/
%
乗除算・剰余
左結合
5 +
-
加減算
左結合
6 <<
>>
ビットシフト(左/右)。
左結合
7 <
<=
>
>=
比較演算子 (関係)
左結合
8 ==
!=
等価比較
左結合
9 & (ビット AND) ビット積
左結合
10 ^ (ビット XOR) 排他的論理和
左結合
11 | (ビット OR) ビット和
左結合
12 && 論理 AND
左結合
13 || 論理 OR
左結合
14 ?: (条件演算子) 三項演算子。右側の : があるため 右結合(式全体は単一演算子として扱われる)。
15 =
+=
-=
*=
/=
%=
<<=
>>=
&=
^=
|=
代入演算子
右結合
16 , (カンマ) カンマ演算子(式の評価順序を明示)。
左結合

補足:_Atomic は「型指定子」

C11 で導入された _Atomic型修飾子 であり、演算子ではありません。そのため優先順位表に含める根拠はなく、本表から除外しています。実際の式中で atomic_int a = ATOMIC_VAR_INIT(0); のように使用されても、評価順序には影響しません(規格上は単なる型情報)。


他サイトとの比較と注意点

項目 本表 (公式) Zenn (2025/03) 主な相違点・留意点
優先度番号の付け方 1 が最高、16 が最低(Microsoft Learn と同一) 「1 が最下位」方式を採用し、全体が逆転している 数字は 相対関係 のみ意味がある。実務では「高い⇔低い」の概念で比較すれば問題なし
条件演算子 ?: の位置 14(右結合) 13 と表記(同様に右結合) 表示上の番号違いだけで、評価規則は一致
前置インクリメント・デクリメントの分類 同一レベル (優先度 3) Zenn は「前置 ++/--」を優先度 2 に分離している 規格では 単項前置演算子 とみなすので、同レベルが正しい
カンマ演算子の位置 最低 (16) 同様に最低 完全一致

結論:Zenn の表は見やすさを追求した独自の番号付けであり、相対的な優先度・結合規則は公式と同一です。混乱を防ぐためには「番号」ではなく「高い⇔低い」の概念で比較してください。


評価順序を確認する実例

優先度だけでの解釈 (高→低) 実際の評価順序(結合規則含む) 解説
a + b * c * が 4、+ が 5 → b*c が先に計算 b * ca + (b*c)(左結合) 典型的な「乗算が足し算より高優先度」
*p++ 後置 ++(優先度 2)と間接参照 *(優先度 3) → p++ が先に評価 tmp = p; p = p + 1; result = *tmp; 後置インクリメントが先に実行され、元のポインタ値がデリファレンスされる
func(a, b ? c : d) カンマは最低 (16) → 関数呼び出し全体が一つの式として扱われる 1️⃣ ab ? c : d の評価順序は未規定(C11 6.5.2.2)
2️⃣ 条件演算子は右結合で、先に b が評価され、次に c または d
引数評価の副作用に注意。コンパイラが左→右・右→左どちらでも正しい
x = y = z + 1 + (5) → = (15) が低優先度、かつ右結合 temp = z + 1; y = temp; x = y; 代入が右から左へ行われるので、最終的に xy は同じ値になる
sizeof *p + 1 sizeof (単項前置, 優先度 3)
* (間接参照, 同優先度) → 結合規則は右結合なので sizeof (*p) が先に評価
size = sizeof(*p); result = size + 1; sizeof は式全体を評価しないので、ポインタが無効でも安全

ポイント:優先度だけで「どの演算子が早く実行されるか」は判定できても、結合規則(左/右) が入ると最終的な評価順序が決まります。式を手書きで分解するときは必ず両方を意識してください。


未定義動作・実装依存の落とし穴

1. 後置 ++/-- と間接参照 * の組み合わせ

  • 注意点:同一式内で * と後置インクリメントが混在すると、評価順序は規格で決まっている(後置が先)。しかし 副作用が重なる 場合は可読性が低くバグの温床になるので、別行に分けることを推奨。

2. 符号付き右シフトの実装依存

  • 規格: C11 6.5.7/4 「右シフトの結果は実装依存」
  • 安全策: 符号ビットが重要な場合は必ず unsigned にキャストしてからシフト、または標準ライブラリ (uint32_t) を用いる。

3. 符号付き整数のオーバーフロー

  • 影響: コンパイラは「未定義」領域を最適化で削除でき、結果が全く予測不能になる。
  • 回避法: if (x < INT_MAX) ++x; あるいは広い型 (int64_t) に昇格させてから演算する。

4. カンマ演算子の意図しない評価順序

  • ポイント: カンマは 左結合 であり、左側の式が完全に評価された後に右側へ進む。副作用がある場合は順序を明示的に書くべき。

実務向けチェックリスト & チートシート

1. 演算子優先順位チェックリスト

# 確認項目 詳細
高優先度演算子が低優先度演算子に埋もれていないか * / %+ - の前に来ているか
結合規則の正しい適用 同一レベルで左結合か右結合かを式ごとに手書きで確認
後置・前置インクリメント/デクリメントが *[] と混在していないか 例: *p++ は OK、*++p-- のような複合は可読性低 → 分割
ビットシフトの符号付き使用 必要なら必ず unsigned にキャスト
条件演算子 ?: 内で副作用が無いか 例: a = (b++ ? c : d) は評価順序依存 → 別行に分割
カンマ演算子の意図的使用 カンマは「式列」の意味しか持たない。for 文以外での多用は避ける
代入チェーンが右結合であることを踏まえているか x = y = z;y = z; x = y; と等価

2. 印刷可能チートシート(PDF)

  • 入手先:Microsoft Learn の「Operator precedence」ページの右上にある Print friendly リンク[^1]。
  • 推奨活用法
  • デスクトップ横に貼って常時参照
  • IDE のサイドバーに画像として保存し、コード補完と併せて閲覧

3. サンプルコード集(GitHub Gist)

  • 備考:実行結果はコンパイラの最適化設定に左右されないよう、volatile を付与すると安全です。

参考文献・出典

  1. Microsoft Learn – C language: Operator precedence
    https://learn.microsoft.com/ja-jp/cpp/c-language/operator-precedence?view=msvc-170(閲覧日:2026‑04‑19)
  2. ISO/IEC 9899:2011 (C11) – 第 6.5 節「式」および付属の優先順位表。
  3. ISO/IEC 9899:2018 (C17) – 同上、変更点は _Atomic の型修飾子追加のみ(演算子優先度は不変)。
  4. Zenn記事 – 「C言語 演算子優先順位まとめ」(2025‑03) – 本稿で比較対象として使用。
  5. Sejuku・Tech Blog – 「C の未定義動作まとめ」(2023) – 未定義・実装依存例の解説に参照。

まとめ

  • C の演算子優先順位は 10 段階の相対関係結合規則 によって決まります。
  • _Atomic は型修飾子であり、優先順位表に含めるべきではありません。
  • 他媒体(Zenn 等)の番号付けは見やすさ重視の独自表記であり、相対的な高低と結合規則が公式と一致しているか を確認すれば問題ありません。
  • 実務では「高優先度 ⇔ 低優先度」の概念を頭に入れ、チェックリストとチートシートを活用することで、演算子関連バグの発生率を大幅に削減できます。

本稿は2026 年 4 月時点の最新情報に基づいています。規格改訂や実装変更があった場合は、公式ドキュメントをご確認ください。

スポンサードリンク

-C言語