The ctype.h file defines functions to check properties of characters, as if a character is a digit - isdigit(), a space - isspace(), and many others. These functions are either implemented as macros, or as real functions. The macro version is used when the -Ot compiler option is used or the macro __OPTIMIZE_FOR_TIME__ is defined. The macros use a table called _ctype.whose length is 257 bytes. In this array, all properties tested by the various functions are encoded by single bits, taking the character as indices into the array. The function implementations otherwise do not use this table. They save memory by using the shorter call to the function (compared with the expanded macro).
The functions in the following listing are explained below together with all other ANSI functions.
extern unsigned char _ctype[]; #define _U (1<<0) /* Uppercase */ #define _L (1<<1) /* Lowercase */ #define _N (1<<2) /* Numeral (digit) */ #define _S (1<<3) /* Spacing character */ #define _P (1<<4) /* Punctuation */ #define _C (1<<5) /* Control character */ #define _B (1<<6) /* Blank */ #define _X (1<<7) /* hexadecimal digit */ #ifdef __OPTIMIZE_FOR_TIME__ /* -Ot defines this macro */ #define isalnum(c) (_ctype[(unsigned char)(c+1)] & (_U|_L|_N)) #define isalpha(c) (_ctype[(unsigned char)(c+1)] & (_U|_L)) #define iscntrl(c) (_ctype[(unsigned char)(c+1)] & _C) #define isdigit(c) (_ctype[(unsigned char)(c+1)] & _N) #define isgraph(c) (_ctype[(unsigned char)(c+1)] & (_P|_U|_L|_N)) #define islower(c) (_ctype[(unsigned char)(c+1)] & _L) #define isprint(c) (_ctype[(unsigned char)(c+1)] & (_P|_U|_L|_N|_B)) #define ispunct(c) (_ctype[(unsigned char)(c+1)] & _P) #define isspace(c) (_ctype[(unsigned char)(c+1)] & _S) #define isupper(c) (_ctype[(unsigned char)(c+1)] & _U) #define isxdigit(c)(_ctype[(unsigned char)(c+1)] & _X) #define tolower(c) (isupper(c) ? ((c) - 'A' + 'a') : (c)) #define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c)) #define isascii(c) (!((c) & ~127)) #define toascii(c) (c & 127) #endif /* __OPTIMIZE_FOR_TIME__ */