すべての if...then...else ステートメントは、?: のみを使用して同等のステートメントに変換できますか?:
3 に答える
コード:
if ( flag ) {
exit(1);
}
else {
return 0;
}
に変換できません:
flag ? exit(1) : return 0;
より良い例- これはループ内にあります:
if ( flag ) {
continue;
}
else {
break;
}
に変換できません:
flag ? continue : break;
三項演算子の考えられる用途はすべて if/else として実装できますが、その逆は当てはまりません。少なくとも、パフォーマンス、可読性、または保守性の点で何のメリットももたらさない、ひねくれた無意味な「トリック」に頼ることなくしてはなりません。
if/else の構文は次のとおりです。
if( <boolean expression> )
<statment>|<statment block>
else
<statment>|<statment block>
一方、?: 三項演算子の構文は次のとおりです。
<boolean expression> ? <expression> : <expression> ;
ここで重要なことは、 an<expression>
と a<statement>
が異なる構文要素であることです。
フォームの非常に限られた使用法:
if( b ) x = y else x = z ;
次のように実装できます。
x = b ? y : x ;
ただし、ここでの制限は、true 句と false 句の両方で同じ変数が割り当てられていることです (したがって、y と z は両方とも少なくとも x の型に変換可能です)。したがって、条件付き代入は三項演算子を使用して実装できると言えます (結局のところ、それが主な目的です)。
関数呼び出しは有効な式であるため、 true 句と false 句を別々の関数でラップできますが、ポイントを証明するためだけにそれを行うのはややひねくれています。
if( b )
true_stuff() ;
else
false_stuff() ;
次と同等です。
b ? true_stuff() : false_stuff() ;
これらの関数には、任意のコードを含めることができます。
したがって、より一般的な if/else ケースを ?: 操作に変換するには、最初に true/false ステートメント ブロックを個別の関数でラップする必要があります。break
ただし、その場合でも、 、continue
、およびの動作が if/else 構造の範囲を超えて制御フローに影響を与えるため、Neil Butterworth の例はこのアプローチを無効にしreturn
ます (ただし、これらは回避したいコードの例でもある可能性があります)。goto
if/elseに a が存在すると、このアプローチも無効になります。.
結局のところ、できたとしても、なぜそうしたいのですか?
いいえ。
条件式の両方の「ブランチ」は同じタイプに評価される必要があり、そのタイプは。であってはなりませんvoid
。
たとえば、次のようにすることができます。
x > 0 ? printf("Positive!\n") : 0;
printf
を返すのでint
。(ただし、これはコードゴルフのラウンドでのみ使用します。実際、使用しただけです。)
しかし、これを行うことはできません:
x > 0 ? exit() : 0;
exit
戻るからですvoid
(または、実際にはまったく戻りません)。