Вопрос о постинкрементном операторе - PullRequest
1 голос
/ 17 января 2010

Почему следующий код

int i = 1; 
System.out.print(i += i++);
System.out.print(i);

вывод 2 два раза вместо 3 для 2-го отпечатка?

Может ли кто-нибудь пролить свет на это?

Спасибо.

Ответы [ 5 ]

4 голосов
/ 17 января 2010

Если вы понимаете, что a ++ работает следующим образом (псевдокод):

func ++(ref a)
{
    int b=a;
    a=a+1;
    return b;
}

тогда все это имеет смысл.

3 голосов
/ 17 января 2010

Может показаться, что мне должно быть 3 в конце.

Однако, если вы посмотрите на утверждение более внимательно

i += (i++)

равно

i = ( i + (i++) ) 

, в данном случае 1 + 1.

Побочным эффектом i ++ является i = i + 1 = 1 + 1 = 2, как и следовало ожидать, однако значение i переопределяется после назначения.

2 голосов
/ 17 января 2010

Я не думаю, что это проблема из-за незнания того, как работает унарный оператор postfix ( expr ++). Именно порядок, в котором оцениваются утверждения, создает путаницу.

int i = 1;
System.out.println(i += i++); // Output: 2

Таким образом, последнее утверждение совпадает со следующими двумя утверждениями в следующем порядке:

i++; // i is now 2 for the rest of this statement and the program
i = 1 + 1; // i is assigned again  

Таким образом, оператор постфикса вычисляется сначала, а затем оценивается вся строка, но с использованием предыдущего значения i.

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

int i = 2;
System.out.println(i += i++); // Output: 4
System.out.println(i); // Output: 4  

И еще один пример:

int i = 2;
System.out.println(i = i + i++ + i--); // Output: 7
System.out.println(i); // Output: 7  

Вторая строка присваивает i . Первый i равен 2, следующий i также равен 2, но теперь третий i равен 3, поскольку i ++ изменил значение я . Как и в предыдущем случае, i - не окажет никакого влияния на i, потому что оно будет переписано с i = 2 + 2 + 3 .

int i = 1;
System.out.println(i = i++ + i); // Output: 3
System.out.println(i); // Output: 3
2 голосов
/ 17 января 2010

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

int i = 1;  // iconst_1:    variables { }, stack {1}
            // istore_1:    variables {1}, stack { }
i += i++;   // iload_1:     variables {1}, stack {1}
            // iinc 1, 1:   variables {2}, stack {1}
            // iadd:        variables {2}, stack {2} ...Note that here 1 gets added to the value on stack
            // istore_1:    variables {2}, stack {2} ...Here the variable value will overwrite the stack value

Я думаю, это объясняет результат, который вы получаете довольно хорошо. : -)

Эксперты, поправьте меня, если я ошибаюсь ...

0 голосов
/ 17 января 2010
1 + 1 == 2. 

Следовательно:

i + i == 2  

и

i += i == 2

, а затем

i += i++ == 2

Довольно прямо вперед.

...