Почему условный оператор справа ассоциативный? - PullRequest
34 голосов
/ 13 сентября 2011

Я могу понять, почему оператор присваивания является ассоциативным.Имеет смысл, что когда оценивается

x = 4 + 3

, то 4 и 3 добавляются перед присвоением x.

Мне неясно, как ?: выиграет от правильной ассоциации,Имеет ли значение только то, когда два ?: были использованы, как это

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

Тогда это оценивается так:

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

Конечно, было бы более разумно оценивать слева направоправо?

Ответы [ 3 ]

41 голосов
/ 13 сентября 2011

Если бы он оценивался слева направо, он выглядел бы так:

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

То есть он использовал бы результат первого условия (a или b) в качествебулево условие второго условного.Это не имеет особого смысла: это все равно что сказать:

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;
20 голосов
/ 13 сентября 2011

На любом языке с правом ассоциативным тернарным оператором вы можете сложить их и построить выражение 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.
?>
4 голосов
/ 13 сентября 2011

Вы ошиблись в понятии ассоциативности.

Когда оператор + называется левоассоциативным, это означает, что a + b + c эквивалентно (a + b) + c, а не a + (b + c).

Оператор = является ассоциативным справа, что означает, что a = b = c эквивалентно a = (b = c), в отличие от (a = b) = c.

Ассоциативность не имеет ничего общего с порядкомоценки.

...