C言語のきほん|どの演算が先に計算される?

カッコを付ける前にここを確認!C言語の優先順位と結合規則がわかると、式がスラスラ読めるよ。

C言語を書いていると、ひとつの式の中に + や * や == や && が混ざることがよくあります。
そのとき大切なのが、「どれが先に計算されるの?」というルールです。

C言語には、

  • 優先順位:どの演算子が先に計算されるか
  • 結合規則:同じ優先順位が並んだとき、左からか右からか

という2つのルールがあります。
これが分かっていると、式を読んだり直したりするときに迷わなくなりますし、バグも減ります。

優先順位ってなに?

優先順位は、同じ式の中に複数の演算子があるときに「先に計算されるほう」を決めるルールです。
基本は、算数と同じで 掛け算・割り算が足し算・引き算より先です。

たとえば次の式は、

int result = 2 + 3 * 4;

この順で計算されます。

2 + (3 * 4)
2 + 12
14

サンプルプログラム

ファイル名:6_10_1.c

#include <stdio.h>

int main(void)
{
    int base = 2;
    int add = 3;
    int times = 4;

    int total = base + add * times;

    printf("計算結果は%dです。\n", total);
    printf("メッセージ: 掛け算が先に計算されるよ。\n");

    return 0;
}

この total は base + (add * times) と同じ意味になります。

結合規則ってなに?

結合規則は、優先順位が同じ演算子が並んだときに「どっちから計算するか」を決めるルールです。

  • 左結合:左から右へ
  • 右結合:右から左へ

左結合の代表例:+ と -

  • と - は同じ優先順位で、左結合です。だから左から順に計算されます。
int result = 10 - 5 + 2;

計算はこうです。

(10 - 5) + 2
5 + 2
7

サンプルプログラム:買い物の計算

ファイル名:6_10_2.c

#include <stdio.h>

int main(void)
{
    int money = 10;
    int spend = 5;
    int refund = 2;

    int rest = money - spend + refund;

    printf("残りは%dです。\n", rest);
    printf("メッセージ: 同じ優先順位なら左から計算されることが多いよ。\n");

    return 0;
}

右結合の代表例:代入 =

代入は右結合です。だから右から左へ代入されます。

a = b = c = 5;

順番はこうです。

c = 5
b = c
a = b

サンプルプログラム:初期値をまとめて入れる

ファイル名:6_10_3.c

#include <stdio.h>

int main(void)
{
    int x, y, z;

    x = y = z = 7;

    printf("x=%d, y=%d, z=%d\n", x, y, z);
    printf("メッセージ: 代入は右から左へ進むよ。\n");

    return 0;
}

よく使う優先順位を“ざっくり”押さえる

全部を暗記するのは大変なので、まずは「よく出るところ」だけ押さえるのがおすすめです。

ざっくり早見表(頻出セット)

上のほうが強い(先に計算される)です。

強い → 弱い覚え方
()(a + b) * cカッコが最優先
単項(前置++/--, !, キャストなど)++i, !flag, (double)a1つの値に作用
乗除余*, /, %掛け算系
加減+, -足し算系
比較<, <=, >, >=大小
等価==, !=同じ?違う?
論理AND&&かつ
論理OR
代入=, += など代入は弱い側
コンマ,いちばん弱い

※ 文書にある一覧を、学習用に「頻出中心」で並べ替えたイメージです。厳密な完全表は資料の表6-7-1を参照、という位置づけでOKです。

優先順位でつまずきやすい典型パターン

比較と論理演算子が混ざる式

たとえば「点数が 0以上 かつ 100以下」を書くとき、こう書きます。

(score >= 0) && (score <= 100)

括弧がなくても多くの場合は意図通りに動きますが、括弧があると読みやすさが段違いです。
「読めるコード」が正義です。

= と == の混同は優先順位以前に危険

if の条件で

if (x = 1)

みたいに書くと、比較ではなく代入になります。
優先順位を知っていても避けたいミスなので、== を使っているかを目で確認するクセが大切です。

結合規則が効く例をもう一つ(同じ優先順位が連続)

- が連続する例(左結合)

ファイル名:6_10_4.c

#include <stdio.h>

int main(void)
{
    int result = 20 - 3 - 4;

    printf("result=%d\n", result);
    printf("メッセージ: (20 - 3) - 4 の順だよ。\n");

    return 0;
}

左結合なので (20 - 3) - 4 になって、13 になります。

迷ったときの安全策(カッコで意図を固定する)

優先順位や結合規則を理解するのは大事ですが、実務でいちばん効くコツはこれです。

  • 迷ったら括弧を付けて意図を固定する
  • 人が読んで誤解しない形にする

たとえば

  • a + b * c は a + (b * c) だと分かるけど、初学者には一瞬迷うことがある
  • (a + b) * c と書けば誰が見ても一発

この「読みやすさのための括弧」は、むしろ歓迎されます。