int x = 10;
x += x--;
В С#/. Net, почему он равен тому, что он равен? (Я намеренно оставляю ответ, чтобы вы могли догадаться и посмотреть, правы ли вы)
int x = 10;
x += x--;
В С#/. Net, почему он равен тому, что он равен? (Я намеренно оставляю ответ, чтобы вы могли догадаться и посмотреть, правы ли вы)
Посмотрите на это утверждение:
x += x--;
Это эквивалентно:
x = x + x--;
Что эквивалентно:
int a1 = x; // a1 = 10, x = 10
int a2 = x--; // a2 = 10, x = 9
x = a1 + a2; // x = 20
Итак, x
- 20 после - и это гарантируется спецификацией.
То, что в значительной степени гарантировано, хотя и не по спецификации, заключается в том, что любой, кто использует такой код, будет подвергнут нападению со стороны своих коллег. Да, хорошо, что результат предсказуем. Нет, это нехорошо использовать такой код.
Джон, конечно, прав.
Хороший способ подумать об этом - запомнить:
1) подвыражения всегда оцениваются слева направо. Период. Оценка подвыражения может вызвать побочный эффект.
2) выполнение операторов всегда выполняется в порядке, указанном скобками, приоритетом и ассоциативностью. Выполнение операторов может вызвать побочный эффект.
"x" слева от + = является самым левым подвыражением, и поэтому применяется правило (1). Сначала вычисляется его значение - 10.
x - справа от + = - следующий в порядке слева направо, поэтому он оценивается следующим образом. Значение x - равно 10, а побочным эффектом является то, что x становится 9. Это так, как должно быть, потому что - имеет более высокий приоритет, чем + =, поэтому его побочный эффект выполняется первым.
Наконец, побочный эффект + = работает последним. Два операнда были 10 и 10, поэтому результат должен назначить 20 х.
У меня возникают вопросы об этом все время. Помните, что правила очень просты: подвыражения слева направо, операторы в порядке приоритета, период.
В частности, обратите внимание, что общепринятый аргумент "оператор-оператор постфикс и, следовательно, работает после всего остального", является неправильной аргументацией. Я обсуждаю, почему это неверно в следующих статьях.
Вот несколько статей, которые я написал на эту тему:
http://blogs.msdn.com/ericlippert/archive/tags/precedence/default.aspx
20; "-" не происходит до тех пор, пока все не будет оценено, и это значение будет перезаписано левой стороной равных.
Если тип возврата выбранного оператора неявно конвертируется в тип x, операция оценивается как x = x op y, за исключением того, что x оценивается только один раз.
Итак, ваш оператор эквивалентен x = x + x--;
, который оценивается в порядке слева направо и дает ответ 20.
Обратите внимание, что здесь также существует разница между --x
и x--
. Если вы написали x += --x;
, это будет эквивалентно x = x + --x
; то вы получите 19. Это потому, что значение x уменьшается, и результирующее значение используется в выражении (в отличие от x--
, где исходное значение x используется в выражении).
Это выражение x = x + --x + x
даст 28, потому что третий раз в четвертый раз (см. комментарии) x оценивается как 9.
Ответ 20. И Том, ты действительно не так удивлен, как кажется, кажется, ваши вопросы, верно? И тем из вас, кто принимает ответ, 19 - я думаю, вы в замешательстве с x + = --x;