Quiero entender el siguiente código:
//...
#define _C 0x20
extern const char *_ctype_;
//...
__only_inline int iscntrl(int _c)
{
return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _C));
}
Se origina en el archivo ctype.h del código fuente del sistema operativo obenbsd. Esta función verifica si un carácter es un carácter de control o una letra imprimible dentro del rango ascii. Esta es mi cadena de pensamiento actual:
- Se llama a iscntrl ('a') y 'a' se convierte a su valor entero
- primero verifique si _c es -1 y luego devuelve 0 más ...
- incremente la dirección a la que apunta el puntero indefinido en 1
- declare esta dirección como un puntero a una matriz de longitud (unsigned char) ((int) 'a')
- aplicar el operador y el bit a _C (0x20) y la matriz (???)
De alguna manera, extrañamente, funciona y cada vez que se devuelve 0 el carácter dado _c no es un carácter imprimible. De lo contrario, cuando se puede imprimir, la función solo devuelve un valor entero que no tiene ningún interés especial. Mi problema de comprensión está en los pasos 3, 4 (un poco) y 5.
Gracias por cualquier ayuda.
(unsigned char)
es cuidar la posibilidad de que los personajes estén firmados y sean negativos.
_ctype_
es esencialmente un conjunto de máscaras de bits. Está siendo indexado por el personaje de interés. Por_ctype_['A']
lo tanto , contendría bits correspondientes a "alfa" y "mayúsculas",_ctype_['a']
contendría bits correspondientes a "alfa" y "minúsculas",_ctype_['1']
contendría un bit correspondiente a "dígito", etc. Parece que0x20
es el bit correspondiente a "control" . Pero por alguna razón, la_ctype_
matriz está compensada por 1, por lo que los bits para'a'
están realmente en_ctype_['a'+1]
. (Eso fue probablemente para que funcioneEOF
incluso sin la prueba adicional.)