Переносимое пользователем определение класса символов в C89 с помощью таблицы поиска, вы бы сделали это? - PullRequest
0 голосов
/ 09 февраля 2010
static const int class[UCHAR_MAX] =

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

Это просто идея. Это плохо?

Ответы [ 4 ]

4 голосов
/ 09 февраля 2010

Назначенные инициализаторы в C99, а не в C89. Они также существуют как расширение GCC для C89, но не будут переносимыми.

Кроме этого, использование таблиц подстановки является распространенным способом быстрой обработки классификации небольшого числа объектов.

Редактировать: одно исправление: размер массива должен быть UCHAR_MAX+1

2 голосов
/ 10 февраля 2010

Кстати, 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.

1 голос
/ 09 февраля 2010

К сожалению, это не переносимо в 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
0 голосов
/ 11 августа 2010

Помимо использования 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)

и т.д.

...