web-dev-qa-db-ja.com

条件演算子が正しく結合するのはなぜですか?

代入演算子が正しい結合性である理由を理解できます。それは意味がある

x = 4 + 3

が評価され、xに割り当てられる前に4と3が追加されます。

?:が正しい連想であることがどのように役立つかについては、はっきりしません。 2つの?:sがこのように使用されたときにのみ問題になりますか

z = (a == b ? a : b ? c : d);

次に、次のように評価されます。

z = (a == b ? a : (b ? c : d));

確かに、左から右に評価する方が理にかなっていますか?

37
Angus Comber

左から右に評価すると、次のようになります。

z = ((a == b ? a : b) ? c : d);

つまり、最初の条件(aまたはb)の結果を2番目の条件のブール条件として使用します。それはあまり意味がありません。

int z, tmp;
/* first conditional */
if(a == b) tmp = a;
else       tmp = b;
/* second conditional */
if(tmp) z = c;
else    z = d;

たぶん、いつかこれを正確に実行したいと思うかもしれませんが、以下の各?:if/else if/else if/else。これは、右連想結合によって得られるものです。

int z;
/* first conditional */
if(a == b)                          z = a;
else /* second conditional */ if(b) z = c;
else                                z = d;
41
Chris Lutz

正しい連想3項演算子を持つ任意の言語では、次のようにそれらをスタックして、if-elseif-elseif-else式を作成できます。

val = a == 0 ? 1:
      a == 1 ? 2:
               4;

逆に、左結合三項演算子を使用する言語(PHPなど、@ user786653に感謝)では、前述の意図を括弧で明示的に適用する必要があります。

<?php
// This will output 't', not 'true'.
echo (true ? 'true' : false ? 't' : 'f');

// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');

// here, you can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool)true, thus returning the true branch of the
// second ternary expression.
?>
20

結合性の概念が間違っています。

演算子_+_が左結合であると言われる場合、これは_a + b + c_がa + (b + c)ではなく_(a + b) + c_と同等であることを意味します。

演算子_=_は右結合です。つまり、_a = b = c_は、_(a = b) = c_ではなく、a = (b = c)と同等です。

結合性は、評価の順序とは何の関係もありません。

4
Roland Illig