Что Х "Х = Х++"?

что происходит (за шторами), когда это выполняется?

int x = 7;
x = x++;

то есть, когда переменная post увеличивается и присваивается себе в одном операторе? Я собрал и выполнил это. x еще 7 даже после всего заявление. В моей книге говорится, что x увеличивается!

17 ответов


x не увеличивается. Но вы присваиваете старое значение x обратно в себя.


x = x++;
  1. x++ С шагом x и возвращает старое значение.
  2. x = присваивает себе старое значение.

Итак, в конце концов,x возвращается к исходному значению.


x = x++;

эквивалентно

int tmp = x;
x++;
x = tmp;

инструкции:

x = x++;

эквивалентно:

tmp = x;   // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
           //     happens after the value is captured.
x = tmp;   // ... this is the effect of assignment operation which is
           //     (unfortunately) clobbering the incremented value.

короче говоря, утверждение не имеет никакого эффекта.

ключевые моменты:

  • значение постфиксного выражения инкремента / декремента является значением операнда до происходит приращение/уменьшение. (В случае префиксной формы значением является значение операнда после операции)

  • в RHS выражения назначения полностью оценивается (включая любые приращения, декременты и/или другие побочные эффекты) до значение присваивается LHS.

обратите внимание, что в отличие от C и c++, порядок оценки выражения в Java полностью задан, и нет места для изменения конкретной платформы. Компиляторам разрешается изменять порядок операций только в том случае, если это не изменяет результат выполнения кода из перспектива текущего потока. В этом случае компилятору будет разрешено оптимизировать весь оператор, потому что можно доказать, что это no-op.


в случае, если это еще не очевидно:

  • "x = x++;" почти наверняка является ошибкой в любой программе.
  • OP (для исходного вопроса!) вероятно, означало " x++;", а не"x = x++;".
  • операторы, которые объединяют auto inc / decrement и назначение на ту же переменную трудно понять, и следует избегать независимо от их правильности. Просто нет необходимости писать такой код.

надеюсь, кодовые шашки, такие как FindBugs и PMD, будут помечать такой код как подозрительный.


int x = 7;
x = x++;

Он имеет неопределенное поведение в C и для Java см. ответ. Это зависит от компилятора, что происходит.


конструкции типа x = x++; указывает, что вы, вероятно, неправильно поняли, что ++ оператор:

// original code
int x = 7;
x = x++;

давайте перепишем это, чтобы сделать то же самое, основываясь на удалении ++ оператор:

// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7

теперь давайте перепишем его, чтобы сделать (что я думаю), что вы хотели:

// original code
int x = 7;
x++;

тонкость здесь в том, что ++ оператор изменяет переменную x, в отличие от таких выражений, как x + x, который оценил бы значение int, но оставьте переменную x сама без изменений. Рассмотрим конструкцию, подобную достопочтенному for петли:

for(int i = 0; i < 10; i++)
{
    System.out.println(i);
}

уведомления i++ там? Это тот же оператор. Мы могли бы переписать это for цикл, как это, и он будет вести себя так же:

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

я также рекомендую не использовать ++ оператор в больших выражениях в большинстве случаев. Из-за тонкости , когда он изменяет исходную переменную в pre-versus post-increment (++x и x++, соответственно), очень легко ввести тонкие ошибки, которые трудно отследить.


в соответствии с байтовым кодом полученных из class-файлов

оба задания увеличивают x, но разница-это время when the value is pushed onto the stack

на Case1, Push происходит (а затем назначается) перед инкрементом (по существу, это означает, что ваш инкремент ничего не делает)

на Case2, инкремент происходит сначала (что делает его 8), а затем нажимается на стек(а затем назначается x)

случае 1:

int x=7;
x=x++;

Байт-Код:

0  bipush 7     //Push 7 onto  stack
2  istore_1 [x] //Pop  7 and store in x
3  iload_1  [x] //Push 7 onto stack
4  iinc 1 1 [x] //Increment x by 1 (x=8)
7  istore_1 [x] //Pop 7 and store in x
8  return       //x now has 7

Пример 2:

int x=7; 
x=++x;

Байт-Код

0  bipush 7     //Push 7 onto stack
2  istore_1 [x] //Pop 7 and store in x
3  iinc 1 1 [x] //Increment x by 1 (x=8)
6  iload_1  [x] //Push x onto stack
7  istore_1 [x] //Pop 8 and store in x
8  return       //x now has 8
  • стек здесь относится к стеку операндов, local: X index: 1 type: int

он увеличивается после "x = x++;". Было бы 8, если бы вы сделали"x = ++x;".


приращение происходит после вызова x, поэтому x по-прежнему равно 7. ++x будет равен 8, Когда x называется


при повторном назначении значения для x это все еще 7. Попробуй!--2--> и вы получите еще 8

x++; // don't re-assign, just increment
System.out.println(x); // prints 8

потому что x++ увеличивает значение после присвоения его переменной. так и во время выполнения этой строки:

x++;

varialbe x по-прежнему будет иметь исходное значение (7), но снова использовать x в другой строке, например

System.out.println(x + "");

даст вам 8.

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

++x;

это увеличит x на 1, а затем присвоит это значение переменной x.

[редактирование] вместо x = x++ это просто x++; первый присваивает себе исходное значение x, поэтому он фактически ничего не делает в этой строке.


оператор Post Increment работает следующим образом:

  1. сохранить Предыдущее значение операнда.
  2. увеличить значение операнда.
  3. возвращает Предыдущее значение операнда.

Итак, утверждение

int x = 7;
x = x++; 

будет оцениваться следующим образом:

  1. X инициализируется значением 7
  2. оператор post increment сохраняет Предыдущее значение x, т. е. 7 для возврата.
  3. увеличивает x, Итак, теперь x - 8
  4. возвращает Предыдущее значение x, т. е. 7, и оно назначается обратно x, поэтому x снова становится 7

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


что происходит, когда int x = 7; x = x++;?

ans ->x++ означает сначала использовать значение x для выражения, а затем увеличить его на 1.
Вот что происходит в вашем случае. Значение x на RHS копируется в переменную x на LHS, а затем значение x увеличивается на 1.

аналогично ++x означает -> сначала увеличьте значение x на единицу ,а затем используйте в выражении.
Так что в вашем случае, если вы делаете x = ++x ; // where x = 7
вы получите значение 8.

для большей ясности попробуйте узнать, сколько оператор printf будет выполнять следующий код

while(i++ <5)   
  printf("%d" , ++i);   // This might clear your concept upto  great extend

++x является pre-increment -> X увеличивается до используется
x++ - Это пост-инкремент -> X увеличивается после используется

int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented

это означает: x++ не равно x = x+1

потому что:

int x = 7; x = x++;
x is 7

int x = 7; x = x = x+1;
x is 8

и теперь это кажется немного странным:

int x = 7; x = x+=1;
x is 8

очень зависит от компилятора!


Я думаю, что этот спор можно решить, не вдаваясь в код и просто думая.

рассмотрим i++ & ++i как функции, скажем Func1 & Func2.

теперь i=7;
Func1 (I++) возвратит 7, Func2 (++i) возвратит 8 (все это знают). Внутренне обе функции увеличивают i до 8, но они возвращают разные значения.

поэтому i = i++ вызывает функцию Func1. Внутри функции I увеличивается до 8, но по завершении функция возвращает 7.

таким образом, в конечном итоге 7 выделяется i. (Итак, в конце концов, i = 7)


x = x++;

Это оператор post-increment. Его следует понимать как "использовать значение операнда, а затем увеличивать операнд".

Если вы хотите, чтобы произошло обратное.e "увеличьте операнд, а затем используйте значение операнда", вы должны использовать оператор предварительного приращения, как показано ниже.

x = ++x;

этот оператор сначала увеличивает значение x на 1, а затем присваивает значение x.


это потому, что вы использовали оператор post-increment. В этой следующей строке кода

x = x++;

что происходит, так это то, что вы присваиваете значение x x. X++ увеличивает x после того, как значение x присваивается x. Именно так работают операторы post-increment. Они работают после выполнения заявления. Таким образом, в вашем коде x возвращается сначала после того, как он впоследствии увеличивается.

Если ты

x = ++x;

ответ будет 8, потому что вы использовали пре-инкремент оператор. Это увеличивает значение сначала перед возвращением значения x.