私がこれを持っていると仮定すると:
enum { A = 0x2E, B = 0x23, C = 0x40 }
x
に定義されているかどうかを確認できenum
ますか?
私はそれを手動でやっています:int isdef = (x == A || x == B || x == C);
しかし、私はもっとダイナミックな何かをしたいです。GCC-extensions
大歓迎です。
私の知る限りではありません。Cの列挙型は、一連の
#define A 0x2E
ステートメント。
列挙型が大きく、その値がたまたま連続している場合は、最小/最大定数を宣言し、それらと比較します。
enum { E_MIN = 0x2E, A = 0x2E, B = 0x23, C = 0x40 ..., E_MAX=0x100};
if(x >= MIN && x <= MAX)
ItsInEnum();
これはあなたの質問の一種の修正版ですが、あなたがしていることに応じて、このようなものがうまくいくかもしれません:
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");
}
どの出力
Aの値:0x2e isEnum(0x2e):true isEnum(0x2f):false
編集:TJDは私を打ち負かしました、そしてソートされた配列を使用してバイナリ検索を行うという彼の提案はあなたの検索時間をnからlog(n)に減らすでしょう。
これを行う最も簡単な方法は次のとおりです。
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
}
受け入れられた回答を拡張するには、Xマクロを使用して、プリプロセッサを使用して同じデータから列挙型と配列を構築します。
/* 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;
}
Anenum
は、マクロを使用して定数を定義するのと本質的に同じですがenum
、関連付けられた定数のセットをデータ型にラップする点が異なります。これにより、コードはより自己文書化されますが、実際には追加機能は提供されません。
標準Cの領域外に出かける場合、一部のコンパイラーはenum
、マクロでは実行できない追加の処理を実行できます。一部のデバッガーはenum
、変数の値を表示する代わりに、変数を名前にマップし直します。また、一部のコンパイラは、範囲外の値などの実行時チェックを追加する機能を提供しenum
ます。これは基本的に表示するコードと同じですが、コンパイラーのみが自動的に追加します。GreenHillsのCコンパイラでは、この機能は-check=assignbound
コンパイラオプションで有効になります。gccにこのようなものが組み込まれているかどうかはわかりません。どのコンパイラを使用していますか?
別の可能な解決策は次のとおりです。
#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");
}
}
}
すでに指摘したように、列挙型メンバーを直接参照して列挙型が定義されているかどうかを確認することはできません。ただし、非常に簡単なショートカットがあります。列挙型ごとに関連付けられた一意の識別子を定義します。次に、列挙型の要素が存在するかどうかを確認する場合は、関連付けられた識別子が定義されているかどうかを簡単に確認できます。
//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
}