int x=1;
int y=2;
x ^= y ^= x ^= y;
Tôi đang mong đợi các giá trị được hoán đổi.Nhưng nó cho x = 0 và y = 1. khi tôi thử bằng ngôn ngữ C, nó cho kết quả chính xác.Tại sao câu lệnh này không hoạt động trong java x^= y^= x^= y;
int x=1;
int y=2;
x ^= y ^= x ^= y;
Tôi đang mong đợi các giá trị được hoán đổi.Nhưng nó cho x = 0 và y = 1. khi tôi thử bằng ngôn ngữ C, nó cho kết quả chính xác.Tại sao câu lệnh này không hoạt động trong java x^= y^= x^= y;
tuyên bố của bạn là tương đương với hình thức mở rộng này:
x = x^(y = y^(x = x^y));
Không giống như trong C, trong Java các toán hạng trái của một nhà điều hành nhị phân được đảm bảo để được đánh giá trước toán hạng phải. Đánh giá xảy ra như sau:
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
Bạn có thể đảo ngược thứ tự của các đối số cho mỗi biểu xor để việc chuyển nhượng được thực hiện trước khi các biến được đánh giá một lần nữa:
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
Đây là một phiên bản nhỏ gọn hơn cũng hoạt động:
x = (y ^= x ^= y)^x;
Nhưng đây thực sự là cách khủng khiếp để hoán đổi hai biến. Đó là một ý tưởng tốt hơn để sử dụng một biến tạm thời.
+1 cho "sử dụng tạm thời". –
+1 Wow - câu trả lời hay. – duffymo
Bạn có chắc chắn không? Tôi nghĩ rằng một nhiệm vụ trở lại đúng, đó là lý do tại sao nếu báo cáo where = đã được sử dụng thay vì == luôn luôn chạy? Điều đó có nghĩa là câu lệnh đầu tiên của bạn giống như x = x^true^true; – AaronM
Đánh dấu là hoàn toàn chính xác về cách nó đánh giá bằng Java. Lý do là JLS §15.7.2., Đánh giá Phép toán trước khi hoạt động, và §15.7, đòi hỏi đánh giá trái sang phải:
Nó tương đương (bằng §15.26.2, nhà khai thác Phân Compound) tới:
x = x^(y = y^(x = (x^y)));
Chúng tôi đánh giá trái sang phải , làm cả hai toán hạng trước khi hoạt động.
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)
Lưu ý rằng hành vi không xác định trong C, bởi vì bạn đang sửa đổi cùng một biến hai lần giữa các điểm chuỗi.
+1 cho các liên kết đến đặc điểm kỹ thuật. –
Hành vi không xác định trong C, vì bạn đang sửa đổi cả x và y hai lần trong một điểm chuỗi. –
Không sử dụng. Sử dụng biến tạm thời bổ sung để hoán đổi 2 là MUCH hiệu quả hơn vì nó không phải tính toán. –
@Imre: Tôi sẽ đưa ra đề xuất của bạn. –