Hãy suy nghĩ booleans, không phải bit
Tóm lại, giải pháp của giáo sư của bạn tốt hơn (nhưng vẫn sai, nói đúng ra, xem thêm) vì nó sử dụng toán tử boolean thay vì toán tử bitwise và coi booleans là số nguyên. Biểu thức c==1
để biểu thị "c là đúng" là không chính xác bởi vì nếu c có thể là một số (theo sự phân công đã nêu) thì mọi giá trị khác không của c sẽ được coi là đại diệntrue
.
Xem câu hỏi này về lý do tại sao không nên so sánh booleans với 0 hoặc 1, ngay cả khi an toàn để làm như vậy.
Một lý do rất tốt để không sử dụng xor
là đây là độc quyền hoặc hoạt động bit-khôn ngoan . Nó xảy ra để làm việc trong ví dụ của bạn bởi vì cả phía bên trái và bên phải là các biểu thức boolean chuyển đổi thành 1 hoặc 0 (xem lại 1 ).
Boolean độc quyền - hoặc trên thực tế !=
.
Phá vỡ biểu thức
Để hiểu rõ hơn về giải pháp của giáo sư của bạn, dễ dàng nhất để thay thế các toán tử boolean bằng các mã tương đương "mã thông báo thay thế" của chúng, biến nó thành mã có thể chuyển đổi tốt hơn (imho) và mã C ++ hoàn toàn tương đương: Sử dụng 'không' cho '!' và 'và' cho '&&' bạn nhận được
(not a and not b) != c
Thật không may, không có exclusive_or
toán tử logic nào khác not_eq
, không hữu ích trong trường hợp này.
Nếu chúng ta phá vỡ biểu thức ngôn ngữ tự nhiên:
Cả a và b đều sai hoặc c đều đúng, nhưng không phải cả hai.
đầu tiên vào một câu về các mệnh đề boolean A và B:
Hoặc A hoặc B, nhưng không phải cả hai.
điều này chuyển thành A != B
(chỉ dành cho booleans, không phải cho bất kỳ loại A và B).
Sau đó, mệnh đề A là
a và b đều sai
có thể được nêu là
a là sai và b là sai
dịch ra (not a and not b)
, và cuối cùng
c là đúng
Mà đơn giản là dịch thành c
. Kết hợp chúng bạn lại nhận được (not a and not b) != c
.
Để giải thích thêm về cách thức biểu hiện này hoạt động, tôi trì hoãn các bảng chân lý mà những người khác đã đưa ra trong câu trả lời của họ.
Cả hai bạn đều sai
Và nếu tôi có thể nitpick: Bài tập ban đầu nói rằng a, b và c có thể là các số không âm, nhưng không rõ ràng rằng nếu chúng là các số, chúng nên được giới hạn ở các giá trị 0 và 1. Nếu bất kỳ số nào là không phải là 0 đại diện true
, theo thông lệ, thì đoạn mã sau sẽ mang lại một câu trả lời đáng ngạc nhiên :
auto c = 2; // "true" in some way
auto a = 0; // "false"
auto b = 0; // "false"
std::cout << ((!a && !b) != c);
// this will output: 1 (!)
// fix by making sure that != compares booleans:
std::cout << ((!a && !b) != (bool)c);
a == b or c
thay vìa == b or a ==c
. Vấn đề là lanuage nói không chính xác và thực sự cả hai cách giải thích đều có thể hợp lệ