この三項演算子は、別名として条件演算子とも言うらしいですね。今回は少し趣向を変えて、代入判定式とも言える三項演算子について解説します。
--
いきなりここに飛んで来ちゃった人は、よろしければ下記からご覧ください。


  • 三項演算子とは?
何かを判定して変数に入れる値を変更する事はよくあります。例えば、縦型と横型という状態があり、それに応じてオフセット座標を得たいとかで…

int ofstX, ofstY; if (isVertical) { ofstX = 0; ofstY = 1; } else { ofstX = 1; ofstY = 0; }
こんな感じの処理です。これを見やすいと見るか、値の代入だけなのに長いと見るかは人の感性ですが、内藤的には実は縦に長くなるこの書き方はあまり好きくないんですよね。そこで使用したいのが三項演算子です。まずはどういう書き方となるのか、先の例を三項演算子で表現してみます。

int ofstX = isVertical ? 0 : 1; int ofstY = isVertical ? 1 : 0;
如何でしょうか。やたらとすっきりしてしまいました。この書き方で、上記のコードと全く同様の動作となります。上記のコードをインデント(改行)を工夫する事で、最初に提示した通常のステートメントでも、似たような書き方にする事は出来ます。

int ofstX, ofstY; if (isVertical) { ofstX = 0; } else { ofstX = 1; } if (isVertical) { ofstY = 1; } else { ofstY = 0; }
なんか…逆にめちゃくちゃ分かりづらくなってしまいました。そうなんです、三項演算子を嫌う人にとっては、この書き方と同じに見えるのです。※ 後述
バッファロー 10GbE対応PCI Expressバス用LANボード LGY-PCIE-MG2
バッファロー
2021-02-17
※ LANカードをわざわざスロットに差して付け替えるのなら、最低でもこのクラスを設置したいです。インテルマザーでたびたびLANが切れるのならこちらを検討を!

  • 三項演算子の文法
勘の良い人なら、上記のサンプルでなんとなく理解できるとは思いますが…

変数 = 条件式 ? true の時に代入する値 : false の時に代入する値
先の例では条件式に直接 bool 変数を入れましたので、その値が true か false かで、代入される値が変わってるのです。条件式の部分は if と同等の式が記述できます。例えば…

posX = x + ofstX < 0 ? 0 : x + ofstX;
…あまり良い例じゃないですね…😓  これは、x + ofstX の結果がマイナスになったら 0、そうじゃなければ x + ofstX の値をそのまま posX に代入しています。

あと、代入する値ですが、関数の返却値も三項演算子の中で記述できるため、例えば…

result = path[0] == 0 ? SaveAs() : Save(path);
こんな書き方も出来ます。これは path が無ければ SaveAs() を、path があれば Save を引数を付けて呼び出すという処理になります。どちらも同じ返却の型を持つ事が前提です。返却の型が異なっている場合は、この記述は出来ません。


  • 三項演算子の悪行
三項演算子が一部の人にとても嫌われる理由、それは三項演算子を組み合わせて使えてしまう事です。三項演算子はその記号そのものに意味を持たせています。そのため、ちょっと記号化言語っぽい書き方になります。節度を持って使用すれば私は見やすい記述が出来ると思っている三項演算子ですが、便利だからと次々と組み合わせていくと…

Mode = IsPC8001 ? PC8001 : IsMZ700 ? MZ700 : IsNES ? NES : Etc;
なにやってるのか、一目でもう全然分かんないですよね。インデントを工夫して多少は見やすく出来ますが、それでも…

Mode = IsPC8001 ? PC8001 : IsMZ700 ? MZ700 : IsNES ? NES : Etc;
50歩100歩ですね😓 この悪い例ですが、これでもまだマシなほうで、酷いのになると

Mode = IsRetro ? IsNEC ? IsPC6001 ? PC6001 : IsPC8001 ? PC8001 : PC8801 : IsSharp ? IsMZ80 ? IsMZ80K ? MZ80K : MZ80C : IsMZ700 ? IsJP ? MZ700JP : MZ700EN : MZ1500 : Etc : IsWindows ? Microsoft : Apple;
これはあくまでも悪い例のサンプルです。書いた本人の私ですら、もはや何がどうなっているのか分からなくなっています。これが悪の部分です。この三項演算子を書いているときは、たぶんまだ理解できていると思いますが、翌日にこれを見てサクッと理解できるとは到底思えません。

cmp = pos1.Y == pos2.Y // Y座標が同じなら ? pos1.X - pos2.X // X座標で比較 : pos1.Y - pos2.Y; // 違うならY座標で比較
せいぜいこの程度の使い方に留めるのが無難です。それでも後から見て分かるように、コメントは入れておいた方が良いと思います。三項演算子を組み合わせて使い始めたらヤバイです。メンテナンスできなくなります。このような書き方だけはしないようにお願いします。
※ 心からのお願いです!
※ これなら鞄に入る!小さくて軽くて安定するし自撮り棒にもあるので一本あると便利です!まあ安いヤツなのですぐ壊れるかもですが😓