C言語のbool型の使い方【stdbool.h, true, false, 真偽値】

411, 2022-02-14

目次

C言語のbool型の使い方

C言語では真偽値(true, false)を扱うことができます。
真偽値を表す型を「bool型」と言います。
bool型を使うとC言語で真偽値を扱うことができるようになります。

この記事ではC言語のbool型の使い方を詳しく解説します。

関連記事

真偽値とは?

真偽値(しんぎち)とは、「」か「」を表す値のことです。
英語にすると真は「true」で偽は「false」になります。
整数では「0」が偽で「0以外」が真になります。

真偽値は2つの状態を表すのにプログラミングでよく使われます。
たとえば「成功」と「失敗」、これらの状態はプログラミングで非常によく使います。
真偽値を使うと「成功をtrue」にして「失敗をfalse」にして表現することができます。

このような真偽値を保存できる型を「論理型」と言います。

(^ _ ^)

論理的な型

(・ v ・)

かしこい型だね

bool型を使う

bool型を使うにはヘッダーファイル「stdbool.h」をインクルードします。

#include <stdbool.h>

このヘッダをインクルードすると「bool」と「true」、「false」を使うことができるようになります。

#include <stdio.h>
#include <stdbool.h>

int main(void) {
    bool flag = true;
    printf("%d\n", flag);  // 1

    flag = false;
    printf("%d\n", flag);  // 0

    return 0;
}

↑のようにbool型にはtruefalseを値として保存することができます。
trueは「真」を表す値で、falseは「偽」を表す値です。
たとえば「関数が成功した」というフラグであれば成功したらtrueを使い、失敗したらfalseを使います。

なぜstdbool.hをインクルードするのか?

なぜbool型を使うのに「stdbool.h」をインクルードする必要があるのでしょうか?
素の状態でboolを使えた方が楽に見えます。

C言語は歴史がある言語なので、bool型を導入以前にすでにboolを定義しているプログラマーが多数存在していました。
あくまで1例ですが、彼らはboolを↓のように定義していました。

#include <stdio.h>

// 自作のbool型の定義
typedef enum {
    false,  // 0
    true,  // 1
} bool;

int main(void) {
    bool flag = true;
    printf("%d\n", flag);  // 1

    flag = false;
    printf("%d\n", flag);  // 0

    return 0;
}

↑のようにtypedefを使えば自作のboolを定義できます。
そしてそれは問題なく機能します。
昔のプロジェクト(C99以前)ではこのようなbool型を定義するのも一般的でした。

こういった自作のbool型が定義されているプロジェクトに、突如として標準のbool型が舞い降りたらどうなるでしょうか
結果は既存の自作bool型と標準bool型のコリジョン、衝突です。
衝突の結果、プロジェクトはコンパイルが出来なくなりマネージャーが怒ります。

(^ _ ^)

しゃちょさんも怒る

そうなってしまっては困るので、標準のboolは「stdbool.h」で定義して、必要であればこれをインクルードして使うという感じになりました。

boolの正体

boolの実装は実装依存になっています。
C99以降であれば「_Bool」という型が使えます。
そのためboolはこの_Boolによって定義されている場合が多いです。

「stdbool.h」内の定義の例ですが、↓のような定義になっていることが多いです。

#define bool    _Bool
#define true    1
#define false   0

↑の定義では「bool」はただの「_Bool」への置き換えです。
また「true」は「1」、「false」は「0」への置き換えです。

このように「stdbool.h」の実装は非常にシンプルになっています。
興味がある型は自分の環境の「stdbool.h」を見て見るといいかもしれません。

UNIX系のシステムでは↓のコマンドで「stdbool.h」を検索できます。

$ find /usr -type f | grep stdbool

_Boolとは?

boolの正体は「_Bool」であることが多いとわかりました。
この_BoolC99で追加された新しい型です。
真偽値を扱うための型になります。

_Bool型は値は「0」か「1」しか扱うことができません。
そのため他の「0」と「1」以外の値を_Bool型の変数に入れても値は保持されません。

#include <stdio.h>

int main(void) {
    _Bool flag = 1;

    printf("%d\n", flag);  // 1

    flag = 0;
    printf("%d\n", flag);  // 0

    flag = 2;
    printf("%d\n", flag);  // 1

    flag = -1;
    printf("%d\n", flag);  // 1

    return 0;
}

型名が「_Bool」で変な名前になっていますが、これも既存のboolと衝突しないようにする工夫です。
もしプロジェクトで「_Bool」を使っている人がいたら、それはごめんなさいという感じでしょう。

(^ _ ^)

コリジョンしてごめんね

真偽値とif文

たとえば関数の実行結果が「成功」からあるいは「失敗」か、そのどちらであるかを知りたい時があります。
そういう時は関数にbool型の値を返させます。

そして関数の呼び出し側で関数の返り値をチェックします。

#include <stdio.h>
#include <stdbool.h>

bool func(void) {
    return true;  // 成功した
}

int main(void) {
    bool result = func();
    if (result) {
        puts("成功しました");
    } else {
        puts("失敗しました");
    }

    return 0;
}

↑のコードを実行すると「成功しました」と表示されます。
関数の返り値である「result」のチェックにif文を使っています。
真偽値のチェックでは

if (result == true) {
    ...
}

と書いてもいいですが、これはより一般的には

if (result) {
    ....
}

と書くことが多いです。
また偽(false)であるかチェックする場合は

if (result == false) {
    ...
}

と書いてもいいですが、これは

if (!result) {
    ...
}

と書くことも多いです。
真偽値をif文で扱う場合はこれらのショートコーディングを覚えておくと捗ります。

おわりに

今回はC言語のbool型について解説しました。
C言語のbool型は比較的によく使われる型といえます。
「stdbool.h」をインクルードして使うようにしてください。

(^ _ ^)

真実はいつもtrue

(・ v ・)

ウソはfalseだ



この記事のアンケートを送信する