Frage

int x=1;
int y=2;
x ^= y ^= x ^= y;

Ich bin die Werte erwartet swapped.But zu sein gibt es x = 0 und y = 1. wenn ich in der C-Sprache versucht, es gibt das richtige Ergebnis.

War es hilfreich?

Lösung

ist Ihre Aussage entspricht in etwa dieser erweiterten Form:

x = x ^ (y = y ^ (x = x ^ y));

Im Gegensatz zu C, in Java der linken Operanden eines Binäroperators garantiert vor dem rechten Operanden ausgewertet werden. Auswertung erfolgt wie folgt:

x = x ^ (y = y ^ (x = x ^ y))
x = 1 ^ (y = 2 ^ (x = 1 ^ 2))
x = 1 ^ (y = 2 ^ (x = 3))
x = 1 ^ (y = 2 ^ 3)             // x is set to 3 
x = 1 ^ (y = 1)
x = 1 ^ 1                       // y is set to 1
x = 0                           // x is set to 0

Sie können die Reihenfolge der Argumente zu jedem xor Ausdruck umkehren, so dass die Zuordnung erfolgt, bevor die Variable erneut ausgewertet wird:

x = (y = (x = x ^ y) ^ y) ^ x
x = (y = (x = 1 ^ 2) ^ y) ^ x
x = (y = (x = 3) ^ y) ^ x 
x = (y = 3 ^ y) ^ x             // x is set to 3
x = (y = 3 ^ 2) ^ x
x = (y = 1) ^ x
x = 1 ^ x                       // y is set to 1
x = 1 ^ 3
x = 2                           // x is set to 2

Dies ist eine kompaktere Version, die auch funktioniert:

x = (y ^= x ^= y) ^ x;

Aber das ist eine wirklich schreckliche Art und Weise zu tauschen zwei Variablen. Es ist eine viel bessere Idee, eine temporäre Variable zu verwenden.

Andere Tipps

Mark ist völlig richtig, wie es wertet in Java. Der Grund dafür ist JLS §15.7.2. , auswerten Operanden vor der Operation und §15.7 , die erfordert Auswertung links nach rechts:

Es entspricht (von §15.26. 2 , Verbindung Zuweisungsoperator) zu:

x = x ^ (y = y ^ (x = (x ^ y)));

Wir werten links nach rechts, vor der Operation beiden Operanden zu tun.

x = 1 ^ (y = y ^ (x = (x ^ y))); // left of outer 
x = 1 ^ (y = 2 ^ (x = (x ^ y))); // left of middle 
x = 1 ^ (y = 2 ^ (x = (1 ^ y))); // left of inner
x = 1 ^ (y = 2 ^ (x = (1 ^ 2))); // right of inner
x = 1 ^ (y = 2 ^ (x = 3)); // inner xor (right inner assign)
x = 1 ^ (y = 2 ^ 3); // inner assign (right middle xor)
x = 1 ^ (y = 1); // middle xor (right middle assign)
x = 1 ^ 1; // middle assign (right outer xor)
x = 0; // outer xor (right outer assign)

Beachten Sie, dass es ist nicht definiertes Verhalten in C, da Sie die gleiche Variable zu modifizieren sind zweimal zwischen Sequenzpunkten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top