ฉันจะลบการตั้งค่าสถานะใน C ได้อย่างไร


148

มีตัวแปรที่มีธงบางส่วนและฉันต้องการลบหนึ่งในนั้น แต่ฉันไม่ทราบวิธีการลบ

นี่คือวิธีที่ฉันตั้งค่าสถานะ

my.emask |= ENABLE_SHOOT;

6
คุณอาจพบคำตอบของคำถาม SO "คุณจะตั้งล้างและสลับบิตใน C ได้อย่างไร" มีประโยชน์
schot

คำตอบ:


339

คำตอบสั้น ๆ

คุณต้องการที่จะทำBitwise และการดำเนินงานในมูลค่าปัจจุบันมีค่าที่เหมาะสมไม่ได้การดำเนินงานของธงคุณต้องการที่จะล้าง Bitwise ไม่แปลงกลับทุกบิต (เช่น 0 => 1, 1 => 0)

flags = flags & ~MASK;flags &= ~MASK;หรือ

คำตอบยาว

ENABLE_WALK  = 0    // 00000000
ENABLE_RUN   = 1    // 00000001
ENABLE_SHOOT = 2    // 00000010
ENABLE_SHOOTRUN = 3 // 00000011

value  = ENABLE_RUN     // 00000001
value |= ENABLE_SHOOT   // 00000011 or same as ENABLE_SHOOTRUN

เมื่อคุณทำการ Bitwise และด้วย Bitwise ไม่ใช่ของค่าที่คุณต้องการยกเลิก

value = value & ~ENABLE_SHOOT // 00000001

คุณกำลังทำจริง:

      0 0 0 0 0 0 1 1     (current value)
   &  1 1 1 1 1 1 0 1     (~ENABLE_SHOOT)
      ---------------
      0 0 0 0 0 0 0 1     (result)

@Aaron: ฉันดีใจที่มันช่วย ตอนแรกฉันมีปัญหาในการทำความเข้าใจการทำงานระดับบิตจนกระทั่งมีคนใช้เวลา 10 นาทีในการอธิบายบนกระดาษ
เดนนิส

1
@Dennis ฉันคิดว่า XOR จะทำงานเพื่อลบการตั้งค่าสถานะแล้ว notification.sound ^= Notification.DEFAULT_SOUND;
likejudo

3
คุณเปิดใช้งาน Walk ได้อย่างไร ตั้งแต่ X | 0 == X
Unikorn

เมื่อ @Unikorn ชี้ให้เห็นว่าค่าสถานะเป็นศูนย์ไม่ทำงานอย่างถูกต้องเช่นถ้าคุณพยายามที่จะหรือมันในหรือถ้าคุณพยายามที่จะและมันออก
RenniePet

ในการเปิดใช้งาน walk คุณต้องปิดการใช้งาน run (ซึ่งจะปล่อยให้บิต 1 ตั้งค่าเป็น 0) อย่าคิดว่าการตั้งค่าสถานะ ENABLE_ * เป็นตัวเลขทศนิยม แต่เป็นเลขฐานสองไม่ว่าจะเปิดหรือปิดก็ตาม อย่างไรก็ตามคุณยังไม่สามารถเปิดใช้งานหรือปิดใช้งานการเดินได้อย่างชัดเจน
Jacob Degeling


13

เป็นสิ่งสำคัญที่จะต้องทราบว่าหากตัวแปรที่มีการจัดการมีขนาดใหญ่กว่า int ค่าที่ใช้ในนิพจน์ 'และไม่' ต้องเป็นเช่นกัน ที่จริงแล้วบางครั้งเราสามารถใช้ชนิดที่มีขนาดเล็กลงได้ แต่มีหลายกรณีที่น่าแปลกใจที่อาจใช้คำต่อท้ายประเภทที่ดีที่สุดเพื่อให้แน่ใจว่าค่าคงที่มีขนาดใหญ่พอ


5
+1 สำหรับการจับมุมตัวพิมพ์ที่ไม่เด่นชัด วิธีหนึ่งในการหลีกเลี่ยงคือการใช้แทนflags -= flags & MY_FLAG;(หรือ^=หากคุณต้องการ)
. GitHub หยุดช่วยน้ำแข็ง

1
@R .. ฉันจะใช้ '^ =' ยกเว้นว่าจะสลับบิตและบางครั้งคุณอาจไม่ทราบว่ามีการตั้งค่าสถานะใดบ้าง ถ้าฉันต้องการตรวจสอบให้แน่ใจว่าบิตที่ถูกต้องที่สุดสองตัวเป็นศูนย์เช่น my.emask: อินพุต 0 0 1 1 ':' 0 0 1 1 'ด้วย:' ^ = '' 0 1 1 0 'ด้วย:' & ~ '' 0 1 0 0 '
เฮ็กเตอร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.