Почему в данном случае a будет равно 20, а не 21?
int a = 10;
a += a++;
Console.WriteLine(a);
Это вариация классической задачи про ++i + ++i
в несколько упрощенном варианте.
В C++ - это undefined behavior, и результатом в большинстве компиляторов будет 21. Цитируя lurkmore:
согласно стандартам С и С++, побочные эффекты (то есть инкремент в данном случае) могут быть применены в любой удобный для компилятора момент между двумя точками следования. Конструкцию i = ++i + ++i; компилятор вправе понять и как
tmp=i; tmp++; i = tmp; tmp++; i += tmp;
и как
tmp=i; tmp++; tmp++; i = tmp + tmp;
Из-за непредсказуемости поведения этот пример раньше часто предлагали объяснить на собеседованиях :)
В C# результатом будет 20, т.к. порядок вычисления явно задан спецификацией. В C# нет никаких точек следования, компилятор не настолько свободен при оптимизации выражений, так что он вычисляет в том порядке, в котором ему приказали:
+=
- это compound assignment operator. Он не самостоятельный оператор (не допускает отдельной перегрузки, и т.д.), а просто шорткат для
a = a + a++;
Т.е. он просто берет результат вычисления a
(10), прибавляет к нему результат вычисления a++
(10) и складывает сумму (20) обратно в a
. При этом операнды вычисляются именно слева направо.
Процесс вычисления постфиксного оператора a++ описан в спецификации C#, 7.6.9 Postfix increment and decrement operators, и он следующий:
Поэтому
a + (a++) -> 20
(a++) + a -> 21
Значение присвоения оператора инкремента не используется ни в одном из путей выполнения, что-то похожее скажет ReSharper на такой код a += a++;
сообщение:
Value assigned is not used in any execution path
Вы попросту потеряете свой постфиксный инкремент, так как он выполняется после того, как выполнится операция сложения и перед присваиванием. Вот если Вы используете префиксный инкремент, тогда получите в результате 21.
int a = 10;
a += ++a;
Console.WriteLine(a);
Так как операция префиксного инкремента выполнится раньше, чем выполнится сложение и присваивание.
В префиксной форме инкремент или декремент выполняется до использования значения при вычислении выражения. В постфиксной форме инкремент или декремент выполняется после использования значения при вычислении выражения.
Ссылки:
a += a++;
^---------- 10
^----- 10
^^--- 11
^^^--- значение 10, но a=11
^^------- 10+10 = 20
Я не совсем согласен с тем, как обьяснили другие ответчики.
Для начала:
инкремент = увеличить (обычно на 1)
Пре- = изменить переменную ПЕРЕД использованием
Пост- = увеличить переменную ПОСЛЕ использования
Код
int a = 10;
a += a++;
по логике должен быть 21.
Вполне логично что должна быть последовательность действий
а
присвоить 10 (инициализация)а
(считываем значение 10) и инкрементируем в 11Скорее всего на других языках значение будет колебатся между 20 и 21 в зависимости от конкретного языка на котором будешь тестировать(считай, в зависимости от компилятора)
Почему я так думаю? Есть очень интересный пример
int i = 5;
i = ++i + ++i;
ожидаемое число -- 14. Потому, что правильная последовательность действий будет
но на практике, разные компиляторы разных языков будут выдавать разные значения в рамках от 10 до 14 в зависимости от компилятора. Результат компилирования в:
Потому мой ответ: Это специфика работы компилятора/специфика языка по его спецификации(если там указано)
[ в случае С# указано ]
Виртуальный выделенный сервер (VDS) становится отличным выбором
Bootstrap подключается только по адресу localhost/site/ , если вести localhost/site/index/index (это одна и та самая страница )то работать уже не будетПолучатся что...