🔀 制御構造
🎯 代入 = と比較 == の違いを説明でき、条件式で取り違えたときに何が起きるかを見抜ける
算数で習った「=」は「等しい」という意味でした。C言語の = は「入れる」です。この1文字の食い違いが、C言語で最も有名な事故を生みます。
仕組みから見ていきましょう。
a = 5 は代入です。そして重要なのは、代入した結果、式全体が「代入した値」を持つという点。つまり a = 5 という式そのものの値は 5 です。
a == 5 は比較です。式の値は真か偽になります。
ということは、if (a = 5) はこう読まれます。「a に 5 を入れて、その結果の 5 を条件として見る」。5 は 0 以外なので——常に真です。しかもコンパイルは通ります。
#include <stdio.h>
int main(void) {
int stock = 0;
if (stock = 5) { // 本当は stock == 5 と書きたかった
printf("在庫は5個です\n");
} else {
printf("在庫は5個ではありません\n");
}
printf("stock = %d\n", stock);
return 0;
}在庫は 0 のはずなのに、「在庫は5個です」「stock = 5」と表示されます。判定するだけのつもりが、変数の中身まで書き換えてしまったのです。あとの行で stock を使う処理があれば、そこも全部おかしくなります。バグの発生地点と症状が出る場所が離れるので、原因にたどり着くのに時間がかかる——これが「悲劇」と呼ばれるゆえんです。
= は「入れる」、== は「同じか?」。この1文字の差で、判定が代入にすり替わる。世界中のC書きが一度は通る道じゃ対策は3つあります。
1. コンパイラの警告を有効にする。 gcc や clang なら -Wall を付けるだけで「代入を条件として使っていますよ」と教えてくれます。人間の注意力より、機械のチェックのほうが確実です。
2. 定数を左に置く(ヨーダ記法)。 if (5 == stock) と書いておけば、うっかり = を1つ落として if (5 = stock) としてもコンパイルエラーになります。定数には代入できないからです。読みにくいという意見もありますが、確実に事故を1種類つぶせます。
#include <stdio.h>
int main(void) {
int stock = 0;
if (5 == stock) { // 書き間違えたら即コンパイルエラー
printf("在庫は5個です\n");
} else {
printf("在庫は5個ではありません\n");
}
return 0;
}3. 読み上げる。 if (stock == 5) を「もし stock が 5 と等しいなら」と口に出す。= が1つだと「もし stock に 5 を入れるなら」となり、日本語として明らかにおかしいので気づけます。
最後に、bool型との比較について。真偽値を == true と比べたくなりますが、その必要はありません。
bool isOpen = true;
if (isOpen == true) { /* … */ } // 動くが回りくどい
if (isOpen) { /* … */ } // こう書けばよい条件式はもともと真偽を見る場所なので、bool 変数はそのまま置けます。比較を書かなければ、= と == を間違えようもありません。
まとめます。= は代入、== は比較。代入式の値は代入した値そのもの。if (x = 5) は常に真になり、おまけに x を壊す。警告を有効にして、bool はそのまま書く。
= は代入、== は比較。代入式の値は「代入した値」そのものif (x = 5) は常に真になり、しかも x の中身を書き換えてしまう真(true)か偽(false)のどちらかに評価される式のこと。if文やwhile文が「どちらへ進むか」を判断するための材料になる。true/falseで表される真偽値の型(bool)がこの評価結果にあたる。
+や-、==など、値どうしを計算したり比較したりするための記号のこと。演算子ごとに計算される優先順位があらかじめ決まっている。+ - * / のような算術演算子のほか、比較や論理の演算子も含まれる。
true(真)かfalse(偽)のどちらかしか入らない型のこと。C23では標準の書き方としてbool・true・falseがそのまま使えるようになった。従来は0と1で真偽を表していたが、C23の書き方の方が意図が伝わりやすい。
値を入れておくための名前付きの箱のこと。名前をつけることで中身を自由に出し入れできる、プログラムの記憶場所にあたる。変数名は自由に付けられるが、意味の分かる名前にすると読みやすいコードになる。
もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。