如何检查枚举变量是否有效?
我有一个枚举:
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 。