Подтвердить что ты не робот

I = я ++ не увеличивает i. Зачем?

Возможные дубликаты:
Почему это происходит в бесконечном цикле?

Такие вещи, как i = i++, имеют поведение undefined в C и С++, потому что значение скалярного объекта изменяется дважды внутри одного и того же выражения без промежуточной точки последовательности.

Однако я полагаю, что эти выражения имеют хорошо определенное поведение на С# или Java, потому что AFAIK оценивает аргумент слева направо и есть точки последовательности по всему.

Тем не менее, я ожидаю, что i = i++ будет эквивалентен i++. Но это не так. Следующая программа выводит 0.

using System;
class Program
{
    static void Main(string[] args)
    {
        int i = 0;
        i = i++;
        Console.WriteLine(i);
    }
}

Не могли бы вы помочь мне понять, почему?

Отказ от ответственности: Я полностью осознаю, что независимо от того, определено ли поведение вышеупомянутых конструкций, они глупы, бесполезны, нечитаемы, не нужны и не должны использоваться в коде. Мне просто интересно.

4b9b3361

Ответ 1

Поведение хорошо определено в С#, а порядок оценки:

  • Левая сторона i оценивается переменной i
  • Правая сторона оценивается как 0, а i увеличивается (теперь i==1)
  • Выполнение назначения выполняется, оно устанавливает i в 0. (теперь i==0)

Конечный результат i==0.

В общем вы сначала создаете дерево выражений. Чтобы оценить его, вы сначала оцениваете левую сторону, затем правую сторону и, наконец, операцию в корне. Сделайте это рекурсивно.

Ответ 2

Результатом выражения post-increment i++ является исходное значение i. Поэтому после того, как i++ был оценен (с увеличением i), вы назначаете старое значение i... i.

Просто используйте

i++;

;)

Ответ 3

i = ++i - это код, который делает то, что, по вашему мнению, происходит здесь. i++ действительно ведет себя по-другому.

С i++ значение i увеличивается, но значение i++ не является новым значением i, это предыдущее значение. Поэтому, когда вы делаете i = i++, вы говорите: "Увеличьте значение i, затем установите i в старое значение".

Ответ 4

Ну, выражение правой стороны должно быть оценено до назначения. Теперь i++ будет оценивать текущее значение i, а значение я впоследствии увеличится на единицу. Тем не менее, назначение еще не выполнено, и когда оно будет, оно будет перезаписывать текущее значение i (1) с любым выражением rhs, которое было в вашем случае равным 0.

Ключевое различие между ++i (pre-increment, которое оценивается с новым значением i после) и i++ или пост-приращением, которое оценивается текущее значение i до.

Если бы вы использовали ++i вместо этого, выражение в правой части было бы оценено до 1, в результате чего я == 1.