Як працюють оператори збільшення (i ++) та попереднього збільшення (++ i) на Java?


99

Чи можете ви пояснити мені вихід цього коду 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 Це минуло шість років, але я все ж хочу зазначити, що "неоднозначне" в цій ситуації неоднозначне - це може означати "компілятор не знає, що поставити", або це може означати "Програміст поняття не має, що це означає ".
Фонд позову Моніки

Відповіді:


150

Чи допомагає це?

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
Ви впевнені, що a == 9 у другому?
Піт Кіркхем

1
i = ++ a + ++ a + a ++; => i = 7 + 8 + 5; (a = 8), оскільки приріст пост має найвищий пріоритет, чи ++ виконується спочатку?
rsirs

2
складний приклад того, що легко пояснити.
ознус

Чи однакова ця відповідь для c # і c ++?
зворотний

Чому тут a, b і c дорівнює 2? int a = 1; int b = a++; int c = ++b;Очікував, що b буде 1, оскільки це приріст посади.
Денніс

202

++aзбільшується, а потім використовує змінну.
a++використовує, а потім збільшує змінну.

Якщо у вас є

a = 1;

і ви

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

//Now a is 2

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

кодовий вирок пояснює ваш конкретний фрагмент.


62

В обох випадках він спочатку обчислює значення, але в інкременті він зберігає старе значення і після обчислення повертає його

++ a

  1. a = a + 1;
  2. повернути a;

a ++

  1. temp = a;
  2. a = a + 1;
  3. темп повернення;

8
Найясніша відповідь
Картік Ч'ю

2
це мене зрозуміло зрозуміти .. дякую.
rematnarab

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

є

i = 6 + 7 + 7

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

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

є

i = 5 + 7 + 8

Робота : Початкове значення a дорівнює 5. Використовуйте його в додаванні, а потім збільшуйте його до 6 (поточне значення 6). Збільшення a від поточного значення 6 до 7, щоб отримати інший операнд +. Сума - 12, а поточне значення - 7. Наступний приріст a від 7 до 8 (поточне значення = 8) і додайте його до попередньої суми 12, щоб отримати 20.


ці твердження працюють право наліво або зліва направо?
Абхієет

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. Якщо дивитися на терміни таким чином, ви легко бачите, що вони обидва такі ж, як і комутативні.


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)

тому я 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)

і після того, як оцінка правої частини буде оцінена (включаючи встановлення а) 8, ТОЛЬ a встановлено 6 + 7 + 7 = 20, і таким чином 20 друкується остаточний час.


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

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

є

i = 7 + 6 + 7

Робота: Приріст до / після має "право наліво" Асоціативність, і має перевагу перед посадою, тому перш за все попередній приріст буде вирішуватися як (++a + ++a) => 7 + 6. тоді 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.