Co się dzieje (za zasłonami), gdy jest to wykonywane?
int x = 7;
x = x++;
To znaczy, kiedy zmienna jest zwiększana i przypisywana do siebie w jednej instrukcji? Skompilowałem i wykonałem to. x
wynosi wciąż 7, nawet po całym oświadczeniu . W mojej książce jest napisane, że x
jest zwiększane!
java
operators
post-increment
Michael
źródło
źródło
int x = 7; x = ++x;
oczywiście nadal jest to okropny kod, nie musisz zmieniać przypisania.int x = 7; x++;
wystarczy.x += 1
, chyba że w pętlach.for(int x=0; x<7; x++)
Odpowiedzi:
x
zwiększa się. Ale przypisujesz starą wartość zx
powrotem do siebie.x++
zwiększax
i zwraca starą wartość.x =
przypisuje starą wartość z powrotem do siebie.W końcu
x
zostaje przypisany z powrotem do wartości początkowej.źródło
x
jest najpierw zwiększany, zanim zostanie odczytany w takim przypadku, więc skończyszx + 1
.jest równa
źródło
x=x+1
zamiastx++
x = x++
, a nie tylko przyrost postux++
.x = ++x;
jest to, że jest to równoważneint tmp = x; ++x; x = tmp;
, więc jaką logiką możemy wywnioskować, że twoja odpowiedź jest poprawna (która to jest)?x=x++
=MOV x,tmp; INC x; MOV tmp,x
Twierdzenie:
jest równa:
Krótko mówiąc, oświadczenie nie ma wpływu.
Kluczowe punkty:
Wartość wyrażenia inkrementacji / dekrementacji Postfix jest wartością operandu przed inkrementacją / dekrementacją. (W przypadku formularza Prefiks wartość jest wartością argumentu po operacji),
RHS wyrażenia przypisania jest całkowicie oceniane (w tym wszelkie przyrosty, zmniejszenia i / lub inne skutki uboczne) przed przypisaniem wartości do LHS.
Zauważ, że w przeciwieństwie do C i C ++, kolejność oceny wyrażenia w Javie jest całkowicie określona i nie ma miejsca na zmienne specyficzne dla platformy. Kompilatory mogą zmieniać kolejność operacji tylko wtedy, gdy nie zmienia to wyniku wykonania kodu z perspektywy bieżącego wątku. W takim przypadku kompilator byłby w stanie zoptymalizować całą instrukcję, ponieważ można udowodnić, że nie działa.
W przypadku, gdy nie jest to już oczywiste:
Mamy nadzieję, że weryfikatory kodu, takie jak FindBugs i PMD, oznaczą ten kod jako podejrzany.
źródło
x++
zamiastx = x++
.Niezdefiniowane zachowanie w C i dla Javy zobacz tę odpowiedź . To zależy od kompilatora, co się stanie.
źródło
Taka konstrukcja
x = x++;
wskazuje, że prawdopodobnie nie rozumiesz, co++
robi operator:Przepiszmy to, aby zrobić to samo, w oparciu o usunięcie
++
operatora:Teraz przepiszmy to, aby zrobić (co myślę), co chciałeś:
Subtelność polega na tym, że
++
operator modyfikuje zmiennąx
, w przeciwieństwie do wyrażenia takiego jakx + x
, który oceniałby na wartość int, ale pozostawiałx
samą zmienną bez zmian. Rozważmy konstrukcję taką jak czcigodnafor
pętla:Zwróć uwagę
i++
na tam? To ten sam operator. Moglibyśmy przepisać tęfor
pętlę w ten sposób i zachowałby się tak samo:Odradzam również używanie
++
operatora w większych wyrażeniach w większości przypadków. Z powodu subtelności, kiedy modyfikuje oryginalną zmienną w przyrostach przed i po (++x
ix++
odpowiednio), bardzo łatwo jest wprowadzić subtelne błędy, które są trudne do wyśledzenia.źródło
Zgodnie z kodem bajtu uzyskanym z plików klas,
Oba przypisania zwiększają x, ale różnicą jest czas
when the value is pushed onto the stack
W trybie
Case1
Push występuje (a następnie przypisywany) przed przyrostem (co oznacza, że przyrost nie robi nic)W
Case2
Przyrost występuje najpierw (co daje 8), a następnie wypychany na stos (a następnie przypisywany do x)Przypadek 1:
Kod bajtowy:
Przypadek 2:
Kod bajtowy
źródło
Jest zwiększany po „
x = x++;
”. Byłoby to 8, gdybyś zrobił „x = ++x;
”.źródło
x = x++
, powinien wynosić 8.Operator Post Increment działa w następujący sposób:
Więc oświadczenie
zostanie oceniony w następujący sposób:
Tak więc x jest rzeczywiście zwiększony, ale ponieważ x ++ przypisuje wynik z powrotem do x, więc wartość x jest zastępowana do poprzedniej wartości.
źródło
Inkrementacja następuje po wywołaniu x, więc x nadal wynosi 7. ++ x będzie równe 8, gdy x zostanie wywołane
źródło
Po ponownym przypisaniu wartości
x
nadal jest to 7. Spróbuj,x = ++x
a dostaniesz 8 innych do zrobieniaźródło
ponieważ x ++ zwiększa wartość PO przypisaniu jej do zmiennej. i podczas wykonywania tego wiersza:
varialbe x nadal będzie miał oryginalną wartość (7), ale użyje x ponownie w innym wierszu, takim jak
da ci 8.
jeśli chcesz użyć zwiększonej wartości x na wyciągu przypisania, użyj
To zwiększy x o 1, NASTĘPNIE przypisze tę wartość do zmiennej x.
[Edytuj] zamiast x = x ++, to tylko x ++; ten pierwszy przypisuje sobie oryginalną wartość x, więc w rzeczywistości nie robi nic w tym wierszu.
źródło
Co się stanie kiedy
int x = 7; x = x++;
?ans ->
x++
oznacza najpierw użyj wartości x dla wyrażenia, a następnie zwiększ ją o 1.Tak dzieje się w twoim przypadku. Wartość x na RHS jest kopiowana do zmiennej x na LHS, a następnie wartość
x
jest zwiększana o 1.Podobnie
++x
oznacza->
zwiększenie wartości x najpierw o jeden, a następnie użycie wyrażenia.Więc w twoim przypadku
x = ++x ; // where x = 7
otrzymasz wartość 8.
Dla większej przejrzystości spróbuj dowiedzieć się, ile instrukcji printf wykona następujący kod
źródło
x
daje 8, ale jest to 7 - przyrost następuje między odczytem a przypisaniem++x
jest przyrostem->
x jest zwiększany przed użyciemx++
jest przyrostem->
x jest zwiększany po użyciuźródło
Oznacza to, że:
x++
nie jest równyx = x+1
ponieważ:
a teraz wydaje się to trochę dziwne:
bardzo zależy od kompilatora!
źródło
(x = x + 1, x-1)
w C, gdzie dozwolone są wyrażenia oddzielone przecinkami.x = x ++;
To jest operator post-increment. Należy to rozumieć jako „Użyj wartości operandu, a następnie zwiększ operand”.
Jeśli chcesz, aby miało miejsce odwrotność, tj. „Zwiększ operand, a następnie użyj wartości operandu”, musisz użyć operatora wstępnej inkrementacji, jak pokazano poniżej.
x = ++ x;
Ten operator najpierw zwiększa wartość x o 1, a następnie przypisuje wartość z powrotem do x.
źródło
Myślę, że ten spór można rozwiązać bez wchodzenia w kod i myślenia.
Rozważ i ++ i ++ i jako funkcje, powiedzmy Func1 i Func2.
Teraz i = 7;
Func1 (i ++) zwraca 7, Func2 (++ i) zwraca 8 (wszyscy to wiedzą). Wewnętrznie obie funkcje zwiększają i do 8, ale zwracają różne wartości.
Więc i = i ++ wywołuje funkcję Func1. Wewnątrz funkcji zwiększa się do 8, ale po zakończeniu funkcja zwraca 7.
Ostatecznie 7 zostaje przydzielonych do i. (Więc w końcu i = 7)
źródło
Wynika to z faktu, że użyłeś operatora post-increment. W następującym wierszu kodu
Tak się składa, że przypisujesz wartość x do x. przyrosty x ++ x po przypisaniu wartości x do x. Tak działają operatorzy działający po dodaniu. Działają po wykonaniu instrukcji. Więc w twoim kodzie x jest zwracane najpierw, a następnie zwiększane.
Jeśli tak
Odpowiedź brzmiałaby 8, ponieważ użyłeś operatora wstępnego przyrostu. To zwiększa wartość najpierw przed zwróceniem wartości x.
źródło