Что такое x после "x = x++"?
что происходит (за занавесками), когда это выполняется?
int x = 7;
x = x++;
то есть, когда переменная пост инкрементируется и присваивается себе в одном операторе? Я скомпилировал и выполнил это. x
еще 7 даже после всего заявление. В моей книге говорится, что x
увеличивается!
17 ответов:
x
не увеличивается. Но вы присваиваете старое значениеx
обратно в себя.
x = x++;
x++
С шагомx
и возвращает его старое значение.x =
присваивает себе старое значение.Итак, в конце концов,
x
возвращается к исходному значению.
инструкции:
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 полностью задан, и нет места для изменения платформы. Компиляторы могут изменять порядок операций только в том случае, если это не изменяет результат выполнения кода из перспектива текущего потока. В этом случае компилятору будет разрешено оптимизировать весь оператор, потому что можно доказать, что это не-op.
в случае, если это еще не очевидно:
- "x = x++;" почти наверняка является ошибкой в любой программе.
- ОП (для исходного вопроса!) вероятно, означало " x++;", а не"x = x++;".
- заявления, сочетающие автоматическое ВКЛ/декремента и назначения ту же переменную трудно понять, и следует избегать независимо от их правильности. Просто нет необходимости писать такой код.
надеюсь, кодовые шашки, такие как 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 пост-инкремент (++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
- стек здесь относится к стеку операндов, локальный: X индекс: 1 тип: int
приращение происходит после вызова x, поэтому x по-прежнему равно 7. ++x будет равно 8, Когда x называется
при повторном назначении значения для
x
это все еще 7. Попробуйx = ++x
и вы получите еще 8x++; // 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 работает следующим образом:
- сохранить Предыдущее значение операнда.
- увеличить значение операнда.
- возвращает Предыдущее значение операнда.
Итак, утверждение
int x = 7; x = x++;
будет оцениваться следующим образом:
- x инициализируется значением 7
- оператор Post increment сохраняет Предыдущее значение x, т. е. 7 для возврата.
- увеличивает x, Итак, теперь x - 8
- возвращает Предыдущее значение 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
это пре-инкремент->
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++;
Это оператор постинкремента. Это следует понимать как"использовать значение операнда, а затем увеличить операнд".
Если вы хотите, чтобы произошло обратное, т. е." увеличить операнд, а затем использовать значение операнда", вы должны использовать оператор предварительного приращения, как показано ниже.
x = ++x;
этот оператор сначала увеличивает значение X на 1, а затем присваивает значение х.
Это потому, что вы использовали оператор post-increment. В следующей строке кода
x = x++;
что происходит, так это то, что вы присваиваете значение x x. x++ инкременты x после того, как значение x присваивается x. Вот как работают операторы после инкремента. Они работают после выполнения инструкции. Таким образом, в вашем коде x возвращается сначала после того, как затем он увеличивается.
Если ты
x = ++x;
ответ будет 8, потому что вы использовали пре-инкремент оператор. Это увеличивает значение сначала перед возвращением значения x.