Was passiert (hinter den Vorhängen), wenn dies ausgeführt wird?
int x = 7;
x = x++;
Das heißt, wenn eine Variable nachträglich inkrementiert und sich selbst in einer Anweisung zugewiesen wird? Ich habe dies kompiliert und ausgeführt. x
ist auch nach der gesamten Aussage noch 7 . In meinem Buch heißt es, dass x
inkrementiert wird!
java
operators
post-increment
Michael
quelle
quelle
int x = 7; x = ++x;
Natürlich ist der Code immer noch schrecklich, Sie müssen ihn nicht neu zuweisen.int x = 7; x++;
reicht.x += 1
, außer vielleicht in Schleifen.for(int x=0; x<7; x++)
Antworten:
x
wird inkrementiert. Aber Sie weisen den alten Wert vonx
back in sich selbst zu.x++
erhöhtx
und gibt seinen alten Wert zurück.x =
weist sich den alten Wert wieder zu.Wird also am Ende
x
wieder seinem Anfangswert zugewiesen.quelle
x
wird zuerst inkrementiert, bevor es in diesem Fall gelesen wird, sodass Sie am Ende mitx + 1
.ist äquivalent zu
quelle
x=x+1
anstattx++
x = x++
, nicht nur das Post-Inkrementx++
.x = ++x;
auch äquivalentint tmp = x; ++x; x = tmp;
ist. Aus welcher Logik können wir also schließen, dass Ihre Antwort richtig ist (welche es ist)?x=x++
=MOV x,tmp; INC x; MOV tmp,x
Die Aussage:
ist äquivalent zu:
Kurz gesagt, die Aussage hat keine Wirkung.
Die wichtigsten Punkte:
Der Wert eines Postfix-Inkrement- / Dekrement-Ausdrucks ist der Wert des Operanden vor dem Inkrementieren / Dekrementieren. (Im Fall eines Präfixformulars ist der Wert der Wert des Operanden nach der Operation.)
Die RHS eines Zuweisungsausdrucks wird vollständig ausgewertet (einschließlich etwaiger Inkremente, Dekremente und / oder anderer Nebenwirkungen), bevor der Wert der LHS zugewiesen wird.
Beachten Sie, dass im Gegensatz zu C und C ++ die Reihenfolge der Auswertung eines Ausdrucks in Java vollständig angegeben ist und kein Platz für plattformspezifische Variationen vorhanden ist. Compiler dürfen die Vorgänge nur neu anordnen, wenn dies das Ergebnis der Ausführung des Codes aus der Perspektive des aktuellen Threads nicht ändert. In diesem Fall kann ein Compiler die gesamte Anweisung optimieren, da nachgewiesen werden kann, dass es sich um ein No-Op handelt.
Falls es nicht schon offensichtlich ist:
Hoffentlich markieren Codeprüfer wie FindBugs und PMD Code wie diesen als verdächtig.
quelle
x++
stattx = x++
.Es hat undefiniertes Verhalten in C und für Java siehe diese Antwort . Es hängt vom Compiler ab, was passiert.
quelle
Ein Konstrukt wie
x = x++;
zeigt an, dass Sie wahrscheinlich falsch verstehen, was der++
Operator tut:Schreiben wir dies neu, um dasselbe zu tun, basierend auf dem Entfernen des
++
Operators:Lassen Sie es uns jetzt umschreiben, um (was ich denke) zu tun, was Sie wollten:
Die Subtilität hier ist, dass der
++
Operator die Variable ändertx
, im Gegensatz zu einem Ausdruck wiex + x
, der einen int-Wert ergibt, aber die Variablex
selbst unverändert lässt. Betrachten Sie ein Konstrukt wie die ehrwürdigefor
Schleife:Beachten Sie die
i++
dort? Es ist der gleiche Operator. Wir könnten diesefor
Schleife so umschreiben und sie würde sich genauso verhalten:Ich empfehle
++
in den meisten Fällen auch, den Operator nicht in größeren Ausdrücken zu verwenden. Wegen der Subtilität , wenn es die ursprüngliche Variable modifiziert in prä- gegen Post-Inkrement (++x
undx++
ist), ist es sehr einfach , subtile Bugs einzuführen, die nur schwer aufzuspüren.quelle
Gemäß dem aus den Klassendateien erhaltenen Bytecode,
Beide Zuweisungen erhöhen x, aber die Differenz ist das Timing von
when the value is pushed onto the stack
In
Case1
wird Push vor dem Inkrement ausgeführt (und später zugewiesen) (was im Wesentlichen bedeutet, dass Ihr Inkrement nichts bewirkt).In
Case2
tritt Inkrement zuerst auf (macht es 8) und wird dann auf den Stapel geschoben (und dann x zugewiesen)Fall 1:
Bytecode:
Fall 2:
Bytecode
quelle
Es wird nach "
x = x++;
" erhöht . Es wäre 8, wenn Sie "x = ++x;
" tun würden .quelle
x = x++
, sollte es 8 sein.Der Post-Increment-Operator funktioniert wie folgt:
Also die Aussage
würde wie folgt bewertet werden:
X wird zwar erhöht, aber da x ++ x das Ergebnis zurückweist, wird der Wert von x auf den vorherigen Wert überschrieben.
quelle
Das Inkrementieren erfolgt nach dem Aufruf von x, sodass x immer noch gleich 7 ist. ++ x wäre gleich 8, wenn x aufgerufen wird
quelle
Wenn Sie den Wert erneut zuweisen
x
, ist er immer noch 7. Versuchenx = ++x
Sie es und Sie erhalten 8 weitere Aufgabenquelle
weil x ++ den Wert erhöht, nachdem er der Variablen zugewiesen wurde. so weiter und während der Ausführung dieser Zeile:
Die Varialbe x hat weiterhin den ursprünglichen Wert (7), verwendet jedoch x erneut in einer anderen Zeile, z
wird dir 8 geben.
Wenn Sie einen inkrementierten Wert von x für Ihre Zuweisungsanweisung verwenden möchten, verwenden Sie
Dadurch wird x um 1 erhöht, und dann wird der Variable x dieser Wert zugewiesen.
[Bearbeiten] anstelle von x = x ++ ist es nur x ++; Ersteres weist sich den ursprünglichen Wert von x zu, sodass in dieser Zeile eigentlich nichts unternommen wird.
quelle
Was passiert wann
int x = 7; x = x++;
?ans ->
x++
bedeutet, dass Sie zuerst den Wert von x für den Ausdruck verwenden und ihn dann um 1 erhöhen.Dies geschieht in Ihrem Fall. Der Wert von x bei RHS wird in die Variable x bei LHS kopiert und dann der Wert von
x
um 1 erhöht.In ähnlicher Weise
++x
bedeutet->
, den Wert von x zuerst um eins zu erhöhen und dann im Ausdruck zu verwenden.Wenn Sie dies tun, erhalten
x = ++x ; // where x = 7
Sie in Ihrem Fall den Wert 8.
Versuchen Sie zur besseren Übersicht herauszufinden, wie viele printf-Anweisungen den folgenden Code ausführen
quelle
x
8++x
Das Vorinkrement->
x wird vor der Verwendungx++
inkrementiert. Das Nachinkrement->
x wird nach der Verwendung inkrementiertquelle
Das heißt also:
x++
ist nicht gleichx = x+1
weil:
und jetzt scheint es ein bisschen seltsam:
sehr compilerabhängig!
quelle
(x = x + 1, x-1)
in C, wo durch Kommas getrennte Ausdrücke zulässig sind.x = x ++;
Dies ist der Post-Inkrement-Operator. Es sollte verstanden werden als "Verwenden Sie den Wert des Operanden und erhöhen Sie dann den Operanden".
Wenn Sie möchten, dass das Gegenteil der Fall ist, dh "Inkrementieren Sie den Operanden und verwenden Sie dann den Wert des Operanden", müssen Sie den Operator vor dem Inkrementieren wie unten gezeigt verwenden.
x = ++ x;
Dieser Operator erhöht zuerst den Wert von x um 1 und weist den Wert dann wieder x zu.
quelle
Ich denke, diese Kontroverse kann gelöst werden, ohne auf Code einzugehen und nur nachzudenken.
Betrachten Sie i ++ & ++ i als Funktionen, z. B. Func1 & Func2.
Jetzt ist i = 7;
Func1 (i ++) gibt 7 zurück, Func2 (++ i) gibt 8 zurück (jeder weiß das). Intern erhöhen beide Funktionen i auf 8, geben jedoch unterschiedliche Werte zurück.
Also ruft i = i ++ die Funktion Func1 auf. Innerhalb der Funktion erhöht sich i auf 8, aber nach Abschluss gibt die Funktion 7 zurück.
Also wird letztendlich 7 i zugewiesen. (Also am Ende ist i = 7)
quelle
Dies liegt daran, dass Sie einen Post-Inkrement-Operator verwendet haben. In dieser folgenden Codezeile
Was passiert ist, dass Sie x den Wert von x zuweisen. x ++ erhöht x, nachdem der Wert von x x zugewiesen wurde. So funktionieren Operatoren nach dem Inkrementieren. Sie funktionieren, nachdem eine Anweisung ausgeführt wurde. In Ihrem Code wird x also zuerst zurückgegeben und anschließend inkrementiert.
Wenn du. .. getan hast
Die Antwort wäre 8, da Sie den Operator vor dem Inkrementieren verwendet haben. Dies erhöht zuerst den Wert, bevor der Wert von x zurückgegeben wird.
quelle