条件演算子

条件演算子（）は、プログラミング言語の演算子で、条件文と同様な意味があるが、文ではなく値を持つ式になる。評価されると、条件式の値により異なる式が評価され、異なる値になる。
なお、C言語やC++など一部のプログラミング言語において、条件演算子とは後述する「? :」(ハテナマークとコロン) の演算子の名称である。
概要.
「If Then Else 」にあたる三項演算子があり、ほぼ唯一の、プログラミング言語において一般的な三項演算子である。また「If Then if」にあたる二項演算子もある。
三項演算子は、条件式・真式・偽式の3つのオペランドを結ぶ。二項演算子の場合は、条件式と、真式または偽式のいずれかの、2つのオペランドを結ぶ。
条件文との違いは、
である。
種類.
C言語など.
C言語などには、次の構文の三項の条件演算子がある。
 <条件式> ? <真式> : <偽式>
3項を結ぶ必要上、「?」と「:」の2つの記号を使うが、演算子としては1つの演算子である。
codice_1は真 (true) または偽 (false) の論理値を返す論理式 (ブール型) である（あるいは論理値に暗黙に型変換可能な型を返す）。真式と偽式は同じ型の値を返さなければならない（暗黙に型変換可能なら許されることもある）。
この構文自身も式であるので値をもち、その値は上記codice_2またはcodice_3の値のいずれかである。codice_1が真の場合はcodice_2、偽の場合はcodice_3の値となる。
例えば、Java言語では、次のように用いる。
int weight;
String message = weight <= 100 ? "OK" : "積載量オーバー";
この場合、変数codice_7の値がcodice_8以下であれば変数codice_9にcodice_10という文字列が代入され、それ以外であればcodice_11という文字列が代入される。これは通常のif-else文を用いて書いた次の例と同じ意味であり、コンパイルした結果はしばしば同じものとなる。
String message;
if (weight <= 100) {
 message = "OK";
} else {
 message = "積載量オーバー";
条件演算子はこの例のように、条件によって異なる値をある処理（上の例ではcodice_9への代入）に適用する、という場合に記述を簡潔にすることができる。
C言語およびC++では、変数宣言時の初期化に条件演算子を用いることで、再代入を許可しないcodice_13修飾された変数を定義することができるようになる。さらにC++においては、if-else文による初期化では必要な、変数宣言時のデフォルトコンストラクタが不要となる。
const std::string message(weight <= 100 ? "OK" : "積載量オーバー");
演算子の結合性.
条件演算子の結合性（associativity）は、CやJavaやPerlなどでは、codice_14 は codice_15 という意味だが、PHPの三項演算子では codice_16 なので注意が必要である。
Ruby.
Rubyでは、codice_17というC と同じ形で条件演算子を使うことができる。しかし、Ruby の場合は if も文ではなく式なので、入れ子や複数行になる場合は、条件演算子ではなくifを使用する方が好まれている。
Python.
Pythonにおいては、Cの条件演算子と同じ機能は、構文に関する論争のため長い間実装されなかったが（論理演算子を使ったハックでなんとか似たことができるというのもあった）、PEP 308として承認され、2006年9月の2.5 releaseに追加された。
Python ではこの機能の式を条件式と呼び、構文は、C言語などとは順序が異なっている（新しい演算子ないしキーワードは導入されなかった）。Perlの後置if修飾子のような見た目になった。
<真の場合の値> if <条件式> else <偽の場合の値>
Visual Basic.
Visual Basic（2008より前）、VBAには演算子はないが、同じように使える関数 Iif がある。
 Iif(<条件式>, <真式>, <偽式>)
ただし条件演算子と違い、真式・偽式いずれも関数の引数なので、条件式の真偽にかかわらず双方とも評価される。条件に合わない側の値は捨てられるので値に影響はないが、真式・偽式に副作用がある（何か出力する、グローバル変数を書き換えるなど）場合は挙動が異なってくる。
Visual Basic 2008以降には、条件演算子と同様の短絡評価をおこなうIf演算子がある。
 If(<条件式>, <真式>, <偽式>)
 'または
 If(<式1>, <式2>)
3引数の場合は、if-then-elseと同様の意味である。2引数の場合は、式1がNothingでない場合は式1の値を、式1がNothingの場合は式2の値を返す。
論理演算子の短絡評価.
論理演算子の短絡評価を利用して条件演算子のような処理を書くことができる。
短絡評価を持つ論理演算子について、論理積 は左辺の式 が偽値（論理演算の文脈で と等価な値）なら右辺の式 は評価されない。
同様に、論理和 は左辺の式 が真値（論理演算の文脈で と等価な値）なら右辺の式 は評価されない。
従って、左辺 を条件式とし、その結果が真値の場合に評価されるべき式を論理積の右辺の式 に書け、また同様に左辺の式 が偽値の場合に評価されるべき式を論理和の右辺の式 に書ける。
条件演算子ないしif-else式を短絡評価する論理演算子で模倣すると、
と書ける（ただし の値は偽値にならないとする）。上記の式は、 が偽値なら を評価せずに を評価し、 が真値（かつ も真値）なら を評価しない。
条件演算子などとの相違点として、論理演算子の評価結果がブーリアン（またはそれに相当する整数型の値）に変換されるプログラミング言語では および の値そのものは利用できない。
条件演算子とif式.
条件演算子をサポートしない言語であっても、ifが文ではなく式となっている言語では、if式を用いることで同等の機能を実現できる。例えばF#には組み込みの条件演算子はないが、以下のようにif式で代用できる。
printfn "Now %s." (if (System.DateTime.Now.Hour >= 12) then "PM" else "AM")
その他、無名関数を応用したものもある。例えばSmalltalkでは関数呼び出しに相当するメッセージ式に無名関数に相当するブロックを渡すことで条件式を実現している。
value := 0 < 1 ifTrue:[ 1 ] ifFalse: [ 2 ].
なお、この#ifTrue:#ifFalse:は分岐専用の構文ではなくメッセージ式の一例に過ぎない。メッセージ式は誰でも追加できるため、標準のライブラリーだけでも下記のような亜種が存在する。
value := 0 < 1 ifTrue:[ 1 ].
value := value ifNil:[ 1 ] ifNotNil[ 2 ].
value := value ifNil:[ 1 ].
value := value ifNotNil:[ :argument | 1 ].
value := value at: 1 ifAbsent:[ 0 ].