8

(私はこの答えを真剣に必要としているわけではありません。私はただ好奇心旺盛です。)

すべての if-else コンストラクトは、条件演算子を使用して同等の条件式に置き換えることができます?:か?

4

8 に答える 8

11

すべての if-else コンストラクトは、条件演算子を使用して同等の条件式に置き換えることができますか?

いいえ、あなたはこれを逆に尋ねました。 if/else の「本体」にはステートメントが含まれており、try、while、break ステートメントや宣言など、すべてのステートメントを式に変換することはできません。ただし、多くの「ステートメント」は実際には変装した表現です。

++i;
blah = 42;
some_method(a,b,c);

これらはすべて、1 つの式 (それぞれインクリメント、代入、関数呼び出し) で構成されるステートメントであり、条件内で式に変換できます。

それでは、質問を逆にしましょう。if/else ステートメントが 3 項条件式とどの程度同等であるかを本当に知りたいと思われるためです。すべての条件式を同等の if/else ステートメントに置き換えることはできますか? ほとんどすべて、はい。一般的な例は return ステートメントです。

return cond ? t : f;
// becomes:
if (cond) return t;
else return f;

しかし、他の表現も:

n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;

これは、条件式を簡単に置き換えることができない場所、つまり初期化を指し始めます。オブジェクトは 1 回しか初期化できないため、条件を使用する初期化を分割して、代わりに明示的な一時変数を使用する必要があります。

T obj (cond ? t : f);
// becomes:
SomeType temp;
if (cond) temp = t;
else temp = f;
T obj (temp);

これははるかに面倒で面倒であり、 SomeType をデフォルトで構築して割り当てることができない場合は、型に依存するものが必要になることに注意してください。

于 2009-11-30T08:02:41.887 に答える
4

表面的には、いいえ。条件演算子は式 (つまり、値を持つ) ですが、if/else はステートメント (したがって値を持たない) です。それらは、言語構文内のさまざまな「ニーズ」を満たします。

ただし、式の値を無視することができ、セミコロンを追加することで任意の式をステートメントに変換できるため、基本的に、条件式と 2 つの補助関数を使用して if/else をエミュレートできます。

// Original code:
if (condition) {
  // block 1
}
else {
  // block 2
}

// conditional expression replacement:

bool if_block() {
  // block 1
  return true;
}

bool else_block() {
  // block 2
  return true;
}

// Here's the conditional expression.  bool value discarded:
condition ? if_block() : else_block();

とは言っても、単なる好奇心に過ぎないとは思いますが…。

于 2009-11-30T07:49:37.310 に答える
2

いいえ、もちろん違います。すでに述べた理由などから!

#include <cstdlib>
#include <iostream>

int main()
{
    if(int i = std::rand() % 2)
    {
        std::cout << i << " is odd" << std::endl;
    }
    else
    {
        std::cout << i << " is even" << std::endl;
    }
}

is が宣言されている場所を確認してください。これは頻繁に使用される手法ではありませんが、すべての呼び出しが (ほとんどの場合) 成功するとゼロ (S_OK)、失敗するとゼロ以外の HRESULT を返す COM のような状況で使用できるため、次のように記述できます。

if(HRESULT hr = myInterface->myMethod())
{
    _com_raise_error(hr);
}

三項演算子は類似のことはできません。

于 2009-11-30T12:23:34.723 に答える
1

原則として、はい:

if (A) B; else C

になる

try {
  A ? throw TrueResult() : throw FalseResult();
  // or: throw A ? TrueResult() : FalseResult();
} catch (TrueResult) {
  B;
} catch (FalseResult) {
  C;
}

(より自然な) プロシージャを使用する場合と比較して、これにより、breakなどが可能になります。 /で終わらないの評価が必要ですが、それらの例外を をシミュレートするためだけに使用する場合は、問題になりません。continuereturnATrueResultFalseResultif

于 2009-11-30T09:27:20.480 に答える
1

?条件演算子は、(条件演算子の結果自体が右辺値であるため) に続く項目の両方が右辺値であることを期待しています。以下は許可されません(または失敗すると、コーディングスタイルが非常に貧弱になります...):

(condition) ? return x : return y;

一方、if-else バージョンは非常に標準的です。

if(condition) return x;
else return y;

そうは言っても、任意のプログラムを使用して、if-else を使用しない同様に機能するプログラムを作成できますか? 確かに、あなたはおそらくできるでしょう。ただし、それが良いアイデアになるとは限りません。;)

于 2009-11-30T07:42:31.587 に答える
1

条件演算子を使用すると式が生成され、条件演算子の両方の潜在的な結果は「互換性」(同じ型に変換可能) である必要があります。

if-コンストラクトは、両方のelse分岐から同じ型をはるかに少なくして、型を「返す」必要さえありません。

于 2009-11-30T07:43:05.713 に答える
1
if( cond )
    break;
else
    a=b;

?:オペレーターが常に交換できるとは限りません。多くの場合 (常にではないにしても)、コード全体を再考してこの代用を提供できますが、通常、実行を制御するものを に入れることはできません?:breakreturn、ループthrowなど

于 2009-11-30T08:00:48.177 に答える
0

GCC には があり、それを使用して、ステートメントを同等の式にstatement expression書き換えることができます。if?:

if (<expression>)
  <statement1>
else
  <statement2>

編集:voidキャストには 2 つの目的があります。の部分式?:は同じ型である必要があり、voidキャストがないと、コンパイラは を出力する可能性がありますwarning: statement with no effect

(<expression>)? (void)({<statement1>}) : (void)({<statement2>});
于 2009-11-30T09:00:15.963 に答える