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

C 如何检查枚举变量是否有效?,c,enums,C,Enums,我有一个枚举: 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 pa

我有一个枚举:

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\u t
随着越来越多的值而增长,
myfunction
似乎并不那么优雅

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


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

您可以使用按位枚举:

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;
}
enum myEnum{

typeA=1你不能也做类似的事情吗

enum myEnum {typeA,typeB, typeC};

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

如果(arg1>=typeA&&arg1不幸的是,没有一种简单的方法可以在语言级别执行(至少使用
C
),您只需确保只使用通过
enum
定义的变量即可

尽管您可以同时启用以下编译器警告之一和
-Werror

  • -Wswitch
  • -Wswitch default
  • -Wswitch enum

如果在交换机中丢失了一个枚举,则会导致生成失败。

< P>枚举在C++中已经比C.

有更强的类型。 以下面的简单程序为例:

#include <iostream>

enum E
{
    A,
    B 
};

void f(E e)
{
}

int main()
{
    f(1);
}
#包括
枚举E
{
A.
B
};
无效f(E)
{
}
int main()
{
f(1);
}
使用GCC编译器,我将得到一个错误提示:

enum.cpp: In function ‘int main()’: enum.cpp:15: error: invalid conversion from ‘int’ to ‘E’ enum.cpp:15: error: initializing argument 1 of ‘void f(E)’ enum.cpp:在函数“int main()”中: 枚举.cpp:15:错误:从“int”到“E”的转换无效 枚举.cpp:15:错误:初始化“void f(E)”的参数1 如您所见,枚举成员已被选中


如果您想要更强大的类型检查,并且有一个支持C++11的编译器,您可以对枚举使用更强大的类型检查,请参阅。

这方面的常见约定是执行以下操作:

typedef enum {
  typeA,
  typeB,
  typeC,
  num_types
} myenum_t;
然后您可以检查
(t

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

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

然后自动更新
num\u types
,您的错误检查代码无需更改。

我过去使用过的一个技巧:

enum foo {FIRST_FOO, BAR, BLETCH, BLURGA, BLAH, LAST_FOO};
然后检查您的值是否为
>FIRST\u FOO&&
1

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

否则,就没有好的方法来满足您的要求(至少在C语言中是这样)


1来自最新在线:

6.7.2.2枚举说明符

3枚举器列表中的标识符声明为常量,其类型为
int
和 可以出现在允许的任何地方。109)带有
=
的枚举数定义其 枚举常量作为常量表达式的值。如果第一个枚举数 否
=
,其枚举常量的值为
0
。每个后续的枚举数都没有
=
将其枚举常量定义为通过以下方式获得的常量表达式的值: 将
1
添加到上一个枚举常量的值。(使用带有
=
可能会生成枚举常量,其值与相同类型中的其他值重复 枚举)枚举的枚举数也称为其成员。
如果没有引用的标准,我会在没有引用的情况下说出来,所以我会做一个评论:在我看到的每一个C或C++实现中, EnUM/<代码>值都是按数字顺序增加的。所以你需要做的就是添加<代码> FiStUnm = Type,LaStime= Type Ec/<代码>到你的代码> EnUM<代码>范围内。使用
if(int(inputEnum)int(lastEnum)){/*handle error*/}
“但是,随着myenum随着值的增加而增加”。使用
1@LuchianGrigore不是有可能溢出吗?您必须将变量名添加到or语句中,但如果您忘记这样做,则不会。这只是一种更简洁的方法来检查它是否由三个值组成。是的,它可能溢出,具体取决于您开发的计算机上的整数大小。但是,根据我的经验,在一个枚举中处理超过32个不同的值是很少见的,这是对最大值的一个很好的估计。这似乎有点过分,但这只是我。问题是,你不能依赖于此。这会导致UB。因此,你可能不走运,让它在你的配置中工作,但当发送到客户端时,它会崩溃h、 我会避免这种情况。编译器是否有可能优化了检查?如果添加了LastType,则check
arg1
不应优化,类似地,可能需要FirstType。在您的enum声明之后,
myenum\u t
意味着什么?似乎没有提到它;他们的示例中没有任何一个有任何内容在关闭括号之后,@ PATRIKM是在C中所需要的,但不是C++或C语言中的,因为C中不能使用EnUM标签作为类型。但是,在上述答案中,我希望在 EnUM< /COD>关键字之前,可以看到< <代码> TyPulf< /Cuff>关键字,声明<代码> MyQueLoT> < /C> >与<代码> Enm MyNeNU<代码相同。>。如果该枚举是面向公众的,那么您将向全世界公开num_类型。有什么办法吗?@duhanebel:嗯,它需要公开,以便用于错误检查(毕竟这是问题的关键),它还可用于定义数组大小等。显然,您会使用除
num_类型
以外的名称,即适合您特定
enum
定义的名称。@duhanebel:这取决于enum的使用范围-如果它是在公共头文件中定义的,并且在多个API中使用,那么所有模块至少,这些API可能希望使用num_类型进行健全性检查、验证等。我的另一点是,它对于定义数组大小等非常有用,例如数组维度需要与枚举中的类型数相对应。@LightnessRacesinOrbit I
enum foo {FIRST_FOO, BAR, BLETCH, BLURGA, BLAH, LAST_FOO};