Câu trả lời thực tế là:
- Trình biên dịch ưu tiên "i == 0", đánh giá là đúng.
- Sau đó, nó sẽ đánh giá i = 1 là TRUE hoặc FALSE và vì các toán tử gán được biên dịch không bao giờ thất bại (nếu không chúng sẽ không biên dịch), nó cũng đánh giá là đúng.
- Vì cả hai câu lệnh đều đánh giá là đúng và TRUE && TRUE đánh giá là TRUE, nên câu lệnh if sẽ đánh giá thành TRUE.
Để chứng minh, chỉ cần nhìn vào đầu ra asm của trình biên dịch của bạn cho mã bạn đã nhập (tất cả các nhận xét là của riêng tôi):
mov dword ptr [rbp - 8], 0 ; i = 0;
cmp dword ptr [rbp - 8], 0 ; i == 0?
sete al ; TRUE (=1)
mov cl, al
and cl, 1 ; = operator always TRUE
movzx edx, cl
mov dword ptr [rbp - 8], edx ; set i=TRUE;
test al, 1 ; al never changed,
; so final ans is TRUE
Đầu ra asm ở trên là từ CLANG, nhưng tất cả các trình biên dịch khác mà tôi đã xem đều cho đầu ra tương tự. Điều này đúng với tất cả các trình biên dịch trên trang web đó, cho dù chúng là trình biên dịch C hay C ++ thuần túy, tất cả đều không có bất kỳ trình duyệt nào để thay đổi chế độ của trình biên dịch (theo mặc định là C ++ cho trình biên dịch C ++)
Lưu ý rằng trình biên dịch của bạn không thực sự đặt i = 1, nhưng i = TRUE (có nghĩa là bất kỳ giá trị nguyên 32 bit nào không bằng 0). Đó là bởi vì toán tử && chỉ đánh giá xem một câu lệnh là TRUE hay FALSE, sau đó đặt kết quả theo kết quả đó. Để chứng minh, hãy thử thay đổi i = 1 thành i = 2 và bạn có thể tự quan sát rằng không có gì thay đổi. Xem cho chính mình bằng bất kỳ trình biên dịch trực tuyến nào tại Compiler Explorer
i
được đặt thành1
.