int j = 0;
for (int i = 0; i < 10; i++)
j = j++;
Console.WriteLine(j);
Почему в ответе получается 0?
Разжевывается вот так: (код, по сути, аналогичен z = j; j = j + 1; j = z ).
В разжеванном варианте понятно все, кроме последней части, зачем j = z ?
Дмитрий Еремин, это я понимаю. Но разве после присваивания в цикле, j вообще не увеличивается на 1 ? Интересно в какой момент в данном случае происходит j++?
Как я предполагал:
1. Переменной j присваивается 0.
2. j увеличивается на 1.
3. Т.к. j объявлена вне цикла, на этот момент в ней уже 1.
4. При следующей итерации j присваивается уже 1 и т.д.
Дмитрий Еремин, я предполагал что в обоих случаях должна быть 1.
int j = 0;
int z = 0;
z = j++;
Console.WriteLine(j);
//1
int j = 0;
j = j++;
Console.WriteLine(j);
// 0
Отдельно взятые примеры понимаю, которые мне скинули тут, в моем конкретном примере никак не пойму, почему в моем случае 0.
Попробую описать еще раз, как я это представляю:
1. Объявили переменную j и присвоили ей 0.
2. j = j++ Сначала происходит присвоение: j = 0. Затем 0 увеличивается на 1.
3. Вывожу значение j. Ожидал получить 1. Как в первом примере.
Юрий, не понимаете потому что считаете что j и 0 это одно и тоже. Это не так.
На самом деле каждая переменная и каждое значение - это разные ячейки памяти, т.е. j, i, 10, 0 - всё что вы объявили в программе - это всё разные ячейки памяти. Процессор же не умеет работать с ячейками памятью напрямую. Т.е. он не может взять и прибавить к 10 еще 1 прямо в ячейке памяти. Он сначала загружает значение из одной ячейки памяти в свое временное хранилище (регистр), затем другое значение из другой ячейки памяти в другое хранилище (второй регистр) и складывает эти два значения из временных хранилищ (регистров), получает результат 11 в каком-то из регистров, и затем этот результат из регистра записывает в какую-то ячейку в памяти. Или не записывает как в вашем случае. Т.е. когда вы пишете j = 0 происходит следующее: в памяти резервируются две ячейки. В первой нет ничего, в другой значение 0. Процессор загружает значение 0 из второй ячейки памяти в свой регистр, а затем записывает это значение в первую ячейку, которой вы дали имя j, из своего регистра. Тут важно понять, что j = 0 это не математическое допущение аля "пусть j у нас будет 0", это операция, которую выполняет процессор. И чтобы в j поместить 0, надо 0 откуда-то взять и затем положить куда-то.
Теперь давайте разберем что происходит когда выполняется код j = j++
Сначала процессор загружает значение j из памяти (это значение равно 0 потому что выше написано j = 0) в свой регистр, затем он производит операцию записи данных из этого регистра в ячейку j, т.е. записывает туда 0, который загрузил в регистр на прошлом шаге. И затем выполняет операцию увеличения значения в своем регистре (а иначе он не умеет, только в регистре), на единицу. И никуда этот результат не записывает.
Или, если кратко, то j = j++ говорит процессору: возьми значение из j (! фактически делает копию), положи его в обратно j и потом свою копию (а не то что в j) увеличь на единицу. А результат фактически отбрасывается.
Запись же, как предлагали выше j = ++j говорит процессору: возьми значение из j, увеличь на единицу и результат положи в j.
В разжеванном варианте понятно все, кроме последней части, зачем j = z ?
Затем, что так определён оператор постфиксного инкремента. Скопировать значение переменной. Увеличить переменную. Вернуть скопированное значение. Этим копированием постфиксный инкремент(ш++) отличается от префиксного(++ш).
Присвоение выполняется в самом конце, поскольку имеет меньший приоритет.
Юрий, никак, потому что для пользователя это атомарная операция. Думаю, если взять дебаггер и пойти по шагам, в определённый момент в j можно увидеть 1.