Что такое 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.