2

C++ 標準は、セクション 4.12 で次のように述べています。

算術、列挙、ポインター、またはメンバー型へのポインターの右辺値は、bool 型の右辺値に変換できます。ゼロ値、ヌル ポインター値、またはヌル メンバー ポインター値は false に変換され、その他の値は true に変換されます。

つまり、次のコードは有効です。

if(5)
  std::cout << "WOW!";

構文的には有効ですが、意味的には意味がありません。私の質問は、なぜ C++ がそのような奇妙なことを許可しているのかということです。私の知る限り、それは混乱を招くのではなく、何の利点もありません。

4

9 に答える 9

21

それが歴史的であり、Cがboolのような概念を評価するために使用された方法の副産物だと思います...

C にはブール型がありませんでした。C の「ダウン トゥ ザ メタル」パラダイムでは、NULL に設定されたポインタや数値型なども暗黙のうちにfalseでした。

それを 'nothing/zero == false' と 'anything else == true' と考えれば、実際には意味があります。

于 2009-06-19T05:47:26.013 に答える
7

実際、C/Python/Perl/BASIC を含む多くの言語では、ゼロ以外の整数/ポインター値は常に​​ true と見なされ、0 は false と見なされます。

これは多くのプログラミング言語でよく知られている規則なので、理由はありません。なぜこれが C++ にあってはならないのでしょうか?

問題は、なぜ Java でそうでないのかということです。

于 2009-06-19T05:53:04.070 に答える
3

C社の製品です。

また、これらは(計算上ではなくても論理的に)同等であることに注意してください。

もし (x && y || z)

もし (x * y + z)

(TI99/4a BASIC には AND 演算も OR 演算もなかったので、私はこれを知っています。したがって、* と + は二重の役割を果たさなければならず、TI99/4a BASIC では、ブール値は C のように機能しました。

于 2009-06-19T06:04:27.343 に答える
2

その理由は歴史にあると思います。次の C++ バージョン (C++0x、C++1x) では、整数への暗黙的な変換が許可されていないスコープ列挙が導入され、次のコードが不正な形式になることに注意してください。

enum class X { A, B, C };
if(X::B) { ... }

ただし、数値がブール値への暗黙的な変換を許可することは私には理にかなっていますが、主な目的は値のリストを列挙することであり、列挙子の実際の値は二次的なものであるため、列挙型についてはあまり意味がありませんほとんどの場合、関心があると思います。範囲指定された列挙にはキャストが必要です

if(static_cast<bool>(X::B)) { ... }

これにより、列挙型の必要な C 互換性がこれまで許可されていなかったタイプ セーフが追加されます (通常の列挙型に禁止されている場合、これは多くのコードを壊すと思います)。

于 2009-06-19T12:48:21.703 に答える
1

これは、特定のハードウェア制限の成果物です。

「int」、「short」、「bool」などの用語。al。コンパイラが動作している限り、実際に異なる意味を持つだけです。実行時には、1ワード(8ビット)の値、2ワード(16ビット)の値、4ワード(32ビット)の値などです。

したがって、ここでの本当の問題は、「ブール値として5を除いてC ++を使用する理由」ではなく、「Cを使用した理由」です。そしてその答えは、メモリアライメントのために、すべての場合に1ビットをどこにでも格納することができなかったため、コンパイラは単語全体を使用しただけであるということです。C ++に指定された「ブール」型があるという事実は、字句の手を振っているだけです。

于 2009-06-19T07:31:52.560 に答える
0

歴史的に、Cは比較的弱い型の言語であり、堅牢性ではなく単純さと効率を目的として設計されています。Pascalおよび同様の言語は、より強く型付けされています。列挙型、ポインター、int、およびboolをランダムに混合して、式で一致させることはできません。

C(および多くのC ++)プログラマーはこのバックグラウンドで成長しており、次のような慣用的なコードがよく見られます。

while (1)
   dosomething(); // repeats forever

.. また...

char * pointer;

if (pointer)  // tests pointer for being != 0, which equals NULL.
  fred = *pointer;

個人的には、C / C ++を20年以上使用しているにもかかわらず、この2番目のイディオムは1行に2つの「隠された」キャスト/仮定を作成するため、まだ醜いです。つまり、(NULL == 0)と(0 == FALSE)です。 )。

于 2009-06-19T11:29:20.253 に答える
0

そこには良い答えがありますが、もう 1つ指摘したいことがありboolean = numberます。boolean = pointerif(number)if(pointer)

于 2009-06-20T22:55:53.600 に答える
0

これは推測ですが、C がミニマリスト言語として設計されたという事実によるものだと思います。

まず、ブール値の評価と算術評価は非常に似ているため、実際には C パーサーで結合されます。これにより、パーサーの全体的なサイズが縮小されます。C++ はこれを継承しています。

第 2 に、アセンブリのゼロ以外の結果のテストは、通常、レジスタのゼロ値をテストする単一のオペコードを使用して実行され、真の場合はステートメントの「else」部分にジャンプします。値がゼロ以外の場合、実行は自然にステートメントの「真の場合」部分に流れます。

于 2009-06-19T11:13:31.817 に答える