Domanda

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

Mi aspetto i valori da swapped.But dà x = 0 ey = 1. quando ho provato in linguaggio C che dà il risultato corretto.

È stato utile?

Soluzione

La tua affermazione è più o meno equivalente a questa forma estesa:

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

A differenza di C, in Java è garantita l'operando a sinistra di un operatore binario da valutare prima che l'operando di destra. La valutazione avviene nel seguente modo:

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

Si potrebbe invertire l'ordine degli argomenti di ogni espressione XOR in modo che l'assegnazione avviene prima che la variabile viene valutata di nuovo:

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

Questa è una versione più compatta che funziona anche:

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

Ma questo è un modo veramente orribile per scambiare due variabili. E 'un'idea molto meglio utilizzare una variabile temporanea.

Altri suggerimenti

Mark è del tutto corretto su come si valuta in Java. Il motivo è JLS §15.7.2. , Valutare Operandi prima del funzionamento e §15.7 , che richiede una valutazione da sinistra a destra:

E 'equivalente (da §15.26. 2 , Compound operatori di assegnazione) a:

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

Si valutano sinistra a destra, facendo entrambi gli operandi prima dell'operazione.

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)

Si noti che è un comportamento indefinito in C, perché si sta modificando la stessa variabile due volte tra i punti di sequenza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top