PoV*_*oVa 19 c enums c-strings
假设我在整个程序中经常使用一些字符串(用于存储状态和类似的东西).字符串操作可能很昂贵,所以无论何时解决它们我都想使用枚举.到目前为止,我已经看到了几个解决方案:
typedef enum {
STRING_HELLO = 0,
STRING_WORLD
} string_enum_type;
// Must be in sync with string_enum_type
const char *string_enumerations[] = {
"Hello",
"World"
}
Run Code Online (Sandbox Code Playgroud)
我经常遇到的另一个:
typedef enum {
STRING_HELLO,
STRING_WORLD
} string_enum_type;
const char *string_enumerations[] = {
[STRING_HELLO] = "Hello",
[STRING_WORLD] = "World"
}
Run Code Online (Sandbox Code Playgroud)
这两种方法的缺点是什么?还有更好的吗?
Lun*_*din 14
前者的唯一优势是它与古老的C标准向后兼容.
除此之外,后一种选择是优越的,因为它确保数据完整性,即使枚举被修改或项目改变位置.但是,它应该通过检查来完成,以确保枚举中的项目数与查找表中的项目数相对应:
typedef enum {
STRING_HELLO,
STRING_WORLD,
STRING_N // counter
} string_enum_type;
const char *string_enumerations[] = {
[STRING_HELLO] = "Hello",
[STRING_WORLD] = "World"
};
_Static_assert(sizeof string_enumerations/sizeof *string_enumerations == STRING_N,
"string_enum_type does not match string_enumerations");
Run Code Online (Sandbox Code Playgroud)
以上是简单的"枚举 - 查找表"耦合的最佳方法.另一种选择是使用结构,但这更适合更复杂的数据类型.
最后,更多的是作为旁注,第3版将是使用"X宏".除非您对代码重复和维护有特殊要求,否则不建议这样做.为了完整起见,我会将其包含在此处,但我不建议在一般情况下使用它:
#define STRING_LIST \
/* index str */ \
X(STRING_HELLO, "Hello") \
X(STRING_WORLD, "World")
typedef enum {
#define X(index, str) index,
STRING_LIST
#undef X
STRING_N // counter
} string_enum_type;
const char *string_enumerations[] = {
#define X(index, str) [index] = str,
STRING_LIST
#undef X
};
_Static_assert(sizeof string_enumerations/sizeof *string_enumerations == STRING_N,
"string_enum_type does not match string_enumerations");
Run Code Online (Sandbox Code Playgroud)