次のコードを理解したいと思います。
//...
#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')
- ビットごとのand演算子を_C(0x20)と配列(???)に適用します。
どういうわけか、奇妙なことに、それは機能し、0が返されるたびに、指定されたchar _cは印刷可能な文字ではありません。それ以外の場合、それが印刷可能である場合、関数は特別な関心のない整数値を返すだけです。私の理解の問題は、ステップ3、4(少し)および5にあります。
助けてくれてありがとう
(unsigned char)
は、文字が署名され、否定的である可能性を処理することです。
_ctype_
基本的にはビットマスクの配列です。関心のあるキャラクターによって索引付けされています。つまり_ctype_['A']
、「alpha」と「uppercase」に_ctype_['a']
対応するビットが含まれ、「alpha」と「lowercase」に_ctype_['1']
対応するビットが含まれ、「digit」に対応するビットが含まれるなどです。0x20
「control」に対応するビットは。しかし、何らかの理由で_ctype_
配列が1だけオフセットされているため、のビット'a'
は実際ににあり_ctype_['a'+1]
ます。(それはおそらくEOF
、追加のテストがなくても機能させるためでした。)