пример - typedef enum c




Правильный способ связывания перечислений со строками (2)

Другая возможность - для пользователя #defines .

Несмотря на многие недостатки его использования, главное преимущество заключается в том, что #defines занимают места, если они не используются ...

#define STRING_HELLO "Hello"
#define STRING_WORLD "World"

Допустим, у меня есть несколько строк, которые я часто использую в своей программе (для хранения состояния и тому подобного). Строковые операции могут быть дорогими, поэтому при их обращении я бы хотел использовать перечисление. До сих пор я видел пару решений:

typedef enum {
    STRING_HELLO = 0,
    STRING_WORLD
} string_enum_type;

// Must be in sync with string_enum_type
const char *string_enumerations[] = {
    "Hello",
    "World"
}

Другой, с которым я сталкиваюсь довольно часто:

typedef enum {
    STRING_HELLO,
    STRING_WORLD
} string_enum_type;

const char *string_enumerations[] = {
    [STRING_HELLO] = "Hello",
    [STRING_WORLD] = "World"
}

Каковы минусы / плюсы этих двух методов? Есть ли лучший?


Другой возможностью может быть использование функции вместо массива:

const char *enumtostring(string_enum_type e) {
    switch(e) {
        case STRING_HELLO: return "hello";
        case STRING_WORLD: return "world";
    }
}

По крайней мере, gcc предупредит вас, если вы добавите значение enum, но забудете добавить соответствующий регистр переключателя.

(Полагаю, вы могли бы попытаться сделать такую ​​функцию inline .)

Приложение: упомянутое мной предупреждение gcc применяется только в том случае, если в операторе switch не указан регистр по default . Поэтому, если вы хотите напечатать что-то для значений за пределами допустимого диапазона, которые каким-то образом проскальзывают, вы можете сделать это не с регистром по default , а с чем-то вроде этого:

const char *enumtostring(string_enum_type e) {
    switch(e) {
        case STRING_HELLO: return "hello";
        case STRING_WORLD: return "world";
    }
    return "(unrecognized string_enum_type value)";
}

Также полезно включить значение за пределами:

    static char tmpbuf[50];
    snprintf(tmpbuf, sizeof(tmpbuf), "(unrecognized string_enum_type value %d)", e);
    return tmpbuf;

(У этого последнего фрагмента есть несколько дополнительных ограничений, но это дополнение уже становится длинным, поэтому я не буду сейчас обсуждать с ними вопрос.)





c-strings