ตัวดำเนินการทางตรรกะ ( ||
และ&&
) เทียบกับตัวดำเนินการแบบบิต ( |
และ&
)
ความแตกต่างที่สำคัญที่สุดระหว่างตัวดำเนินการเชิงตรรกะและตัวดำเนินการแบบบิตคือตัวดำเนินการเชิงตรรกะรับสองบูลีนและสร้างบูลีนในขณะที่ตัวดำเนินการแบบบิตรับจำนวนเต็มสองจำนวนและสร้างจำนวนเต็ม (หมายเหตุ: จำนวนเต็มหมายถึงชนิดข้อมูลที่เป็นหนึ่งใด ๆ ไม่ใช่เฉพาะ int)
เพื่อเป็นการอวดดีตัวดำเนินการระดับบิตจะใช้รูปแบบบิต (เช่น 01101011) และใช้บิตที่ชาญฉลาด AND / OR ในแต่ละบิต ตัวอย่างเช่นหากคุณมีจำนวนเต็ม 8 บิตสองตัว:
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)
ในขณะที่ตัวดำเนินการเชิงตรรกะทำงานเฉพาะในbool
:
a = true
b = false
--------------
a && b = false
a || b = true
ประการที่สองมักเป็นไปได้ที่จะใช้ตัวดำเนินการแบบบิตบนบูลเนื่องจากจริงและเท็จเทียบเท่ากับ 1 และ 0 ตามลำดับและเกิดขึ้นว่าหากคุณแปลค่าจริงเป็น 1 และเท็จเป็น 0 ให้ทำการดำเนินการแบบบิตจากนั้นแปลงค่าที่ไม่ใช่ศูนย์ เป็นจริงและศูนย์เป็นเท็จ มันเกิดขึ้นที่ผลลัพธ์จะเหมือนกันหากคุณเพิ่งใช้ตัวดำเนินการเชิงตรรกะ (ตรวจสอบสิ่งนี้เพื่อการออกกำลังกาย)
อีกความแตกต่างที่สำคัญยังเป็นที่ผู้ประกอบการตรรกะลัดวงจร ดังนั้นในบางแวดวง [1] คุณมักจะเห็นคนทำสิ่งนี้:
if (person && person.punch()) {
person.doVictoryDance()
}
ซึ่งแปล: "ถ้าคนที่มีอยู่ (เช่นไม่ null) พยายามที่จะชกเขา / เธอและถ้าหมัดประสบความสำเร็จ (เช่นผลตอบแทนจริง) แล้วทำเต้นรำชัยชนะ"
หากคุณใช้ตัวดำเนินการ bitwise แทนสิ่งนี้:
if (person & person.punch()) {
person.doVictoryDance()
}
จะแปล: "ถ้าคนที่มีอยู่ (เช่นไม่ null) และหมัดประสบความสำเร็จ (เช่นผลตอบแทนจริง) แล้วทำเต้นรำชัยชนะ"
โปรดสังเกตว่าในตัวดำเนินการลอจิคัลลัดวงจรperson.punch()
รหัสอาจไม่ถูกรันเลยถ้าperson
เป็นโมฆะ ในความเป็นจริงในกรณีนี้รหัสที่สองจะสร้างข้อผิดพลาดในการอ้างอิงที่person
เป็นโมฆะหากเป็นค่าว่างเนื่องจากพยายามเรียกperson.punch()
ไม่ว่าบุคคลนั้นจะเป็นโมฆะหรือไม่ก็ตาม พฤติกรรมของการไม่ประเมินตัวถูกดำเนินการที่เหมาะสมนี้เรียกว่าลัดวงจร
[1] โปรแกรมเมอร์บางคนจะดักฟังการเรียกใช้ฟังก์ชันที่มีผลข้างเคียงในif
นิพจน์ในขณะที่คนอื่น ๆ เป็นสำนวนที่ใช้กันทั่วไปและมีประโยชน์มาก
เนื่องจากตัวดำเนินการระดับบิตทำงานบน 32 บิตในแต่ละครั้ง (หากคุณใช้เครื่อง 32 บิต) จึงสามารถนำไปสู่รหัสที่สวยงามและรวดเร็วยิ่งขึ้นหากคุณต้องการเปรียบเทียบเงื่อนไขจำนวนมากเช่น
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;
การทำเช่นเดียวกันกับตัวดำเนินการเชิงตรรกะจะต้องมีการเปรียบเทียบที่น่าอึดอัดใจ:
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;
ตัวอย่างคลาสสิกที่ใช้รูปแบบบิตและตัวดำเนินการบิตอยู่ในสิทธิ์ระบบไฟล์ Unix / Linux