CHỈNH SỬA: Được rồi, hiểu rồi.
Điểm đầu tiên cần làm là rõ ràng bạn không nên sử dụng mã này. Tuy nhiên, khi bạn mở rộng nó, nó sẽ tương đương với:
j = j ^ (i = i ^ (j = j ^ i));
(Nếu chúng ta đang sử dụng một biểu thức phức tạp hơn chẳng hạn foo.bar++ ^= i
, điều quan trọng là nó ++
chỉ được đánh giá một lần, nhưng ở đây tôi tin rằng nó đơn giản hơn.)
Bây giờ, thứ tự đánh giá các toán hạng luôn từ trái sang phải, vì vậy để bắt đầu, chúng ta có:
j = 36 ^ (i = i ^ (j = j ^ i));
Đây (ở trên) là bước quan trọng nhất. Chúng tôi đã kết thúc với 36 là LHS cho hoạt động XOR được thực hiện cuối cùng. LHS không phải là "giá trị j
sau khi RHS đã được đánh giá".
Việc đánh giá RHS của ^ liên quan đến biểu thức "lồng nhau một cấp", vì vậy nó trở thành:
j = 36 ^ (i = 25 ^ (j = j ^ i));
Sau đó, xem xét mức độ lồng ghép sâu nhất, chúng ta có thể thay thế cả hai i
và j
:
j = 36 ^ (i = 25 ^ (j = 25 ^ 36));
... trở thành
j = 36 ^ (i = 25 ^ (j = 61));
Việc gán cho j
trong RHS xảy ra đầu tiên, nhưng dù sao thì kết quả sau đó vẫn được ghi đè ở cuối, vì vậy chúng ta có thể bỏ qua điều đó - không có đánh giá nào nữa j
trước khi thực hiện nhiệm vụ cuối cùng:
j = 36 ^ (i = 25 ^ 61);
Điều này bây giờ tương đương với:
i = 25 ^ 61;
j = 36 ^ (i = 25 ^ 61);
Hoặc là:
i = 36;
j = 36 ^ 36;
Trở thành:
i = 36;
j = 0;
Tôi nghĩ tất cả đều đúng và nó sẽ có câu trả lời đúng ... xin lỗi Eric Lippert nếu một số chi tiết về thứ tự đánh giá hơi sai :(