Cには組み込みのブール型はありません。Cでそれらを使用する最良の方法は何ですか?
Cには組み込みのブール型はありません。Cでそれらを使用する最良の方法は何ですか?
回答:
最高から最低まで:
オプション1(C99)
#include <stdbool.h>
オプション2
typedef enum { false, true } bool;
オプション3
typedef int bool;
enum { false, true };
オプション4
typedef int bool;
#define true 1
#define false 0
まだ決まっていない場合は、#1に進んでください。
<stdbool.h>
bool
コンパイラーが選択する配置、最適化、およびコンパイラーの保管方法は、ブール値の使用目的よりもint
(コンパイラーがとはbool
異なる実装を選択する可能性があるためint
)ブール値の使用目的に適している場合があります。運が良ければ、コンパイル時に型チェックが厳密になる可能性もあります。
int
するのbool
ですか?それは無駄です。を使用しunsigned char
ます。または、Cの組み込みを使用します_Bool
。
Cのブール値に関するいくつかの考え:
私は十分に古くint
、typedefやtrue / false値の特別な定義や列挙をせずに、プレーンsをブール型として使用するだけです。ブール定数に対して決して比較しないという以下の私の提案に従うなら、とにかくフラグを初期化するために0/1を使用する必要があるだけです。しかし、このようなアプローチは、これらの現代ではあまりにも反動的であると見なされる場合があります。その場合、<stdbool.h>
少なくとも標準化されているという利点があるので、間違いなく使用する必要があります。
ブール定数の名前が何であれ、初期化のみに使用します。次のようなことは決して書いてはいけません
if (ready == TRUE) ...
while (empty == FALSE) ...
これらは常により明確なものに置き換えることができます
if (ready) ...
while (!empty) ...
これらは実際には合理的かつ理解可能に大声で読み上げることができることに注意してください。
ブール変数に正の名前を付けます(例:のfull
代わりに)notfull
。後者は、簡単に読み取るのが難しいコードにつながります。比較する
if (full) ...
if (!full) ...
と
if (!notfull) ...
if (notfull) ...
前者のペアはどちらも自然!notfull
に読み取られますが、そのままでも読みにくく、より複雑なブール式ではさらに悪くなります。
ブール値の引数は、通常は避ける必要があります。このように定義された関数を考えます
void foo(bool option) { ... }
関数の本体内では、便利でうまくいけば意味のある名前が付いているため、引数の意味は非常に明確です。しかし、呼び出しサイトは次のようになります
foo(TRUE);
foo(FALSE):
ここでは、関数の定義や宣言を常に見ていないと、パラメーターの意味を理解することは基本的に不可能であり、さらにブール型パラメーターを追加するとすぐに、事態はさらに悪化します。私はどちらかを提案します
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
または
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
どちらの場合も、呼び出しサイトは次のようになります。
foo(OPT_ON);
foo(OPT_OFF);
読者は、少なくともの定義に手を加えることなく理解できる可能性がありfoo
ます。
a == b
か?
a
してb
、ゼロからカウントアップ、私はお勧めしますa > 0 == b > 0
代わりに。ゼロ以外の任意の値の真実性を利用すると主張!!var
するとvar
、と同等のブール値0/1が生成されるため、を書くことができますが!!a == !!b
、多くの読者は混乱を招きます。
!a == !b
同等性のテストにも十分であり、非ゼロはゼロになり、ゼロは1になります。
!!a
、「ブール値ではないaを同等の真理値に変換する」と読んだ方が!a
、「ブール値の変数aを論理的に反転させる」と読んだと思います。特に、論理反転が必要な特定の理由を探します。
Cのブール値は整数です。偽の場合はゼロ、真の場合は非ゼロです。
ブールデータ型、セクションC、C ++、Objective-C、AWKも参照してください。
これが私が使ったバージョンです:
typedef enum { false = 0, true = !false } bool;
falseの値は1つだけですが、論理trueは多くの値を持つ可能性がありますが、テクニックはfalseの反対にコンパイラが使用するものをtrueに設定します。
これは誰かがこれに帰着する何かをコーディングする問題を処理します:
if (true == !false)
これは良い習慣ではないことは誰もが認めると思いますが、「true =!false」を実行するための一時的なコストで、その問題は解消されます。
[編集]最後に私が使用した:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
定義していた他のスキームとの名前の衝突を回避しtrue
、false
。しかし、コンセプトは同じです。
[編集]整数からブールへの変換を表示するには:
mybool somebool;
int someint = 5;
somebool = !!someint;
最初(最も右)!ゼロ以外の整数を0に変換し、次に2番目(左端)に!0をmyfalse
値に変換します。読者がゼロ整数を変換する練習として残しておきます。
[編集]デフォルト値が同じであっても特定の値が必要な場合は、列挙型の値の明示的な設定を使用するのが私のスタイルです。例:falseはゼロである必要があるため、使用するのfalse = 0,
ではなくfalse,
true
、false
とbool
は対照的に、彼らは、列挙型の値とのtypedefであるため、ほとんどのIDEの中で強調表示され#defines
、めったに構文が強調表示されています。
gcc -ansi -pedantic -Wall
は警告を出さないので、信頼しgcc
ます。これがうまくc89
いくなら、それもうまくいくはずc99
です。
!
値のみを返すことができます0
し、1
ので、true = !false
常に割り当て値1は、この方法では、上の余分な安全性を与えるものではありませんでしょうtypedef enum { false, true } bool;
。
if(!value)
)が重要ではない場合、このルールを法的に無視できますが、この例外はこの特定のケースには適用されません。
C99コンパイラを使用している場合は、ブール型のサポートが組み込まれています。
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
まず最初に。C、つまりISO / IEC 9899は、19年間ブール型になりました。これは、この質問にアクセスしたときに、アマチュア/アカデミック/プロフェッショナルのパーツを組み合わせたCプログラミングキャリアの予想される長さよりもはるかに長い時間です。鉱山はたぶんたった1-2年でそれを超えます。これは、平均的な読者がCについて何も学んでいない間、Cは実際にはブール型のデータ型を持っていたことを意味します。ます。
データ型については#include <stdbool.h>
、使用true
、false
およびbool
。それとも、および使用を含んでいない_Bool
、1
と0
代わりに。
このスレッドに対する他の回答では、さまざまな危険な行為が奨励されています。私はそれらに対処します:
typedef int bool;
#define true 1
#define false 0
19年以内にCを習得したカジュアルな読者bool
は、実際の bool
データ型を参照して同じように動作することを期待しているはずですが、実際はそうではないためです。例えば
double a = ...;
bool b = a;
C99でbool
/ _Bool
、b
に設定されますfalse
IFF a
ゼロだった、とtrue
そうでありません。C11 6.3.1.2p1
- スカラー値がに変換される
_Bool
と、値が0と等しい場合、結果は0になります。それ以外の場合、結果は1になります。59)脚注
59)NaNは0と比較しないため、1に変換されます。
typedef
代わりに、double
に強制変換されるだろうint
-ダブルの値が用範囲内にない場合int
、動作は未定義です。
当然、同じことはif true
とfalse
で宣言され、enum
。
何でもあるより危険を宣言しています
typedef enum bool {
false, true
} bool;
今ので、すべての値 1と0以外には無効であり、そのような値は、その型の変数に代入されるべきで、動作は完全に定義されていないことになります。
したがって、場合に限っあなたには、いくつかの不可解な理由のためにC99を使用することはできません、ブール変数のためにあなたが使用する必要があります。
int
と値0
、および現状の1
まま。そして、他の値からこれらの値へのドメイン変換を二重否定で慎重に行う!!
BOOL
、TRUE
とFALSE
!int
またはunsigned int
列挙型を保持するために使用できますが、列挙型が整数以外として動作する原因となる標準には何も知りませんタイプ。
Cのブール型はbool(少なくとも過去10年間)です。
stdbool.hをインクルードすると、true / falseが期待どおりに機能します。
bool
に展開するマクロである必要があります_Bool
。#undef
マクロは可能ですが(少なくとも移行措置としては許可されます)、untypedef
typedef はできないため、違いは重要です。ただし、最初のコメントの主な目的は変わりません。
ブール演算ではゼロ以外のものはすべてtrueと評価されるので、
#define TRUE 1
#define FALSE 0
定数を使用します。
C99の使用が許可されている場合は、他の回答の補足といくつかの明確化。
+-------+----------------+-------------------------+--------------------+
| Name | Characteristic | Dependence in stdbool.h | Value |
+-------+----------------+-------------------------+--------------------+
| _Bool | Native type | Don't need header | |
+-------+----------------+-------------------------+--------------------+
| bool | Macro | Yes | Translate to _Bool |
+-------+----------------+-------------------------+--------------------+
| true | Macro | Yes | Translate to 1 |
+-------+----------------+-------------------------+--------------------+
| false | Macro | Yes | Translate to 0 |
+-------+----------------+-------------------------+--------------------+
私の好みのいくつか:
_Bool
またはbool
?どちらも問題ありませんがbool
、キーワードよりも見栄えがします_Bool
。bool
とは_Bool
、次のとおりですfalse
かtrue
。割り当て0
または1
の代わりに、false
またはtrue
有効であるが、論理の流れを読み、理解することは困難です。標準からのいくつかの情報:
_Bool
はないがunsigned int
、符号なし整数型のグループの一部である。値を保持するのに十分な大きさ0
または1
です。bool
true
してfalse
しかし確かに良いアイデアではありません。この機能は廃止されたと見なされ、将来削除される予定です。_Bool
、またはbool
、場合スカラー値が同一である0
か、と比較する0
ことがあろう0
、そうでなければ結果は1
:_Bool x = 9;
9
に変換される1
に割り当てられた場合x
。_Bool
は1バイト(8ビット)です。通常、プログラマは他のビットを使用しようとする傾向がありますが、推奨されるのは1ビットだけがデータを格納するために使用されるchar
ということです。利用可能なビット。char、または別の小さなコンテナを使用できます。
疑似コード
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
int
)を使用することをお勧めします。一部のアーキテクチャでは、これらの変数のチェックをアンパック/マスクする必要があるため、パフォーマンスが大幅に低下するためです。
_Boolを使用することもできますが、戻り値は整数でなければなりません(trueの場合は1、falseの場合は0)。言ったようしかし、C ++のようにブール値を含めると、使用することをお勧めします 。この回答からdaniwebフォーラムだけでなく、この答えこの他のstackoverflowの質問から、:
_Bool:C99のブール型。_Boolを直接使用することは、bool、true、またはfalseのマクロをすでに定義しているレガシーコードを維持している場合にのみお勧めします。それ以外の場合、これらのマクロはヘッダーで標準化されます。そのヘッダーを含めれば、C ++と同じようにboolを使用できます。
条件式は、それらがゼロ以外の場合に真であると見なされますが、C標準では、論理演算子自体が0または1を返す必要があります。
@トム:#define TRUE!FALSEは悪く、完全に無意味です。ヘッダーファイルがコンパイル済みC ++コードに組み込まれると、問題が発生する可能性があります。
void foo(bool flag);
...
int flag = TRUE;
foo(flag);
一部のコンパイラは、int => bool変換に関する警告を生成します。時々人々はこれをすることによってこれを避けます:
foo(flag == TRUE);
式を強制的にC ++ boolにします。ただし、#define TRUE!FALSEを定義すると、次のようになります。
foo(flag == !0);
これは、とにかく警告をトリガーできるint-bool比較を行うことになります。
C99を使用している場合は、_Bool
タイプを使用できます。#include
sは必要ありません。ただし、1
is true
と0
isは整数のように扱う必要がありますfalse
。
その後、TRUE
およびを定義できますFALSE
。
_Bool this_is_a_Boolean_var = 1;
//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;
#include <stdbool.h>
と使用bool
、true
およびfalse
標準は、あなたがしたいよう。
これは私が使用するものです:
enum {false, true};
typedef _Bool bool;
_Bool
Cの組み込み型です。ブール値を対象としています。
#define
次のようにディレクティブを使用するだけです。
#define TRUE 1
#define FALSE 0
#define NOT(arg) (arg == TRUE)? FALSE : TRUE
typedef int bool;
次のように使用します。
bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);
等々
arg
と式全体を保護する必要があります#define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
。しかし、それは偽りのためのテストに良いだろう(それがあっても正しい答えを与えるarg
23の代わりに、0または1であった。#define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)
しかし、式全体はに減らすことができる。#define NOT(arg) (!(arg))
同じ結果を生成する、もちろん、。