Как операторы пост-инкремента (i ++) и пре-инкремента (++ i) работают в Java?

100

Не могли бы вы объяснить мне вывод этого Java-кода?

int a=5,i;

i=++a + ++a + a++;
i=a++ + ++a + ++a;
a=++a + ++a + a++;

System.out.println(a);
System.out.println(i);

Выход 20 в обоих случаях

Анкит Сачан
источник
9
Всегда избегайте двусмысленных заявлений :)
Prasoon Saurav
9
@Prasoon Saurav В отличие от C и C ++, Java и C # имеют строго определенный порядок оценки, поэтому эти утверждения не являются двусмысленными.
Пит Киркхэм
12
Я знаю это, но все же эти утверждения не используются (не могут быть) использованы в практических целях, поэтому этого следует избегать.
Prasoon Saurav
4
@PeteKirkham Прошло более шести лет, но я все еще хочу отметить, что «двусмысленность» в этой ситуации неоднозначна - это может означать «компилятор не знает, что поставить» или «программист понятия не имеет, что это значит ".
Иск Фонда Моники

Ответы:

153

Это помогает?

a = 5;
i=++a + ++a + a++; =>
i=6 + 7 + 7; (a=8)

a = 5;
i=a++ + ++a + ++a; =>
i=5 + 7 + 8; (a=8)

Главное, что ++aувеличивает значение и сразу возвращает его.

a++ также увеличивает значение (в фоновом режиме), но возвращает неизменное значение переменной - похоже, что это выполняется позже.

Кгианнакакис
источник
5
Вы уверены, что во втором случае == 9?
Пит Киркхэм,
1
я = ++ а + ++ а + а ++; => я = 7 + 8 + 5; (a = 8) поскольку приращение поста имеет наивысший приоритет, выполняется ли сначала a ++?
rsirs
2
сложный пример того, что легко объяснить.
oznus
Одинаков ли этот ответ для C # и C ++?
workoverflow
Почему здесь a, b и c равны 2? int a = 1; int b = a++; int c = ++b;Ожидал, что b будет равно 1, поскольку это инкремент сообщения.
Деннис
205

++a увеличивает, а затем использует переменную.
a++использует, а затем увеличивает значение переменной.

Если у вас есть

a = 1;

а ты делаешь

System.out.println(a++); //You will see 1

//Now a is 2

System.out.println(++a); //You will see 3

codaddict объясняет ваш конкретный фрагмент.

Ломбо
источник
64

В обоих случаях он сначала вычисляет значение, но при постинкременте сохраняет старое значение и после вычисления возвращает его.

++ а

  1. а = а + 1;
  2. вернуть;

а ++

  1. temp = a;
  2. а = а + 1;
  3. возвратная температура;
Тигран Бабаджанян
источник
8
Самый четкий
2
это заставило меня ясно понять .. спасибо.
rematnarab
22
i = ++a + ++a + a++;

является

i = 6 + 7 + 7

Работа : увеличить a до 6 (текущее значение 6) + увеличить a до 7 (текущее значение 7). Сумма равна 13, теперь прибавьте ее к текущему значению a (= 7), а затем увеличьте a до 8. Сумма равна 20, а значение a после завершения присваивания равно 8.

i = a++ + ++a + ++a;

является

i = 5 + 7 + 8

Работа : Начальное значение a равно 5. Используйте его в сложении, а затем увеличьте до 6 (текущее значение 6). Увеличьте a от текущего значения 6 до 7, чтобы получить другой операнд +. Сумма равна 12, а текущее значение a - 7. Затем увеличьте a от 7 до 8 (текущее значение = 8) и добавьте его к предыдущей сумме 12, чтобы получить 20.

codaddict
источник
эти утверждения работают справа налево или слева направо?
Abhijeet
10

++aувеличивается aдо его оценки. a++оценивает, aа затем увеличивает его.

Относительно вашего выражения:

i = ((++a) + (++a) + (a++)) == ((6) + (7) + (7)); // a is 8 at the end
i = ((a++) + (++a) + (++a)) == ((5) + (7) + (8)); // a is 8 at the end

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

Aurril
источник
1
Коммутатор @ KlasLindbäck означает, что вы можете поменять местами оба выражения и при этом получить тот же результат. Итак, a ++ + ++ a == ++ a + a ++ (5 + 7 == 6 + 6; a == 7 в конце).
Aurril
8

В приведенном выше примере

int a = 5,i;

i=++a + ++a + a++;        //Ans: i = 6 + 7 + 7 = 20 then a = 8 

i=a++ + ++a + ++a;        //Ans: i = 8 + 10 + 11 = 29 then a = 11

a=++a + ++a + a++;        //Ans: a = 12 + 13 + 13 = 38

System.out.println(a);    //Ans: a = 38

System.out.println(i);    //Ans: i = 29
Винод
источник
4

++ a - оператор приращения префикса:

  • результат вычисляется и сохраняется первым,
  • затем используется переменная.

a ++ - оператор постфиксного приращения:

  • переменная используется первой,
  • затем результат рассчитывается и сохраняется.

Как только вы запомните правила, EZ для вас, чтобы все рассчитать!

Синьи Лю
источник
4

Предполагая, что вы имели в виду

int a=5; int i;

i=++a + ++a + a++;

System.out.println(i);

a=5;

i=a++ + ++a + ++a;

System.out.println(i);

a=5;

a=++a + ++a + a++;

System.out.println(a);

Это оценивается как:

i = (6, a is now 6) + (7, a is now 7) + (7, a is now 8)

поэтому i равно 6 + 7 + 7 = 20, поэтому печатается 20.

i = (5, a is now 6) + (7, a is now 7) + (8, a is now 8)

поэтому i равно 5 + 7 + 8 = 20, и поэтому снова печатается 20.

a = (6, a is now 6) + (7, a is now 7) + (7, a is now 8)

и после того, как вся правая часть оценена (включая установку a на 8), THEN a устанавливается на 6 + 7 + 7 = 20, и поэтому 20 печатается в последний раз.

user93199
источник
3

когда aравно 5, то a++выдает 5 выражению и aзатем увеличивает его , а затем ++aувеличивает aперед передачей числа в выражение (которое aв данном случае дает 6 выражению).

Итак, вы рассчитываете

i = 6 + 7 + 7
i = 5 + 7 + 8
Торбьёрн Равн Андерсен
источник
3

Однако я считаю, что если вы объедините все свои утверждения и запустите их на Java 8.1, вы получите другой ответ, по крайней мере, так говорит мой опыт.

Код будет работать так:

int a=5,i;

i=++a + ++a + a++;            /*a = 5;
                                i=++a + ++a + a++; =>
                                i=6 + 7 + 7; (a=8); i=20;*/

i=a++ + ++a + ++a;           /*a = 5;
                                i=a++ + ++a + ++a; =>
                                i=8 + 10 + 11; (a=11); i=29;*/

a=++a + ++a + a++;            /*a=5;
                                a=++a + ++a + a++; =>
                                a=12 + 13 + 13;  a=38;*/

System.out.println(a);        //output: 38
System.out.println(i);         //output: 29
Ришаб Вашиштха
источник
3

Предварительное приращение означает, что переменная увеличивается ДО того, как она оценивается в выражении. Постинкремент означает, что переменная увеличивается ПОСЛЕ того, как она была оценена для использования в выражении.

Поэтому посмотрите внимательно, и вы увидите, что все три назначения арифметически эквивалентны.

Оке Увечуэ
источник
2

пре-инкремент и пост-инкремент эквивалентны, если не в выражении

int j =0;
int r=0         
for(int v = 0; v<10; ++v) { 
          ++r;
          j++;
          System.out.println(j+" "+r);
  }  
 1 1  
 2 2  
 3 3       
 4 4
 5 5
 6 6
 7 7
 8 8
 9 9
10 10
Java Main
источник
0
a=5; i=++a + ++a + a++;

является

i = 7 + 6 + 7

Работа: пре / пост инкремент имеет ассоциативность "справа налево", а пре имеет приоритет над постом, поэтому в первую очередь пре-инкремент будет решен как (++a + ++a) => 7 + 6. then a=7предоставляется для увеличения поста => 7 + 6 + 7 =20и a =8.

a=5; i=a++ + ++a + ++a;

является

i=7 + 7 + 6

Работа: пре / пост инкремент имеет ассоциативность «справа налево», а пре имеет приоритет над постом, поэтому в первую очередь будет (++a + ++a) => 7 + 6решено пре-инкремент, поскольку. Затем a=7предоставляется пост инкремент => 7 + 7 + 6 =20и a =8.

Винит Саху
источник
0

Я считаю, что вы выполняете все эти операторы по-разному,
выполняя их вместе, вы получите => 38, 29

int a=5,i;
i=++a + ++a + a++;
//this means i= 6+7+7=20 and when this result is stored in i,
//then last *a* will be incremented <br>
i=a++ + ++a + ++a;
//this means i= 5+7+8=20 (this could be complicated, 
//but its working like this),<br>
a=++a + ++a + a++;
//as a is 6+7+7=20 (this is incremented like this)
Randhawa
источник