
C言語のきほん|優先順位の総まとめ
迷ったらカッコ!優先順位と結合規則を“安全に使いこなす”総まとめで、条件式と計算式が読みやすくなるよ。
演算子の優先順位と結合規則は、覚え始めるとちょっと情報量が多く感じます。でも安心してね。実務でも学習でも、完璧に暗記するより「よく出るパターンを確実に読む」ほうが大事です。
この総まとめでは、
- カッコで優先順位を明示する理由
- 読みにくい式を読みやすくする書き換え
- 確認問題で理解を固める
- コンマ演算子(,)の正体と、区切りのカンマとの違い
を、セットで整理していきます。
丸括弧で優先順位を明示する
カッコは「計算順序の指定」と「読みやすさアップ」の両方に効く
たとえば、次の式は * が + より先に計算されます。
int result = 2 + 3 * 4;
でも「先に足したい」なら、丸括弧で意図を固定できます。
int result = (2 + 3) * 4;
計算の流れはこうです。
(2 + 3) = 5
5 * 4 = 20
サンプルプログラム:買い物の合計
ファイル名:6_11_1.c
#include <stdio.h>
int main(void)
{
int snack = 2;
int add = 3;
int packs = 4;
int total1 = snack + add * packs; /* 掛け算が先 */
int total2 = (snack + add) * packs; /* 足し算を先にしたい */
printf("カッコなしの計算結果: %d\n", total1);
printf("カッコありの計算結果: %d\n", total2);
printf("メッセージ: カッコは意図を固定する便利アイテムだよ。\n");
return 0;
}条件式こそカッコで読みやすくする
&& と || が混ざると、人間の目がつまずきやすい
次の式は、ルール上は && が || より優先なので、先に && が評価されます。
if (a < b && b < c || a == c) {
/* ... */
}
動きとしては問題なくても、「ぱっと見で意図が伝わりにくい」ことがあります。
そこで、読み手に意図を伝えるためにカッコを付けます。
if ((a < b && b < c) || a == c) {
/* ... */
}
“読みやすさのためのカッコ”は良い習慣
カッコは、コンパイラのためというより 人間のため に付けることが多いです。
数年後の自分にも効きます。
結合規則のおさらい(同じ強さが並んだときの順番)
| 種類 | 例 | どっち向き? | イメージ |
|---|---|---|---|
| 左結合が多い | 10 - 5 + 2 | 左→右 | (10 - 5) + 2 |
| 代入は右結合 | a = b = c = 5 | 右→左 | c=5 → b=c → a=b |
「同じ優先順位の演算子が連続したら、どっちから評価するか」を決めるのが結合規則です。
確認問題:6章チェック
○か×を付けてください。
① int a = 7, b = 2; double x = a / b; のとき、x は 3.5 になる。
② a % b は、整数に対してのみ使える。
③ a / 0 は実行時エラーになるが、a % 0 は問題なく動く。
④ 単項 - は値の符号を反転させる演算子である。
⑤ double x = (double)(3 / 2); のとき、x は 1.5 になる。
⑥ (double)3 / 2 は、浮動小数点の割り算になり 1.5 を得られる。
⑦ キャストは演算のために一時的に型を変えるだけで、変数の型そのものは変わらない。
⑧ a と b が int のとき、(double)a / b と (double)(a / b) は同じ結果になる。
⑨ 丸括弧は、演算子の優先順位を強制的に変えられる。
⑩ コンマ演算子は、左から順に式を評価し、最後の式の値を全体の値として返す。
解答と解説
① ×
a / b は int 同士なので整数除算です。7 / 2 は 3 になり、x には 3.0 が入ります。3.5 が欲しいなら (double)a / b のように計算前に型を変えます。
② ○
% は剰余なので整数専用です。浮動小数点には使えません。
③ ×
a / 0 も a % 0 も、0で割るので実行時エラーになり得ます。クラッシュの原因になります。
④ ○
単項 - は符号反転です。a が正なら負に、負なら正にします。
⑤ ×
3 / 2 が先に int で計算されて 1 になり、そのあと double 化されるので 1.0 になります。1.5 にはなりません。
⑥ ○
(double)3 / 2 は 3 が double 扱いになり、全体が浮動小数点の割り算になります。結果は 1.5 です。
⑦ ○
キャストは一時的な変換です。変数そのものの型が永久に変わるわけではありません。
⑧ ×
(double)a / b は小数が出ますが、(double)(a / b) は先に整数除算して手遅れになります。結果が変わることが多いです。
⑨ ○
丸括弧で計算順序を明示でき、優先順位に関係なく先に計算させられます。
⑩ ○
コンマ演算子は左から評価し、最後の式の値が全体の値になります。
解説補足:コンマ演算子(,)は「区切り」じゃないことがある
コンマはいつも区切りに見えますが、C言語には コンマ演算子 という別物があります。
見分け方は、「式として使って値を返しているかどうか」です。
コンマ演算子の特徴
- 左から順に評価する
- 最後の式の値を返す
例1:1行で複数の代入をして、最後の値を使う
ファイル名:6_11_2.c
#include <stdio.h>
int main(void)
{
int x = 1, y = 2, z;
z = (x = 8, y = 9); /* 最後の式 y=9 の値(9)がzに入る */
printf("x=%d, y=%d, z=%d\n", x, y, z);
printf("メッセージ: コンマ演算子は最後の式の値を返すよ。\n");
return 0;
}この実行後は x=8, y=9, z=9 になります。
例2:for の中でよく見るコンマ(区切りと演算子が混ざる)
for の初期化部や更新部では、複数の式を書きたいのでコンマがよく出ます。
ファイル名:6_11_3.c
#include <stdio.h>
int main(void)
{
int i, j;
for (i = 0, j = 5; i <= j; i++, j--)
printf("i=%d, j=%d\n", i, j);
return 0;
}ここでのポイントはこれです。
- for の ( ) の中で i = 0, j = 5 と書けるのは、コンマ演算子として左から評価しているから
- printf の i=%d, j=%d のカンマは、単なる文字列の一部で演算子ではない
- printf の引数を区切るカンマは、ただの区切りであって、コンマ演算子の「最後の値を返す」みたいな意味はありません
注意:コンマ演算子は便利だけど、式が複雑になると読みにくい
1行で色々できてしまうので、やりすぎると自分でも読めなくなることがあります。
学習中は、必要な場面(for の初期化・更新)を中心に使うのがちょうどいいです。
