在c中定义一个enum类型很容易:
enum _pet_type{DOG, CAT, COW};
但是使用为了方便,可以使用typedef来定义:
typedef enum _pet_type{DOG, CAT, COW} pet_type;
这样就可以直接这样使用了:pet_type type = DOG;
1. 关于枚举数值
在这样的定义中,DOG被赋予了整型值0,后面的依次加1。你可以指定某一项元素的整数值,其后的元素依然是依次加1。
比如 typedef enum _pet_type{DOG, CAT = 10, COW} pet_type;
则DOG的值是0, CAT是10, COW是11。
2. 枚举数值与字符串的互换?
关于enum经常遇到的一个问题是,需要在字符串和整数值之间进行转换。比如遇到了枚举类型DOG,想显示字符串“DOG”,而不是数字? 拿到一个字符串“DOG”,怎样才能转换成枚举类型DOG,或者整数0?
了解了enum的原理,会发现直接转换不太可能. 因为c中enum类似与宏,比如定义了#define DOG 0,这样编译预处理时已经把所有的DOG替换成了0。enum与之类似, 每个枚举的符号(DOG、CAT、COW)都会被替换成数字,这样在运行期,只存在数字0、1、2,而完全没有了任何枚举符号DOG、CAT等的信息。所以想做一些简单直接的转换是不可能的,只能自己来写。
比如,从枚举类型得到对应的字符串,手工写一个转换函数:
static char *enum_to_name(pet_type type){ switch(type){ case DOG: return "DOG"; case CAT: return "CAT"; case COW: return "COW"; default: return NULL; } } int main (int argc, char const *argv[]) { char *name = enum_to_name(DOG); printf("DOG name is \"%s\"\n", name); return 0; }
同样的,可以写从字符串到枚举数字的转换函数。当然,如果枚举类型比较多,而且所有枚举值是连续的话,可以写的简单一点:
typedef enum _pet_type{DOG, CAT, COW}pet_type; static pet_type get_pet_type(char *data){ char map[][4] = {"DOG", "CAT", "COW"}; int i; for (i = 0; i < 3; ++i) { if (strcmp (map[i], data) == 0) { return i; } } return -1; } int main (int argc, char const *argv[]) { pet_type type = get_pet_type("DOG"); printf("\"DOG\" type is %d\n", type); return 0; }
3. 在enum中定义ENUM_COUNT
有时候会使用枚举类型的数量,可能与硬编码。此时,可以在enum时定义一个元素ENUM_COUNT。由于默认情况下对应的整数值自动加1,所以这个值恰好代表了enum类型的数量:
typedef enum _pet_type{DOG, CAT, COW, PET_COUNT}pet_type;
这样如果对枚举类型进行增删,所有的PET_COUNT的引用不需要进行修改。