Je veux comprendre le code suivant:
//...
#define _C 0x20
extern const char *_ctype_;
//...
__only_inline int iscntrl(int _c)
{
return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _C));
}
Il provient du fichier ctype.h du code source du système d'exploitation obenbsd. Cette fonction vérifie si un caractère est un caractère de contrôle ou une lettre imprimable à l'intérieur de la plage ascii. Voici ma chaîne de pensée actuelle:
- iscntrl ('a') est appelé et 'a' est converti en sa valeur entière
- vérifiez d'abord si _c est -1 puis retournez 0 sinon ...
- incrémenter l'adresse vers laquelle le pointeur non défini pointe de 1
- déclarer cette adresse comme un pointeur sur un tableau de longueur (caractère non signé) ((int) 'a')
- appliquer l'opérateur au niveau du bit et à _C (0x20) et au tableau (???)
D'une manière ou d'une autre, étrangement, cela fonctionne et à chaque fois que 0 est renvoyé, le caractère _c donné n'est pas un caractère imprimable. Sinon, lorsqu'elle est imprimable, la fonction renvoie simplement une valeur entière qui ne présente aucun intérêt particulier. Mon problème de compréhension se trouve aux étapes 3, 4 (un peu) et 5.
Merci pour toute aide.
(unsigned char)
est de prendre en compte la possibilité que les personnages soient signés et négatifs.
_ctype_
est essentiellement un tableau de bitmasks. Il est indexé par le caractère qui nous intéresse. Contiendrait donc_ctype_['A']
des bits correspondant à "alpha" et "majuscule",_ctype_['a']
contiendrait des bits correspondant à "alpha" et "minuscule",_ctype_['1']
contiendrait un bit correspondant à "chiffre", etc. On dirait que0x20
c'est le bit correspondant à "contrôle" . Mais pour une raison quelconque, le_ctype_
tableau est décalé de 1, donc les bits de'a'
sont vraiment dedans_ctype_['a'+1]
. (C'était probablement pour le laisser fonctionnerEOF
même sans le test supplémentaire.)