9章 ブール数



9.1:
ブール値をC言語で扱うのに適切なデータ型は? なぜブール値を扱う データ型が、標準で用意されていないのか。真と偽をあらわすのに、 #defineを使うべきか列挙型を使うべきか。

A:
C言語は標準のブール型を用意していない。ブール型のデータ型を選 ぶことは空間と時間を天秤にかけることである。どちらを選択するか はプログラマーにまかせるのが一番である(intをブール型に選べば速 いだろうし、charをブール型に選べばデータの保存領域の節約になる。 けれどintより小さいデータ型を使うと、intに変換したりintから変 換するのでコードが大きくなったり遅くなるかもしれない)。

#defineを使うか列挙型を使うかはどっちでもいいことで、とくに興 味を引くようなことはない(質問2.2217.10を参照のこと)。プログ ラムやプロジェクトで首尾一貫している限り、以下のどれを使っても かまわない


#define TRUE 1#define YES 1
#define FALSE 0#define NO 0
enum bool {false, true};enum bool {no, yes};
あるいは生の1と0を使うのもいい(変数の値を調べるときに列挙型の 値を展開してくれるようなデバッガーを使っているのであれば、列挙 型のほうがいいかもしれない)。

以下のようなちょっと違った形を好む人もいる。

#define TRUE (1==1)
#define FALSE (!TRUE)

あるいは"補助の"マクロ、例えば

#define Istrue(e) ((e) != 0)

を定義する人もいる。どちらにしても大した効果はない(以下の質問 9.2を参照。また質問5.1210.2も参照のこと)。


9.2:
TRUEを1に#defineすることは危険ではないのか。なぜなら、C言語で は0でない値はすべて"真"と考えられるから。組み込みのブール値を 返す演算子や関係演算子が1以外の値を"返したら"どうするのか。

A:
C言語では、どんな非0の値も真と考えられることは真実である。しか しこのことは「入力においてのみ」、すなわちブール値がくることを 期待されているところでだけなりたつ。組み込みの演算子によってブー ル値が産み出されるときは、1か0であることが保証されている。よっ てテスト

if ((a == b) == TRUE)

は(TRUEが1であるかぎり)期待したとおりの結果を返す。しかしバカ げたことである。一般にTRUEやFALSEを相手に明示的にテストするこ とは望ましくない。なぜならライブラリ関数の中には(有名なのは isupper()、isalpha()など)条件が成立したときに非0の値を返すが、 その値は必ずしも1ではないものがある(さらに、もし君が「if((a == b) == TRUE)」が「if(a == b)」の改良版であると信じるのなら、な ぜそこで止めるのか。なぜ「if (((a == b) == TRUE) == TRUE)」を 使わないのか)。おおまかな目安としては、TRUEとFALSEを(あるいは 似た物を)ブール値をあらわす変数に代入する際や、関数の引数、ブー ル値を返す関数の戻り値としてだけ使うこと。けっして比較に使って はいけない。

プリプロセッサーのマクロのうち、TRUEやFALSE(もちろんNULLも)は コードの可読性を上げるのに使うのであって、あらわす値が変わる可 能性があるから使うのではない(質問5.35.10も参照のこと)。

一方、ブール値の取る値や、定義の仕方はどう見ても混乱を招く可能 性がある。プログラマーの中にはTRUEとFALSEマクロは混乱の度合を 増すだけだと考えている人もいる。

References:
K&R1 Sec. 2.6 p. 39, Sec. 2.7 p. 41; K&R2 Sec. 2.6 p. 42, Sec. 2.7 p. 44, Sec. A7.4.7 p. 204, Sec. A7.9 p. 206; ANSI Sec. 3.3.3.3, Sec. 3.3.8, Sec. 3.3.9, Sec. 3.3.13, Sec. 3.3.14, Sec. 3.3.15, Sec. 3.6.4.1, Sec. 3.6.5; ISO Sec. 6.3.3.3, Sec. 6.3.8, Sec. 6.3.9, Sec. 6.3.13, Sec. 6.3.14, Sec. 6.3.15, Sec. 6.6.4.1, Sec. 6.6.5; H&S Sec. 7.5.4 pp. 196-7, Sec. 7.6.4 pp. 207-8, Sec. 7.6.5 pp. 208-9, Sec. 7.7 pp. 217-8, Sec. 7.8 pp. 218-9, Sec. 8.5 pp. 238-9, Sec. 8.6 pp. 241-4; "亀がアキレスに言ったこと".


9.3:
pがポインターだとしてif(p)は正しい条件か。

A:
正しい。質問5.3を参照のこと。

目次へ戻る