三項演算子

処理ではなく値を切り替えたい

ここまでの if 文は「どの処理を実行するか」を分けるものでした。しかし実際に書きたいことの中には、処理はひとつで、入れる値だけが条件で変わる場面がよくあります。

int high; if (a > b) { high = a; } else { high = b; }

やっていることは「high に入れる値を選ぶ」だけなのに5行かかっています。しかも high を宣言と別の行で初期化することになり、代入し忘れの隙も生まれます。こういうときに使うのが三項演算子です。

int high = (a > b) ? a : b;

読み方は「a > b が真なら a、偽なら b」です。C で唯一、値を3つ取る演算子なので三項演算子と呼ばれます。条件演算子と呼ぶこともあります。

if 文との決定的な違い

三項演算子は文ではなく式です。つまり全体がひとつの値になります。だから代入の右辺にも書けますし、printf の引数にもそのまま書けます。

printf("高いほうは%d点です\n", (a > b) ? a : b);

逆に、値にならないものは書けません。? : の左右に printf(...) を並べるようなことは、できてもコードが読みにくくなるだけです。三項演算子は「値を選ぶ」ときだけに使い、「処理を選ぶ」ときは if 文を使う、と役割を分けてください。

左右の型はそろえる

? : の左右は、最終的にひとつの値になるので同じ型にそろえます。片方が int でもう片方が double だと、結果は double に引き上げられます。書式指定子とずれると表示が壊れるので、迷ったら同じ型を書きます。

合否の表示にも使えます。文字列はまだ扱っていないので、ここでは合格を意味する 'P'、不合格を意味する 'F' という1文字で切り替えてみます。

char mark = (score >= 60) ? 'P' : 'F'; printf("判定は%cです\n", mark);

char 同士なので型はそろっており、%c でそのまま表示できます。

入れ子にしすぎない

三項演算子は中にもう一段書けますが、(a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c) のようになると、もう誰も読めません。2段以上になったら素直に else if に戻してください。短く書くことが目的ではなく、読み手が1行で意図をつかめることが目的です。

かっこを付けておく

条件の部分をかっこで囲むかどうかは自由です。a > b ? a : b でも動きます。三項演算子は代入や比較よりも優先順位が低いので、たいていは意図どおりに解釈されます。それでも条件をかっこで囲んでおくと、どこまでが条件でどこからが選ばれる値なのかが目で追えます。優先順位を暗記して短く書くより、かっこで意図を示すほうが事故が減ります。

printf の引数に直接書くときは1つに絞る

次のように書くと、条件を2回評価することになります。

printf("%d点で%cです\n", (a > b) ? a : b, ((a > b) ? a : b) >= 60 ? 'P' : 'F');

動きはしますが、同じ条件を2回書いているので片方だけ直す事故が起きます。いったん変数に受けてから printf に渡すほうが、行数は増えても安全です。

要件

  1. scanf で整数を2つ読む
  2. 高いほうの点数を「高いほうは80点です」の形で表示する
  3. 高いほうが60以上なら 'P'、そうでなければ 'F' を選び、「判定はPです」の形で表示する
  4. 値の選択は if 文ではなく三項演算子で書く

入出力例

main("80 65") → "高いほうは80点です 判定はPです" main("40 55") → "高いほうは55点です 判定はFです" main("60 60") → "高いほうは60点です 判定はPです" main(12, 100) → "高いほうは100点です 判定はPです"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.c
学習モード

メモ

三項演算子

⌘S で保存