我想了解以下代码:
//...
#define _C 0x20
extern const char *_ctype_;
//...
__only_inline int iscntrl(int _c)
{
return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _C));
}
它源自obenbsd操作系统源代码中的文件ctype.h。此函数检查char是ascii范围内的控制字符还是可打印的字母。这是我目前的思路:
- 调用iscntrl('a')并将'a'转换为其整数值
- 首先检查_c是否为-1,然后返回0,否则...
- 将未定义指针指向的地址加1
- 声明此地址为长度数组的指针(unsigned char)((int)'a')
- 将按位和运算符应用于_C(0x20)和数组(???)
奇怪地,它以某种方式起作用,并且每次返回0时,给定的char _c都不是可打印字符。否则,当该函数可打印时,它只会返回一个没有特殊意义的整数值。我的理解问题在于第3步,第4步(有点)和第5步。
感谢您的任何帮助。
(unsigned char)
为要考虑字符签名和否定的可能性。
_ctype_
本质上是位掩码的数组。它被感兴趣的字符索引。因此_ctype_['A']
将包含与“ alpha”和“大写”_ctype_['a']
相对应的位,将包含与“ alpha”和“小写”_ctype_['1']
相对应的位, 将包含与“ digit”相对应的位,依此类推。看起来0x20
是与“ control”相对应的位。但是由于某种原因,_ctype_
数组偏移了1,所以for的位'a'
实际上在中_ctype_['a'+1]
。(这可能EOF
即使没有额外的测试也可以使其正常工作。)