如何为其成员实现具有特定值的枚举?

时间:2014-04-02 06:37:54

标签: c switch-statement

我可能会发现这一切都错了,可能是枚举确实不是解决这个问题的好办法,但我真的不知道该怎么办呢。

基本上,我有与某些字符串对应的非顺序代码。例如,

9 = "Enter"
10 = "Right"
15 = "Left"
17 = "Down"

等等。我目前使用大量定义实现了这一点:

#define ENTER_INDEX 0
#define RIGHT_INDEX 1

用于索引char *数组:

char* array[] = { "Enter", "Right" };

当我收到有关收到哪些代码的信息时,我会用巨大的switch案例打印字符串。

有关如何更有效地执行此操作的任何想法? enum是一个好方法吗?

5 个答案:

答案 0 :(得分:3)

当然,您可以使用enum,但这无助于您将名称与数值相关联。

问题是你不能使用相同的源代码字符“并行”声明枚举和字符串,而不使用X macros等技巧。即便如此,您可能也无法解决代码显示的不同外壳的要求。您可能想要避免,因为混淆。

enum只是:

typedef enum {
  ID_ENTER = 9,
  ID_RIGHT = 10,
  ID_LEFT = 15,
  ID_DOWN = 17
} Id;

然后我会使用C99对数组初始值设定项中显式索引的出色支持来声明由Id索引的字符串数组:

static const char *id_names[] = {
  [ID_ENTER] = "Enter",
  [ID_RIGHT] = "Right",
  /* add more */
};

请注意,上述内容与顺序无关,因为每个元素初始值设定项都有一个显式索引。这使它非常强大。

你当然可以使用一个宏来减少重复,但这会产生一个全大写的字符串数组:

#define DECL_ID(i)  [ID_ ## i] = #i
static const char *id_names2[] = {
  DECL_ID(ENTER), DECL_ID(RIGHT), /* add more */
};

答案 1 :(得分:1)

要为其成员实现具有特定值的枚举,可以通过

来完成
 enum options_en
{
     Enter=9,
     Right=10,
     Left=15,
     Down=17,
     Default=0;
} ; 

然后您可以声明一个只能采用枚举类型

中定义的值的变量
options_en  opt_val = Default;

如需了解有关您问题的更多信息,请参阅此链接,发现它非常有用并且与您的问题相关

http://www.cprogramming.com/tutorial/enum.html

答案 2 :(得分:1)

可以使用字典或哈希表。在c ++ stl库中,我不记得集合的名称,但简而言之。使用带有泛型的字典/哈希表。

因此,在您的情况下,您使用键值对填充字典,当您以后使用该集合时,您可以使用密钥获取值。

因此它摆脱了switch语句和枚举,并允许您映射任何两种类型。这是伪代码

Value = dictionary [key]

因此,如果key为0,则该值将根据您的示例设置为Enter。

简短的c ++和字典查找示例,因为我正在通过手机回复,但无法将您引导至确切的集合名称。

答案 3 :(得分:1)

您还可以在初始化期间创建地图:

#include<stdio.h>

typedef struct { int code; const char *str; } key_info;
key_info keys[] = {
    {9, "Enter"}, {10, "Right"}, {15, "Left"}, {-1, NULL}
};

#define MAX_KEY_CODE 15
size_t keymap[MAX_KEY_CODE + 1];

int main ( ) {  
    size_t i;
    for (i = 0; keys[i].str; i++) {
        keymap[keys[i].code] = i;
    }
    printf("%s\n", keys[keymap[10]].str);
    return 0;
}

答案 4 :(得分:1)

巨大的开关并不是一个糟糕的解决方案。问题是为什么你需要一个额外的名字数组。为什么不直接从交换机返回字符串文字?

char *name(int code) {
  switch (code) {
  case 9:  return("Enter");
  case 10: return("Right");
  case 15: return("Left");
  ...
  }
}