通过查找表在C89中进行便携式用户定义的字符类划分,你会这样做吗?

时间:2010-02-09 20:34:59

标签: c c89

static const int class[UCHAR_MAX] =

{ [(unsigned char)'a'] = LOWER, /*macro value classifying the characters*/
  [(unsigned char)'b'] = LOWER,
.
.
.
}

这只是一个想法。这是一个糟糕的吗?

4 个答案:

答案 0 :(得分:4)

Designated initializers在C99,而不是C89。它们也作为C89的GCC扩展存在,但不可移植。

除此之外,使用查找表是快速处理少量对象分类的常用方法。

编辑:虽然有一个更正:数组的大小应为UCHAR_MAX+1

答案 1 :(得分:2)

BTW,GCC的designated initializer extensions允许

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。

答案 2 :(得分:1)

不幸的是,这在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

答案 3 :(得分:0)

除了使用int而不是unsigned char作为类型(从而浪费768字节)之外,我认为这是一个非常好的主意/实现。请记住,它取决于C99功能,因此它不适用于旧的C89 / C90编译器。

另一方面,简单的条件应该是相同的速度,而且代码大小要小得多,但它们只能有效地代表某些自然类。

#define is_ascii_letter(x) (((unsigned)(x)|32)-97<26)
#define is_digit(x) ((unsigned)(x)-'0'<10)