如何检查枚举变量是否有效?

我有一个枚举:

enum myenum{ typeA, typeB, typeC } myenum_t; 

然后,使用枚举参数调用函数:

 int myfunction(myenum_t param1) { switch(param1) { case typeA: case typeB: case typeC: //do the work break; default: printf("Invalid parameter"); } return 0; } 

但是,随着myenum_t随着越来越多的值而增长, myfunction似乎并不那么优雅。

有没有更好的方法来检查枚举是否有效?

一个常见的约定是做这样的事情:

 typedef enum { typeA, typeB, typeC, num_types } myenum_t; 

然后你可以检查(t < num_types)

如果您随后添加更多枚举,例如

 typedef enum { typeA, typeB, typeC, typeD, typeE, num_types } myenum_t; 

然后num_types会自动更新,您的错误检查代码无需更改。

您可以使用按位枚举:

 enum myEnum { typeA = 1 << 0; typeB = 1 << 1; typeC = 1 << 2; } int myFunction(myEnum arg1) { int checkVal = typeA | typeB | typeC; if (checkVal & arg1) { // do work here; } else { printf("invalid argument!"); } return 0; } 

对不起,我好像读错了。

看来你想要做的是确定你是否传入了适当的值,而不是一些随机的无效选项。 在这种情况下,最合乎逻辑的选择是:

 if (arg1 < typeA || arg1 > typeC) printf("invalid argument"); 

当然,这是假设您没有为枚举设置手动值,除非使用按位枚举,否则这很少见。

是。

让编译器完成它的工作,不要将int转换为enum类型,你应该很好。

我过去使用的一个技巧:

 enum foo {FIRST_FOO, BAR, BLETCH, BLURGA, BLAH, LAST_FOO}; 

然后检查您的值是否> FIRST_FOO && < LAST_FOO 1

当然,这假设您的枚举值之间没有间隙。

否则,不,没有好方法可以做你所要求的(至少在C中)。


1来自最新的在线C语言标准 :

6.7.2.2枚举说明符
...
3枚举器列表中的标识符声明为具有int类型的常量,并且可以出现在允许的位置。 109)=的枚举数将其枚举常量定义为常量表达式的值。 如果第一个枚举数没有= ,则其枚举常量的值为0 。 具有no =每个后续枚举器将​​其枚举常量定义为通过将1添加到先前枚举常量的值而获得的常量表达式的值。 (枚举器与=的使用可能会产生枚举常量,其值与同一枚举中的其他值重复。)枚举的枚举数也称为其成员。

你也不能做类似的事情

 enum myEnum {typeA,typeB, typeC}; int myFunction (myEnum arg1) { if (arg1 >= typeA && arg1 <= typeC) { // do work here } else { printf("invalid argument!"); } return 0; } 

不幸的是,没有一种简单的方法来完成它的语言级别(至少用C ),你只需要确保你只使用通过enum定义的变量。

虽然您可以与-Werror一起启用以下编译器警告-Werror

  • -Wswitch
  • -Wswitch-default
  • -Wswitch-enum

如果在交换机内部遗漏了其中一个枚举,则会导致构建失败。

C ++中的枚举已经比C中的枚举更强。

采取以下简单程序:

 #include  enum E { A, B }; void f(E e) { } int main() { f(1); } 

使用GCC编译器我将收到此错误:

 enum.cpp:在函数'int main()'中:
 enum.cpp:15:错误:从'int'到'E'的无效转换
 enum.cpp:15:错误:初始化'void f(E)'的参数1

因此,您可以看到已经检查了枚举成员。

如果您想要更强大的类型检查,并且具有支持C ++ 11的编译器,您可以对枚举使用更强大的类型检查,请参阅http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations 。