ฉันต้องการที่จะเข้าใจรหัสต่อไปนี้:
//...
#define _C 0x20
extern const char *_ctype_;
//...
__only_inline int iscntrl(int _c)
{
return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _C));
}
มันมาจากไฟล์ctype.hจากรหัสที่มาระบบปฏิบัติการ obenbsd ฟังก์ชั่นนี้จะตรวจสอบว่าถ่านเป็นตัวควบคุมหรือตัวอักษรที่พิมพ์ได้ภายในช่วง ascii นี่คือห่วงโซ่ความคิดปัจจุบันของฉัน:
- iscntrl ('a') ถูกเรียกและ 'a' ถูกแปลงเป็นค่าจำนวนเต็ม
- ก่อนอื่นตรวจสอบว่า _c เป็น -1 แล้วส่งกลับ 0 อื่น ๆ
- เพิ่มที่อยู่ของพอยน์เตอร์ที่ไม่ได้กำหนดชี้ไปที่ 1
- ประกาศที่อยู่นี้เป็นตัวชี้ไปยังอาร์เรย์ของความยาว (ถ่านที่ไม่ได้ลงชื่อ) ((int) 'a')
- ใช้ bitwise และโอเปอเรเตอร์กับ _C (0x20) และ array (???)
ยังไงก็เถอะมันใช้งานได้และทุกครั้งที่ 0 ถูกส่งคืน char _c ที่กำหนดไม่ใช่อักขระที่พิมพ์ได้ มิฉะนั้นเมื่อพิมพ์ออกมาฟังก์ชันก็แค่คืนค่าจำนวนเต็มที่ไม่สนใจเป็นพิเศษ ปัญหาความเข้าใจของฉันอยู่ในขั้นตอนที่ 3, 4 (บิต) และ 5
ขอบคุณสำหรับความช่วยเหลือ
(unsigned char)
คือการดูแลความเป็นไปได้ที่ตัวละครจะถูกเซ็นชื่อและติดลบ
_ctype_
เป็นอาร์เรย์ของ bitmasks มันถูกจัดทำดัชนีโดยตัวละครที่น่าสนใจ ดังนั้น_ctype_['A']
จะมีบิตที่สอดคล้องกับ "อัลฟา" และ "ตัวพิมพ์ใหญ่"_ctype_['a']
จะมีบิตที่สอดคล้องกับ "อัลฟา" และ "ตัวพิมพ์เล็ก"_ctype_['1']
จะมีบิตที่สอดคล้องกับ "หลัก" ฯลฯ ดูเหมือนว่า0x20
เป็นบิตที่สอดคล้องกับ "ควบคุม" . แต่ด้วยเหตุผลบางอย่าง_ctype_
อาเรย์จะถูกชดเชยด้วย 1 ดังนั้นบิตของ'a'
มันจึงเข้า_ctype_['a'+1]
มา (นั่นอาจจะทำให้มันทำงานEOF
ได้โดยไม่ต้องมีการทดสอบเพิ่มเติม)