Toán tử logic ( ||
và &&
) so với toán tử bitwise ( |
và&
).
Sự khác biệt quan trọng nhất giữa toán tử logic và toán tử bitwise là toán tử logic lấy hai booleans và tạo boolean trong khi toán tử bitwise lấy hai số nguyên và tạo ra một số nguyên (lưu ý: số nguyên có nghĩa là bất kỳ loại dữ liệu tích phân nào, không chỉ int).
Để được mô tả, một toán tử bitwise lấy một mẫu bit (ví dụ: 01101011) và thực hiện AND / OR một chút trên mỗi bit. Vì vậy, ví dụ nếu bạn có hai số nguyên 8 bit:
a = 00110010 (in decimal: 32+16+2 = 50)
b = 01010011 (in decimal: 64+ 16+2+1 = 83)
----------------
a & b = 00010010 (in decimal: 16+2 = 18)
a | b = 01110011 (in decimal: 64+32+16+2+1 = 115)
trong khi một toán tử logic chỉ hoạt động trong bool
:
a = true
b = false
--------------
a && b = false
a || b = true
Thứ hai, thường có thể sử dụng toán tử bitwise trên bool vì true và false tương ứng với 1 và 0, và điều đó xảy ra là nếu bạn dịch true thành 1 và false thành 0, sau đó thực hiện thao tác bitwise, sau đó chuyển đổi khác không đúng và không thành sai; nó xảy ra rằng kết quả sẽ giống như bạn đã sử dụng toán tử logic (kiểm tra điều này để thực hiện).
Một điểm khác biệt quan trọng nữa là toán tử logic bị ngắn mạch . Do đó, trong một số vòng kết nối [1], bạn thường thấy mọi người làm điều gì đó như thế này:
if (person && person.punch()) {
person.doVictoryDance()
}
có nghĩa là: "nếu con người tồn tại (tức là không phải là null), hãy cố gắng đấm anh ấy / cô ấy và nếu cú đấm thành công (tức là trở về đúng), thì hãy thực hiện một điệu nhảy chiến thắng" .
Nếu bạn đã sử dụng một toán tử bitwise thay thế, điều này:
if (person & person.punch()) {
person.doVictoryDance()
}
sẽ dịch thành: "nếu người tồn tại (tức là không rỗng) và cú đấm thành công (tức là trả về đúng), thì hãy thực hiện một điệu nhảy chiến thắng" .
Lưu ý rằng trong toán tử logic ngắn mạch, person.punch()
mã có thể không được chạy nếu không person
có giá trị. Trong thực tế, trong trường hợp cụ thể này, mã thứ hai sẽ tạo ra lỗi tham chiếu null nếu person
là null, vì nó cố gắng gọi person.punch()
bất kể người đó có null hay không. Hành vi không đánh giá toán hạng đúng này được gọi là ngắn mạch .
[1] Một số lập trình viên sẽ bực bội vì đã thực hiện một cuộc gọi hàm có tác dụng phụ bên trong một if
biểu thức, trong khi đối với những người khác, đó là một thành ngữ phổ biến và rất hữu ích.
Vì toán tử bitwise hoạt động trên 32 bit mỗi lần (nếu bạn đang sử dụng máy 32 bit), nó có thể dẫn đến mã thanh lịch hơn và nhanh hơn nếu bạn cần so sánh một số lượng lớn các điều kiện, ví dụ:
int CAN_PUNCH = 1 << 0, CAN_KICK = 1 << 1, CAN_DRINK = 1 << 2, CAN_SIT = 1 << 3,
CAN_SHOOT_GUNS = 1 << 4, CAN_TALK = 1 << 5, CAN_SHOOT_CANNONS = 1 << 6;
Person person;
person.abilities = CAN_PUNCH | CAN_KICK | CAN_DRINK | CAN_SIT | CAN_SHOOT_GUNS;
Place bar;
bar.rules = CAN_DRINK | CAN_SIT | CAN_TALK;
Place military;
military.rules = CAN_SHOOT_CANNONS | CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT;
CurrentLocation cloc1, cloc2;
cloc1.usable_abilities = person_abilities & bar_rules;
cloc2.usable_abilities = person_abilities & military_rules;
// cloc1.usable_abilities will contain the bit pattern that matches `CAN_DRINK | CAN_SIT`
// while cloc2.usable_abilities will contain the bit pattern that matches `CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT`
Làm tương tự với các toán tử logic sẽ đòi hỏi một lượng so sánh khó xử:
Person person;
person.can_punch = person.can_kick = person.can_drink = person.can_sit = person.can_shoot_guns = true;
person.can_shoot_cannons = false;
Place bar;
bar.rules.can_drink = bar.rules.can_sit = bar.rules.can_talk = true;
bar.rules.can_punch = bar.rules.can_kick = bar.rules.can_shoot_guns = bar.rules.can_shoot_cannons = false;
Place military;
military.rules.can_punch = military.rules.can_kick = military.rules.can_shoot_guns = military.rules.can_shoot_cannons = military.rules.can_sit = true;
military.rules.can_drink = military.rules.can_talk = false;
CurrentLocation cloc1;
bool cloc1.usable_abilities.can_punch = bar.rules.can_punch && person.can_punch,
cloc1.usable_abilities.can_kick = bar.rules.can_kick && person.can_kick,
cloc1.usable_abilities.can_drink = bar.rules.can_drink && person.can_drink,
cloc1.usable_abilities.can_sit = bar.rules.can_sit && person.can_sit,
cloc1.usable_abilities.can_shoot_guns = bar.rules.can_shoot_guns && person.can_shoot_guns,
cloc1.usable_abilities.can_shoot_cannons = bar.rules.can_shoot_cannons && person.can_shoot_cannons
cloc1.usable_abilities.can_talk = bar.rules.can_talk && person.can_talk;
bool cloc2.usable_abilities.can_punch = military.rules.can_punch && person.can_punch,
cloc2.usable_abilities.can_kick = military.rules.can_kick && person.can_kick,
cloc2.usable_abilities.can_drink = military.rules.can_drink && person.can_drink,
cloc2.usable_abilities.can_sit = military.rules.can_sit && person.can_sit,
cloc2.usable_abilities.can_shoot_guns = military.rules.can_shoot_guns && person.can_shoot_guns,
cloc2.usable_abilities.can_talk = military.rules.can_talk && person.can_talk,
cloc2.usable_abilities.can_shoot_cannons = military.rules.can_shoot_cannons && person.can_shoot_cannons;
Một ví dụ cổ điển trong đó các mẫu bit và toán tử bitwise được sử dụng là trong các quyền của hệ thống tệp Unix / Linux.