回答:
このアプローチは、実際に使用されますboolean
(にと決意タイプtrue
とfalse
、コンパイラがサポートしている場合)。(具体的には、C ++)
ただし、C ++が(__cplusplus
マクロを介して)使用されているかどうかを確認し、実際にtrue
andを使用することをお勧めしますfalse
。
Cコンパイラでは、これは0
およびと同等1
です。
(括弧を削除すると、操作の順序により、括弧が壊れることに注意してください)
boolean
型は?
true
orを返しfalse
ます。
#define TRUE true
、#define FALSE false
いつでも__cplusplus
定義されます。
答えは移植性です。およびの数値は重要TRUE
でFALSE
はありません。何で重要なことはのような文ということであるif (1 < 2)
と評価されたif (TRUE)
とのような文if (1 > 2)
に評価if (FALSE)
。
確かに、Cでは、に(1 < 2)
評価され1
、に(1 > 2)
評価される0
ため、他の人が言ったように、コンパイラに関する限り、実際的な違いはありません。しかし、コンパイラが定義させることにより、TRUE
およびFALSE
独自のルールに従って、あなたはプログラマにその意味が明示的に作っている、とあなたはあなたのプログラム内の一貫性や他のライブラリを保証している(他のライブラリと仮定すると、あなたがしたい... Cの規格に準拠しています驚きます)。
一部の履歴
一部のBASICはFALSE
、0
およびTRUE
として定義されてい-1
ます。多くの現代言語と同様に、ゼロ以外の値はと解釈されましたが、真であるブール式をTRUE
と評価しました-1
。彼らのNOT
操作は、1を追加して符号を反転することによって実装されました。したがって、「NOT x」はになりました-(x+1)
。この副作用として、のような値はに5
評価されますがTRUE
、にもNOT 5
評価されます-6
。これもTRUE
!この種のバグを見つけることは楽しいことではありません。
ベストプラクティス
を考えると事実上のゼロがあると解釈されていることをルールFALSE
と任意の非ゼロ値は以下のように解釈されてはTRUE
、あなたがすべきにブール-探して式を比較しませんTRUE
かFALSE
。例:
if (thisValue == FALSE) // Don't do this!
if (thatValue == TRUE) // Or this!
if (otherValue != TRUE) // Whatever you do, don't do this!
どうして?多くのプログラマーは、int
sをsとして扱うショートカットを使用しているためbool
です。それらは同じではありませんが、コンパイラは通常それを許可します。したがって、たとえば、次のように書くことは完全に合法です
if (strcmp(yourString, myString) == TRUE) // Wrong!!!
それは合法に見え、コンパイラは喜んでそれを受け入れますが、おそらくあなたが望むことをしません。の戻り値strcmp()
は
0の場合yourString == myString
<0の場合yourString < myString
> 0の場合yourString > myString
したがって、上の行はの場合にTRUE
のみ戻りますyourString > myString
。
これを行う正しい方法は、
// Valid, but still treats int as bool.
if (strcmp(yourString, myString))
または
// Better: lingustically clear, compiler will optimize.
if (strcmp(yourString, myString) != 0)
同様に:
if (someBoolValue == FALSE) // Redundant.
if (!someBoolValue) // Better.
return (x > 0) ? TRUE : FALSE; // You're fired.
return (x > 0); // Simpler, clearer, correct.
if (ptr == NULL) // Perfect: compares pointers.
if (!ptr) // Sleazy, but short and valid.
if (ptr == FALSE) // Whatisthisidonteven.
プロダクションコードでこれらの「悪い例」のいくつかを見つけることがよくあり、経験豊富なプログラマーの多くは彼らに誓います。しかし、考慮してください。「正しい」バージョンは、それほど効率的ではなく、移植可能であることが保証されており、最も厳密なリンターでさえ合格し、新しいプログラマーでも理解できます。
それだけの価値はありませんか?
(1==1)
よりもポータブルではありません1
。コンパイラー自体の規則は、C言語の規則です。これは、等価性と関係演算子のセマンティクスについて明確で明確です。コンパイラーがこれを間違っているのを見たことがありません。
strcmp
0よりも小さい、等しい、または0より大きいことがわかっています。-1、0、または1であるとは限らず、実装の速度を上げるためにこれらの値を返さないプラットフォームが存在します。もしそうならstrcmp(a, b) == TRUE
、次にa > b
その逆含意が保持しない場合があります。
(1==1)
、1
どちらもint
値が1の定数式であり、意味的には同じです。それを知らない読者向けのコードを書くことができると思いますが、それはどこで終わりますか?
この(1 == 1)
トリックはTRUE
、Cに対して透過的な方法で定義するのに役立ちますが、C ++でのより良いタイピングを提供します。"Clean C"(CまたはC ++としてコンパイルされる)という方言で書いている場合、またはCまたはC ++プログラマーが使用できるAPIヘッダーファイルを書いている場合、同じコードをCまたはC ++として解釈できます。
C翻訳単位で1 == 1
は、とまったく同じ意味1
です。と1 == 0
同じ意味0
です。ただし、C ++変換ユニットで1 == 1
は、型を持っていbool
ます。したがって、TRUE
そのように定義されたマクロは、C ++によく統合されます。
それがより良い統合する方法の例としては、例えば機能があればということであるfoo
ため過負荷があるint
とのためにbool
、その後、foo(TRUE)
選択しますbool
過負荷を。TRUE
がとして定義されているだけの場合1
、C ++ではうまく機能しません。オーバーロードfoo(TRUE)
が必要にint
なります。
もちろん、C99は、導入bool
、true
およびfalse
これらはC99とし、Cとその仕事ヘッダファイルで使用することができます
しかしながら:
TRUE
しFALSE
、(0==0)
それ(1==0)
よりも前に、およびそれよりも前に行われるこのプラクティスCとC ++が混在するプロジェクトで作業していて、C99が不要な場合true
はfalse
、bool
代わりに小文字を定義します。
#ifndef __cplusplus
typedef int bool;
#define true (0==0)
#define false (!true)
#endif
0==0
とはいえ、このトリックは、C ++との相互運用を意図したものではないコードでも一部のプログラマーによって使用されています(使用されていますか?)。これは何も購入せず、プログラマーがCでブール値がどのように機能するかについて誤解していることを示唆しています。
C ++の説明が明確でない場合のために、ここにテストプログラムを示します。
#include <cstdio>
void foo(bool x)
{
std::puts("bool");
}
void foo(int x)
{
std::puts("int");
}
int main()
{
foo(1 == 1);
foo(1);
return 0;
}
出力:
bool
int
CとC ++の混合プログラミングに関連するC ++関数のオーバーロードについてのコメントからの質問について。これらは、型の違いを示しています。C ++としてコンパイルtrue
するbool
ときに定数を使用したい正当な理由は、明確な診断のためです。最高の警告レベルでは、整数をbool
パラメーターとして渡すと、C ++コンパイラーは変換について警告する可能性があります。Clean Cで記述する理由の1つは、コードの移植性が高い(C ++コンパイラだけでなくC ++コンパイラでも理解されるため)だけでなく、C ++コンパイラの診断的意見を活用できることです。
TRUE
C ++で異なることはまったく明らかではありません。
#ifdef __cplusplus
意図をより明確に表現するために使用できます。
bool
ありint
ません。これらは互いに暗黙的に変換可能であるため(そしてCでは実際には「同じ」であり、引用符に注意してください)ただし、2つの間で実際に分解する必要がある状況は多くありません。「それほど多くない」はおそらく重すぎ、「テンプレートとオーバーロードを使用したコードと比較してはるかに少ない」のほうが多分良いでしょう。
#define TRUE (1==1)
#define FALSE (!TRUE)
に相当
#define TRUE 1
#define FALSE 0
Cで
関係演算子の結果は0
or 1
です。1==1
評価されることが保証されている1
と!(1==1)
まで評価されることが保証されています0
。
最初のフォームを使用する理由はまったくありません。ただし、ほとんどすべてのコンパイラでは定数式が実行時ではなくコンパイル時に評価されるため、最初の形式は効率が悪くないことに注意してください。これは、次のルールに従って許可されています。
(C99、6.6p2)「定数式は、実行時ではなく変換中に評価できるため、定数が可能な任意の場所で使用できます。」
TRUE
およびFALSE
マクロにリテラルを使用しない場合、PC-Lintはメッセージ(506、定数値のブール値)を発行します。
Cの場合、
TRUE
として定義する必要があります1
。ただし、他の言語は1以外の量を使用するため、一部のプログラマー!0
は安全にプレイしていると感じています。
また、C99では、stdbool.h
ブールマクロの定義true
とfalse
リテラルを直接使用します。
#define true 1
#define false 0
1==1
評価されることが保証されています1
if(foo == true)
単に悪い習慣から完全なバグに移行します。
(x == TRUE)
は、とは異なる真理値を持つことができますx
。
C ++(前述)以外に、静的分析ツールの利点もあります。コンパイラーは非効率性を排除しますが、静的アナライザーは独自の抽象型を使用して比較結果と他の整数型を区別できるため、TRUEは比較の結果である必要があり、互換性があるとは見なされないことを暗黙的に認識します整数で。
明らかにCは互換性があると言っていますが、バグを強調するためにその機能の意図的な使用を禁止することを選択することもできます-たとえば、誰かが混乱&
している可能性があります&&
。または、演算子の優先順位をぶつけました。
if (boolean_var == TRUE)
、拡張によって愚かなコードを捕らえることさえできるかもしれません。拡張さif (boolean_var == (1 == 1))
れた(1 == 1)
ノードの型情報のおかげで、パターンに該当しますif (<*> == <boolean_expr>)
。
実質的な違いはありません。0
に評価されfalse
、1
に評価されtrue
ます。ブール式(1 == 1
)またはを使用して1
を定義true
しても、違いはありません。どちらもに評価されint
ます。
C標準ライブラリには、ブール値を定義するための特定のヘッダーが用意されていますstdbool.h
。
true
に評価され1
、false
に評価され0
ます。Cはネイティブのブール型を知りません。それらは単なるintです。
int
は、値0
or を使用したタイプの結果を生成します1
。Cは、実際のboolean型を(持っている_Bool
マクロで、bool
で定義されている<stdbool.h>
が、唯一なかったC99、で追加されたものではない新しいタイプを使用する事業者の意味を変更します。
_Bool
し、<stdbool.h>
持っています#define bool _Bool
。
1 == 1
として評価されることについて正しいですint
。編集。
TRUEと等しい正確な値はわかりません。コンパイラは独自の定義を持つことができます。したがって、コンパイラーの内部のものを定義に使用することが優先されます。これは、良いプログラミングの習慣がある場合は必ずしも必要ではありませんが、次のような不適切なコーディングスタイルの問題を回避できます。
if((a> b)== TRUE)
これは、手動でTRUEを1と定義すると、災害になる可能性がありますが、TRUEの内部値は別の値です。
>
演算子は常にtrueの場合は1、falseの場合は0を返します。Cコンパイラがこれを間違っている可能性はありません。等価比較にTRUE
とFALSE
貧弱なスタイルです。上記はより明確に書かれていif (a > b)
ます。しかし、異なるCコンパイラが真と偽を異なる方法で処理できるという考えは、正しくありません。
通常、Cプログラミング言語では、1はtrueとして定義され、0はfalseとして定義されます。したがって、次のことがよく見られる理由:
#define TRUE 1
#define FALSE 0
ただし、条件文では、0以外の数値もtrueと評価されます。したがって、以下を使用することにより:
#define TRUE (1==1)
#define FALSE (!TRUE)
falseをtrueでないものと等しくすることで、安全に再生しようとしていることを明示的に示すことができます。
#define TRUE (’/’/’/’)
;#define FALSE (’-’-’-’)
(coding-guidelines.com/cbook/cbook1_1.pdf page 871 から取得)