c - 将枚举与字符串相关联的正确方法

标签 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"
}

另一个我经常遇到的:

typedef enum {
    STRING_HELLO,
    STRING_WORLD
} string_enum_type;

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

这两种方法的优缺点是什么?还有更好的吗?

最佳答案

前者的唯一优势是它向后兼容古老的 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");

以上是简单“枚举-查​​找表”耦合的最佳方法。另一种选择是使用结构,但这更适合更复杂的数据类型。


最后,作为旁注,第三个版本将使用“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");

关于c - 将枚举与字符串相关联的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48986498/

相关文章:

c++ - 在模板参数中将枚举转换为 int

java - java枚举变量是静态的吗?

C:检查数组是否包含相等的连续元素

c - 为什么空 C 程序中执行的指令总数会发生变化?

c - Malloc 尝试寻址 0x0?

oop - 在 Rust 中更改枚举的字段

c++ - 使用 strtok 拆分 C 字符串

c++ - 围绕变量 "name"的堆栈已损坏 C++

c - 当我们在 C 中编写 printf() 时,我们是声明它还是定义它?

c - 何时在 C 中将局部变量声明为静态变量?