2017-02-14 4 views
10

Я не понимаю, почему это уравнение приращения столбца не увеличивается. Я бы подумал, что после операции + = значение будет увеличиваться на 1, а затем во второй раз вокруг i будет иметь значение 1. Но выход представляет собой бесконечный цикл 0 нуля. Кто-нибудь может объяснить, почему «я» не увеличивается.Post Increment Бесконечный цикл i + = i ++;

int i = 0; 
for(; ;) { 
    if (i >= 10) break; 
    i += i++; 
} 
System.out.println(i); 
+1

В качестве побочного примечания поведение происходит от того, как определяется пост-инкремент и как работает оператор + =. Такое же поведение наблюдается в JS и, вероятно, на других языках. – njzk2

+0

* Java Puzzlers * имеет похожую, но немного более сложную головоломку под названием [* Inclement Increment *] (http://cs.fit.edu/~ryan/cse4051/java-puzzlers/4-loopy-puzzlers/puzzle-25/Increment -java.html). – shmosel

+0

В Java и C# он выводит бесконечный цикл. Но в C он выводится как код: 'i + = ++ i;' Изменяет язык на язык. –

ответ

6

Хотя ответ от @ njzk2 правильно, полезно указать почему это правильно.

Существуют и другие возможности - например, почему Java не выполняет оператор постинкрета после назначения? (Ответ: потому что это не то, что выбрали разработчики Java-языков)

Порядок оценки сложных назначений (например, +=) указан в разделе 15.26.2 языка Java. Я процитирую how it is defined for Java 8:

  • Во-первых, левый операнд вычисляется для получения переменной.Если эта оценка завершается внезапно, то выражение назначения завершается внезапно по той же причине; правый операнд не равен и не выполняется присвоение.

  • В противном случае значение левого операнда сохраняется, а затем оценивается правый операнд. Если эта оценка завершает внезапно, тогда выражение присваивания внезапно завершается для той же причины и не происходит никакого присвоения.

  • В противном случае сохраненное значение левой переменной и значение правого операнда используются для выполнения двоичной операции , указанной оператором составного присваивания. Если эта операция завершается внезапно, то по этой же причине выражение присваивания завершается внезапно и не происходит никакого присвоения.

  • В противном случае, результат бинарной операции преобразуется к типу переменных слева, подвергается преобразованию значения, установленного (§5.1.13) к набору соответствующего стандарта значения (не расширенного показателя значение), а результат преобразования - , хранящийся в переменной.

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

+0

Правильно, но бессмысленно. Это один из случаев, когда UB полностью оправдан. – KevinZ

+0

@KevinZ Вы, вероятно, ссылаетесь на Undefined Behavior (UB) в C. Я не согласен с вашим утверждением, когда дело доходит до Java. Философия Java заключается в том, чтобы сделать ее максимально возможной кросс-платформенной. В Java нет абсолютно неопределенного поведения, хотя существует некоторое поведение, которое может варьироваться между платформами в пределах спецификации. Философия дизайна для C/C++ отличается. –

22

Давайте рассмотрим i += i++;

i++ средства считывания значения для i, то приращение i.

i += x означает оценить i, затем оцените x и добавьте 2 и поместите результат в i.

Итак, что происходит, является:

  • i получает оценку, это 0
  • i++ получает оценку. он возвращает 0, а значение для i установлено на 1
  • i += i++ сейчас i = 0 + 0.
  • i = 0

Попробуйте с ++i, чтобы получить результат приращения перед чтением его значения.

1

Не удивительно, что вы получаете в петлю бесконечности ..

class Demo{ 
    public static void main(String[] args){ 
    int i = 0; 
    for(; ;) { 
     if (i >= 10) 
      break; 
     i = i+i++; 
     System.out.println(i); 
    } 
    } 
} 

Предположим, приведенный выше код, я просто заменить свою линию с приращением с тем, что компилятор заменит.

Теперь i = 0; Так

i = i+i++ 

результатов в г = 0 +-// и теперь я являюсь 1

, но в конце концов вы снова сделать я равняться 0!

Поэтому бесконечность ...

Смежные вопросы