Voglio capire il seguente codice:
//...
#define _C 0x20
extern const char *_ctype_;
//...
__only_inline int iscntrl(int _c)
{
return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _C));
}
Ha origine dal file ctype.h dal codice sorgente del sistema operativo obenbsd. Questa funzione controlla se un carattere è un carattere di controllo o una lettera stampabile all'interno dell'intervallo ascii. Questa è la mia attuale catena di pensiero:
- viene chiamato iscntrl ('a') e 'a' viene convertito nel suo valore intero
- controlla prima se _c è -1, quindi restituisce 0 else ...
- incrementa l'indirizzo a cui punta il puntatore indefinito di 1
- dichiarare questo indirizzo come puntatore a un array di lunghezza (unsigned char) ((int) 'a')
- applica bit a bit e operatore a _C (0x20) e all'array (???)
In qualche modo, stranamente, funziona e ogni volta che viene restituito 0 il dato char _c non è un carattere stampabile. Altrimenti quando è stampabile la funzione restituisce solo un valore intero che non ha alcun interesse speciale. Il mio problema di comprensione è nel passaggio 3, 4 (un po ') e 5.
Grazie per tutto l'aiuto.
(unsigned char)
è quello di prendersi cura della possibilità che i personaggi siano firmati e negativi.
_ctype_
è essenzialmente una matrice di maschere di bit. Viene indicizzato dal personaggio di interesse. Conterrebbe quindi i_ctype_['A']
bit corrispondenti a "alfa" e "lettere maiuscole",_ctype_['a']
conterrebbe i bit corrispondenti a "alfa" e "lettere minuscole",_ctype_['1']
conterrebbe un bit corrispondente a "cifre", ecc. Sembra che0x20
sia il bit corrispondente a "controllo" . Ma per qualche ragione l'_ctype_
array è sfalsato di 1, quindi i bit per'a'
sono veramente dentro_ctype_['a'+1]
. (Probabilmente era per farlo funzionareEOF
anche senza il test extra.)