static const int class[UCHAR_MAX] =
{ [(unsigned char)'a'] = LOWER, /*macro value classifying the characters*/
[(unsigned char)'b'] = LOWER,
.
.
.
}
これは単なるアイデアです。悪いものですか?
Designated initializers are in C99, not C89. They also exist as a GCC extension for C89, but will not be portable.
Other than that, the use of lookup tables is a common way to handle classification of a small number of objects quickly.
Edit: One correction though: The size of the array should be UCHAR_MAX+1
ところで、GCC の指定されたイニシャライザ拡張により、
static const int class[] = {
[0 ... UCHAR_MAX] = UNCLASSIFIED,
[(unsigned)'0' ... (unsigned)'9'] = DIGIT,
[(unsigned)'A' ... (unsigned)'Z'] = UPPER,
[(unsigned)'a' ... (unsigned)'z'] = LOWER,
};
初期化子はインデックスの範囲に適用され、後の初期化は以前の初期化をオーバーライドします。
ただし、非常に非標準です。これは C89/C90 にも C99 にもありません。
Unfortunately, that is not portable in C89/90.
$ gcc -std=c89 -pedantic test.c -o test
test.c:4: warning: ISO C90 forbids specifying subobject to initialize
test.c:5: warning: ISO C90 forbids specifying subobject to initialize
int
型ではなく使用する (したがって 768 バイトを浪費する) ことを除けば、unsigned char
これは非常に良いアイデア/実装だと思います。C99 の機能に依存するため、古い C89/C90 コンパイラでは動作しないことに注意してください。
一方、単純な条件式は、同じ速度でコード サイズがはるかに小さくなりますが、特定の自然なクラスを効率的に表現することしかできません。
#define is_ascii_letter(x) (((unsigned)(x)|32)-97<26)
#define is_digit(x) ((unsigned)(x)-'0'<10)
等