在 C 中为 typedef 枚举定义附加数据的最佳方法是什么?

例子:

typedef enum {
  kVizsla = 0,
  kTerrier = 3,
  kYellowLab = 10
} DogType;

现在我想为每个定义名称,例如 kVizsla 应该是“维兹拉”。我目前使用一个使用大型开关块返回字符串的函数。

有帮助吗?

解决方案

@dmckee:我认为建议的解决方案很好,但对于简单的数据(例如如果只需要名称)它可以用自动生成的代码进行扩充。虽然自动生成代码的方法有很多,但对于像这样简单的事情,我相信您可以编写一个简单的 XSLT,它接受枚举的 XML 表示形式并输出代码文件。

XML 的形式如下:

<EnumsDefinition>
    <Enum name="DogType">
        <Value name="Vizsla" value="0" />
        <Value name="Terrier" value="3" />
        <Value name="YellowLab" value="10" />
    </Enum>
</EnumsDefinition>

生成的代码将类似于 dmckee 在他的解决方案中建议的内容。

有关如何编写此类 XSLT 的信息,请尝试 这里 或者只是在谷歌中搜索并找到合适的教程。在我看来,编写 XSLT 并不是很有趣,但也没有那么糟糕,至少对于像这样的相对简单的任务来说是这样。

其他提示

完美适合 X() 宏. 。这些类型的宏可以使用 C 预处理器从同一源构造枚举和数组。您只需将新数据添加到包含 X() 宏的#define 中。

你的例子可以写成如下:

// All dog data goes in this list
#define XDOGTYPE \
  X(kVizsla,0,"vizsla") \
  X(kTerrier,3,"terrier") \
  X(kYellowLab,10,"yellowlab")

 // Dog info
 typedef struct {
     int val;       // Defined value
     char * desc;   // Text description
 } DogType;

 // Build an array index using the Names
 typedef enum {
  #define X(Name,Val,Text)     Name,
   XDOGTYPE
  #undef X
  MAXDOGS
 } DogIndex;

 // Build a lookup table of values
 DogType Dog[] = {
  #define X(Name,Val,Text)    {Val,Text},
   XDOGTYPE
  #undef X
 };

 // Access the values
 for (i=0; i < MAXDOGS; i++)
    printf("%d: %s\n",Dog[i].val,Dog[i].desc);

如果您的枚举值足够密集,您可以定义一个数组来保存字符串并仅查找它们(对任何跳过的值使用 NULL 并在查找例程中添加特殊情况处理程序)。

char *DogList[] = {
  "vizsla", /* element 0 */
  NULL,
  NULL,
  NULL,
  "terrier", /* element 3 */
  ...
};

这对于稀疏枚举来说效率很低。

即使枚举并不密集,您也可以使用结构数组来保存映射。

typedef struct DogMaps {
  DogType index;
  char * name;
} DogMapt;
DogMapt DogMap[] = {
  {kVizsla, "vizsla"},
  {kTerrier, "terrier"},
  {kYellowLab, "yellow lab"},
  NULL
};

第二种方法非常灵活,但它确实意味着每次需要使用数据时都要搜索映射。对于大型数据集,请考虑使用 b 树或哈希而不是数组。

任何一种方法都可以推广到连接更多数据。在第一个中使用结构数组,在第二个中只需向结构中添加更多成员。

当然,您会希望编写各种处理程序来简化与这些数据结构的交互。


@Hershi 无论如何,将代码和数据分开。上面的例子是为了清晰起见,而不是为了实用。

我不好意思承认,我仍然使用空格分隔的平面文件来实现此目的,而不是您展示的那种结构化输入,但我的生产代码会尽可能多地从外部源读取数据。


等等,我明白你的意思是代码生成。

当然。没有错。

我怀疑,虽然OP对生成的代码应该是什么样子感兴趣......

这是一个开放式问题,但一个建议是使用以枚举作为键类型并在值中包含额外信息的映射。(如果您的索引是连续的,与示例不同,您可以使用序列容器而不是映射)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top