条件判定は演算子で行われますが、演算子の結果は全てという状態に変換されてから、最終的な分岐処理の実行に移ります。今回は C言語で重要な真 TRUE と偽 FALSE のお話です。
--
いきなりここに飛んで来ちゃった人は、よろしければ下記からご覧ください。
C言語基礎講座インデックス


  • そもそも真と偽の状態ってなに?
条件判定などの演算子の結果が成立すると真という状態になります。逆に条件が成立しなかったら偽となります。では、そもそも、この真偽ってどういう状態なのでしょうか。少し実験してみましょう。

int num; printf("適当な数値を入力してください。\n"); scanf_s("%d", &num); if (num) { printf("%dは真です。", num); } else { printf("%dは偽です。", num);
}

いきなり if の中に変数だけの状態です。これでエラーにならないのです。演算した結果が真と偽に変換されているので、このように結果だけを if に入れても動作します。では、どういう値を入れたら真と偽に分かれるのでしょうか。

数字の範囲が大きすぎて大変だと思いますので答えを言ってしまいますが、0 の時だけ偽と表示されます。それ以外は全てです。これで分かるとおり、0 が偽で 0 以外が真なのです。これがまず C言語における条件判定の前提となります。


  • TRUE と FALSE の定義
真と偽の状態を表現するための定数名である、真 = TRUE と偽 = FALSE は、元々 C言語では未定義なので、自分で定義をする必要があります。このとき、FALSE は 0 で良いのですが、TRUE をどうしようかと悩みかもしれません。通常は、以下のような定義とします。

#define FALSE 0 #define TRUE !FALSE

ついに使いました。! 否定演算子です。FALSE の反対が TRUE です。否定演算子とは、この TRUE と FALSE を入れ替える動作をしていたのです。!FALSE と書く事で、FALSE が否定された TRUE の値が格納されます。具体的にどういう値が入っているか?それは以下のプログラムを実行すると分かります。

#define FALSE 0 #define TRUE !FALSE void main() { printf("%dが真です。\n", TRUE); printf("%dが偽です。\n", FALSE);
}

VS2022 環境では、1 が真と表示されます。先にも説明したとおり、0 以外が TRUE なので実は 0 以外なら何でも良いのです。私が遙か昔に使っていた太古の C言語では、TRUE は -1 でした。-1 は 2進数で表すと 0b11111111 なので、0b00000000 のビット反転という意味では正しかったのだと思います。これを知ってる人は昭和の時代からのプログラマかも。※ 或いは C言語の歴史に詳しい人とか
※ 原木切り落としのハムを食べた事がありますが、本当に美味しくてビックリします。人数が集まるパーティとかでもてなすと最高です。

  • 判定の仕方と否定演算子
C99 という C言語のバーション以降では、bool という true と false を格納する専用の型が用意されています。その型ではそれぞれ 1 と 0 という値が与えられたので、false を否定すると 1 になります。それ以前では真偽には固定的な数値は存在していませんでした。このような経緯があるため、条件判定で TRUE と比較するのは、多くのプログラマに嫌がられます。
※ 大文字の TRUE / FALSE はユーザー定義定数、小文字の true / false はC言語組み込みの bool 型定数です。
※ 説明が少し遅れましたが真偽はそのときの状態を示しています。

if (Result == TRUE) { printf("正常です。\n"); }

こんな書き方をするとだいたいダメ出しされます。そもそも、最終的に真と偽という状態に変換されてから分岐しているのですから、こういう時は

if (Result) { printf("正常です。\n"); }

と記述するのが C言語的な記述です。どうしても条件判定に演算子を記述したいのであれば、

if (Result != FALSE) { printf("正常です。\n"); }

このように、FALSE と比較するのであればまだ許してもらえるかと思います。ちなみに昔は条件判定式の中で代入しても、何の警告もなかったため、判定しているつもりでうっかり…

if (Result = 1) { printf("正常です。\n"); }

とすると、Result に 1 が代入されて、結果、常に条件判定が 1 = 真となって、正常としか表示されなくなるバグが多発しました。このバグ、作ってしまうと本当に分かりにくくて、思い込みも重なってかなり難儀します。が、今のインテリセンスは、こういう時にバグじゃねぇの?って指摘するという素敵なおじさまになっちゃってます。
VS2022インテリセンスからの指摘
半分余分になりますが、こういうバグを防ぐために古き良きプログラマは書き方として…

if (1 == Result) { printf("正常です。\n"); }

このように、判定する定数を左辺に記述するという手法を採用しました。これだとうっかり == を = と書いてしまっても、
エラーとして確実に指摘される
このようにエラーとして確実に指摘されるようになります。なお、真は成立という意味の他に、正常という意味も持ちます。偽は非成立ですが、他には異常という意味も持ちます。現在の状態を表すような変数を保ちたい場合は、このような意味合いがありますので、なるべくそれに沿って値を使うようにしてください。成立・正常・成功の結果は 真 = TRUE、不成立・異常・失敗の結果は偽 = FALSE ですね。


  • C言語に組み込まれた bool 型
現在のC言語講座では拡張子が cpp になっているので、実際には C++ 相当で動かしています。それもあって、最初から bool 型は int や float 等と同じく、普通に型として使う事が出来ます。bool 変数に格納可能な値は true と false です。自分で定数定義したモノは TRUE / FALSE と大文字で記述していますが、最初から組み込まれた数値としての true / false は小文字で表現されます。そして、true は 1 で、false は 0 と固定となっています。ちょっと試してみます。

void main() { bool result; result = 100; printf("値は%dです。\n", result); }

100 を代入していますが、値の表示結果は 1 となりました。この bool 型には 0 以外を入れると全て true、すなわち 1 に変えてしまうのです。なので、== true と判定しても間違いではなくなりましたが、すいません、私のようなロートルプログラマには大変気持ち悪く感じるので、今後とも出来れば != false と常に false と比較して頂けますと幸いです(汗

なお、bool 型の result に NULL を入れると false になります。以前、NULL は 0 と定義していますが、このように C言語においては 0 は特別な意味を持つ数値なのです。


  • まとめ
  1. そもそも真と偽の状態ってなに?
  2. TRUE と FALSE の定義
  3. 判定の仕方と否定演算子
  4. C言語に組み込まれた bool 型

※ 今回のご紹介は本気でオススメです!生ハムは美味い!!
生ハム切り落とし 500g たっぷり こだわり 訳あり (【A級品】500g)
世界の美味しいがお手頃価格!豊代
※ 家庭で食べるのならこちらをオススメ。味は変わらず手軽な量です。ビールやワインが進む進む!ちょっぴり塩っぱくて香りが豊潤。一言でサイコーです!