First, let's remember some properties of XOR (exclusive-OR):

- A ^ A = 0
- element neutral: A ^ 0 = A
- commutative: A ^ B = B ^ A
- associative: (A ^ B) ^ C = A ^ (B ^ C)

Here's an explanation taken from here :

The key to convincing yourself that this works is to keep track of the original values of x and y. Let A be the original value of x (that is, the value x has before executing these three lines of code). Similarly, let B be the original value of y.

We can comment on each line of code to see what's happening.

```
// x == A, y == B
x = x ^ y ;
// x == A ^ B, y == B
y = x ^ y ;
// x == A ^ B
// y == (A ^ B) ^ B == A ^ (B ^ B) (por associatividade)
// == A ^ 0 (devido à propriedade z ^ z == 0)
// == A (devido à propriedade z ^ 0 == z)
x = x ^ y ;
// x == ( A ^ B ) ^ A
// == ( A ^ A ) ^ B (por associatividade/comutatividade)
// == 0 ^ B (devido à propriedade z ^ z == 0)
// == B (devido À propriedade z ^ 0 == z)
// y == A
```

After the second statement has run, y = A. After the third statement , x = B.