简体   繁体   English

检查是否在C enum中定义了值?

[英]Check if a value is defined in an C enum?

Assuming that I have this: 假设我有这个:

enum { A = 0x2E, B = 0x23, C = 0x40 }

it's possible check if x is defined into enum ? 可以检查x是否定义为enum

I'm doing it manually: int isdef = (x == A || x == B || x == C); 我是手动完成的: int isdef = (x == A || x == B || x == C); But I want to something more dynamic. 但我想要更有活力的东西。 GCC-extensions are welcome too. GCC-extensions也是受欢迎的。

Not to the best of my knowledge. 不是我所知道的。 An enum in C is just a cleaner alternative to a series of C中的枚举只是一系列更清晰的替代品

#define A 0x2E

statements. 声明。

If the enum is large and its values happen to be continuous, declare min/max constants and compare to those: 如果枚举很大并且其值恰好是连续的,则声明最小/最大常量并与之比较:

enum { E_MIN = 0x2E, A = 0x2E, B = 0x23, C = 0x40 ..., E_MAX=0x100};

if(x >= MIN && x <= MAX)
    ItsInEnum();

This is kind of a modified version of your question, but depending on what you're doing, something like this might work: 这是你问题的修改版本,但根据你正在做的事情,这样的事情可能有效:

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");
}

which outputs 哪个输出

Value of A: 0x2e
isEnum(0x2e): true
isEnum(0x2f): false

EDIT: TJD beat me to it, and his suggestion of using a sorted array and doing binary search would decrease your search time from n to log( n ). 编辑:TJD打败了我,他建议使用排序数组并进行二分查找会减少你从n到log( n )的搜索时间。

To expand on the accepted answer, use X-macros to build your enum and array from the same data using the preprocessor. 要扩展已接受的答案,请使用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;
}

The easiest way to do this is: 最简单的方法是:


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
}

An enum is essentially the same thing as using macros to define constants, except that the enum wraps a set of associated constants up into a data type. enum与使用宏来定义常量基本相同,只是enum将一组关联的常量包装到数据类型中。 This makes your code more self-documenting, but doesn't really provide any additional functionality. 这使您的代码更加自我记录,但实际上并没有提供任何其他功能。

If you venture outside the realm of standard C, some compilers can do extra things with enum that they can't do with macros. 如果你在标准C的范围之外冒险,一些编译器可以使用enum来做额外的事情,而不能用宏做。 Some debuggers will map enum variables back to their name instead of showing their value. 一些调试器会将enum变量映射回其名称,而不是显示其值。 Also, some compilers provide the ability to add run-time checks for things like out-of-bounds enum values. 此外,一些编译器提供了为诸如越界enum值之类的事物添加运行时检查的能力。 This is essentially the same as the code you show, only the compiler adds it automatically. 这与您显示的代码基本相同,只有编译器会自动添加它。 With GreenHills' C compiler, this feature is enabled with the -check=assignbound compiler option. 使用GreenHills的C编译器,可以使用-check=assignbound编译器选项启用此功能。 I'm not sure if gcc has something like this built-in or not. 我不确定gcc是否有类似内置的东西。 What compiler are you using? 你用的是什么编译器?

Here is another possible solution: 这是另一种可能的解决方案

#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");
    }
  }
}

As already pointed out, it is not possible to check if an enum is defined by directly referring to an enum member. 正如已经指出的那样,无法通过直接引用枚举成员来检查是否定义了枚举。 However, there is a very simple shortcut: define a unique identifier associated with each enumerated type. 但是,有一个非常简单的快捷方式:定义与每个枚举类型关联的唯一标识符。 Then, when you want to check if an element of the enumeration exists, you can simply check if the associated identifier is defined: 然后,当您要检查枚举的元素是否存在时,您只需检查是否定义了关联的标识符:

//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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM