假设我有这个:
enum { A = 0x2E, B = 0x23, C = 0x40 }
可以检查x
中是否定义了enum
?
我是手动完成的:int isdef = (x == A || x == B || x == C);
但我想要更有活力的东西。 GCC-extensions
也受到欢迎。
答案 0 :(得分:13)
据我所知。 C中的枚举只是一系列
的更清晰的替代品#define A 0x2E
语句。
如果枚举很大并且其值恰好是连续的,则声明最小/最大常量并与之比较:
enum { E_MIN = 0x2E, A = 0x2E, B = 0x23, C = 0x40 ..., E_MAX=0x100};
if(x >= MIN && x <= MAX)
ItsInEnum();
答案 1 :(得分:10)
这是您问题的修改版本,但根据您正在做的事情,这样的事情可能会有效:
enum {A,B,C};
const int E[] = {0x2E,0x23,0x40};
// Or:
// enum { A = 0x2E, B = 0x23, C = 0x40 };
// const int E[] = {A,B,C};
int isEnum(int x)
{
for(int i=0; i<(sizeof(E)/sizeof(*E)); i++)
{
if(E[i] == x){ return 1; }
}
return 0;
}
int main(void)
{
printf("Value of A: 0x%02x\n", E[A]);
// Or:
// printf("Value of A: 0x%02x\n", A);
printf("isEnum(0x2e): %s\n", isEnum(0x2e) ? "true" : "false");
printf("isEnum(0x2f): %s\n", isEnum(0x2f) ? "true" : "false");
}
输出
Value of A: 0x2e isEnum(0x2e): true isEnum(0x2f): false编辑:TJD打败了我,他建议使用排序数组并进行二进制搜索会将搜索时间从 n 减少到log( n )。
答案 2 :(得分:5)
最简单的方法是:
enum {
MODE_A,
MODE_B,
MODE_C
};
int modeValid(int mode)
{
int valid = 0;
switch(mode) {
case MODE_A:
case MODE_B:
case MODE_C:
valid = 1;
};
return valid;
}
void setMode(int mode)
{
if (modeValid(mode)) {
// Blah, blah
}
}
int main(void)
{
setMode(1); // Okay
setMode(500); // Error
}
答案 3 :(得分:4)
要扩展已接受的答案,请使用X-macros使用预处理器从相同的数据构建枚举和数组。
/* Only need to define values here. */
#define ENUM_VALUES \
X(A, 0x2E) \
X(B, 0x23) \
X(C, 0x40)
/* Preprocessor builds enum for you */
#define X(a, b) a = b,
enum {
ENUM_VALUES
};
#undef X
/* Preprocessor builds array for you */
#define X(a, b) a,
const int E[] = {
ENUM_VALUES
};
#undef X
/* Copied from accepted answer */
int isEnum(int x)
{
for(int i=0; i<sizeof(E);i++)
{
if(E[i] == x){ return 1; }
}
return 0;
}
答案 4 :(得分:1)
enum
与使用宏来定义常量基本相同,只是enum
将一组关联的常量包装到数据类型中。这使您的代码更加自我记录,但实际上并没有提供任何其他功能。
如果你在标准C领域之外冒险,一些编译器可以使用enum
做额外的事情,而这些事情是他们无法用宏做的。某些调试器会将enum
变量映射回其名称,而不是显示其值。此外,一些编译器还能够为越界enum
值之类的内容添加运行时检查。这与您显示的代码基本相同,只有编译器会自动添加它。使用GreenHills的C编译器,使用-check=assignbound
编译器选项启用此功能。我不确定gcc是否有类似内置的东西。你使用什么编译器?
答案 5 :(得分:1)
这是另一种可能的解决方案:
#include <stdio.h>
#include <stdint.h>
typedef enum {
VALUE_1 = 0x01,
VALUE_2 = 0x03,
VALUE_3 = 0x0A
} values_e;
int main(void)
{
int a = 0;
values_e vlr;
for (int i = 0; i < 10; i++) {
scanf("%d", &a);
vlr = (values_e)a;
switch (vlr) {
case VALUE_1:
printf("do ... value 1:\r\n");
break;
case VALUE_2:
printf("do ... value 2:\r\n");
break;
case VALUE_3:
printf("do ... value 3:\r\n");
break;
default:
printf("ops...\r\n");
}
}
}
答案 6 :(得分:0)
正如已经指出的那样,无法通过直接引用枚举成员来检查是否定义了枚举。但是,有一个非常简单的快捷方式:定义与每个枚举类型关联的唯一标识符。然后,当您想检查枚举的元素是否存在时,您只需检查是否定义了相关的标识符:
//Header File:
typedef enum
{
ENUM_ELEMENT_1 = 0,
ENUM_ELEMENT_2 = 1,
ENUM_ELEMENT_3 = 2,
ENUM_ELEMENT_MAX
} eEnumElement;
#define ENUM_ELEMENT_DEFINED 1
...
//Source file:
void TaskOperateOnEnums(void)
{
#if defined(ENUM_ELEMENT_DEFINED)
eEnumElement Test = ENUM_ELEMENT_1;
...
#endif
}