私はCで定義を見てきました
#define TRUE (1==1)
#define FALSE (!TRUE)
これは必要ですか? TRUEを1として、FALSEを0として定義することの利点は何ですか?
このアプローチでは、コンパイラがサポートしている場合、実際のboolean
型を使用します(そして、true
およびfalse
に解決します)。 (具体的には、C++)
ただし、C++が(__cplusplus
マクロを介して)使用されているかどうかを確認し、実際にtrue
とfalse
を使用する方が良いでしょう。
Cコンパイラでは、これは0
および1
と同等です。
(括弧を削除すると、操作の順序により括弧が壊れることに注意してください)
_(1 == 1)
_トリックは、Cに対して透過的な方法でTRUE
を定義するのに役立ちますが、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)
_として定義するこの慣行は、C99よりも前です。CとC++の混合プロジェクトで作業しており、C99が必要ない場合は、代わりに小文字のtrue
、false
およびbool
を定義します。
_#ifndef __cplusplus
typedef int bool;
#define true (0==0)
#define false (!true)
#endif
_
とはいえ、_0==0
_トリックは、C++との相互運用を意図していないコードでも、一部のプログラマーによって使用されています(is?)。 これは何も買わず、プログラマーが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++コンパイラの診断意見から利益を得ることができるからです。
_#define TRUE (1==1)
#define FALSE (!TRUE)
_
と同等です
_#define TRUE 1
#define FALSE 0
_
cで.
関係演算子の結果は_0
_または_1
_です。 _1==1
_は_1
_に評価されることが保証され、!(1==1)
は_0
_に評価されることが保証されます。
最初の形式を使用する理由はまったくありません。ただし、ほとんどすべてのコンパイラーでは定数式が実行時ではなくコンパイル時に評価されるため、最初の形式の効率は低下しません。これは、次の規則に従って許可されます。
(C99、6.6p2)「定数式は、実行時ではなく翻訳中に評価できるため、定数が存在する可能性のあるあらゆる場所で使用できます。」
TRUE
およびFALSE
マクロにリテラルを使用しない場合、PC-Lintはメッセージ(506、定数値ブール値)を発行します。
Cの場合、
TRUE
は_1
_になるように定義する必要があります。ただし、他の言語は1以外の量を使用するため、一部のプログラマーは_!0
_が安全にプレイしていると感じています。
また、C99では、ブールマクロtrue
およびfalse
の_stdbool.h
_定義は、リテラルを直接使用します。
_#define true 1
#define false 0
_
C++(既に述べた)とは別に、もう1つの利点は静的分析ツールです。コンパイラーは非効率性を排除しますが、静的アナライザーは独自の抽象型を使用して比較結果と他の整数型を区別できるため、TRUEは比較の結果でなければならず、互換性があると見なされるべきではないことを暗黙的に認識します整数で。
明らかにCは互換性があると言っていますが、バグを強調するためにその機能の意図的な使用を禁止することもできます。たとえば、誰かが混乱する場合は&
および&&
、または、演算子の優先順位を下げました。
実際の違いはありません。 0
はfalse
に評価され、1
はtrue
に評価されます。 ブール式(1 == 1
)または1
を使用してtrue
を定義するという事実は、違いはありません。両方ともint
に評価されます。
C標準ライブラリは、ブール値を定義する特定のヘッダーstdbool.h
を提供していることに注意してください。
TRUEが等しい正確な値はわかりません。コンパイラは独自の定義を持つことができます。したがって、privodeは、コンパイラの内部定義を使用して定義します。これは、プログラミングの習慣が優れている場合には必ずしも必要ではありませんが、コーディングスタイルが悪い場合の問題を回避できる場合があります。例:
if((a> b)== TRUE)
TRUEの内部値が別の値であるのに、手動でTRUEを1として定義すると、これは災害になる可能性があります。
通常、Cプログラミング言語では、1はtrueとして定義され、0はfalseとして定義されます。したがって、次のことが頻繁に表示される理由:
#define TRUE 1
#define FALSE 0
ただし、0以外の数値は、条件文でもtrueと評価されます。したがって、以下を使用して:
#define TRUE (1==1)
#define FALSE (!TRUE)
Falseをtrueではないものと等しくすることで、安全にプレイしようとしていることを明示的に示すことができます。