🔀 制御構造
🎯 && || ! で複数の条件を組み立てられるようになり、短絡評価の性質を安全のために利用できる
遊園地の乗り物に、こんな看板があります。「身長120cm以上、かつ、大人の同伴がある方」。条件が2つ以上あるとき、日本語の「かつ」「または」「〜でない」をCに翻訳するのが論理演算子です。
&& は「かつ」。両方が真のときだけ真になります。
|| は「または」。どちらかが真なら真になります。
! は「〜でない」。真と偽をひっくり返します。
実際に使ってみましょう。
#include <stdio.h>
int main(void) {
int height = 125;
bool hasTicket = true;
if (height >= 120 && hasTicket) {
printf("ご乗車できます\n");
} else {
printf("ごめんなさい、条件を満たしていません\n");
}
return 0;
}hasTicket を && hasTicket == true と書かなくてよいのは、前のトピックのとおりです。
さて、ここで数学の書き方をそのまま持ち込むと事故ります。「x が 0 以上 100 以下」を、こう書きたくなりませんか。
if (0 <= x <= 100) { // これは常に真!
printf("範囲内です\n");
}コンパイルは通ります。警告すら出ないことがあります。しかしどんな x でも必ず真になります。Cは左から順に処理するので、まず 0 <= x を判定して true(1) か false(0) という値にします。次に残った式が 1 <= 100 か 0 <= 100 になり、どちらも成り立ってしまうのです。正しくはこう書きます。
#include <stdio.h>
int main(void) {
int x = 250;
if (0 <= x && x <= 100) { // 比較はそれぞれ完全な形で
printf("範囲内です\n");
} else {
printf("範囲外です\n");
}
return 0;
}0 <= x <= 100 が通ってしまうのは、比較の結果がまた数値になるからじゃ。Cは律儀に、左から2回比べておるもうひとつ知っておくべき性質が短絡評価です。A && B は、A が偽だと分かった時点で B を評価しません。結果はもう偽で確定しているからです。同じく A || B は A が真なら B を見ません。これは「たまたまそうなる」のではなく、C言語の仕様で保証された動きです。
この性質は、防波堤として使えます。
#include <stdio.h>
int main(void) {
int total = 10;
int count = 0;
if (count != 0 && total / count > 3) { // count が 0 なら右は評価されない
printf("平均は3より大きい\n");
} else {
printf("平均は計算できません\n");
}
return 0;
}count が 0 のとき、total / count は0除算でプログラムが異常終了します。しかし左の count != 0 が偽になった瞬間に判定は打ち切られ、割り算は実行されません。もし左右を入れ替えて total / count > 3 && count != 0 と書いたら、その場でクラッシュします。守りの条件を左に置く——これは後々ポインタを扱うときにも命綱になる書き方です。
最後に細かい注意を2つ。&& は || より先に結合するので、混ぜて使うときはかっこを付けて意図をはっきりさせてください。a || b && c は a || (b && c) です。そして ! は結合が強いので、!a == b は (!a) == b になります。迷ったらかっこ、で構いません。
まとめます。&& は「かつ」、|| は「または」、! は「でない」。範囲は 0 <= x && x <= 100。短絡評価のおかげで、左に守りの条件を置けば右は安全に書ける。
&&=かつ、||=または、!=でない。比較はそれぞれ完全な形で書く0 <= x <= 100 は常に真になる罠。0 <= x && x <= 100 と書く&& の左が偽なら右は評価されない。守りの条件を左に置く+や-、==など、値どうしを計算したり比較したりするための記号のこと。演算子ごとに計算される優先順位があらかじめ決まっている。+ - * / のような算術演算子のほか、比較や論理の演算子も含まれる。
真(true)か偽(false)のどちらかに評価される式のこと。if文やwhile文が「どちらへ進むか」を判断するための材料になる。true/falseで表される真偽値の型(bool)がこの評価結果にあたる。
&&や||で式を評価するとき、左側だけで結果が確定した時点で右側の評価を省略する仕組みのこと。ぬるぽ防止のガード条件などで活用される。if (p != NULL && *p == 1)のように、安全確認とセットで使われることが多い。
true(真)かfalse(偽)のどちらかしか入らない型のこと。C23では標準の書き方としてbool・true・falseがそのまま使えるようになった。従来は0と1で真偽を表していたが、C23の書き方の方が意図が伝わりやすい。
もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。