2012-02-06 83 views
12

我有一個枚舉:如何檢查一個枚舉變量是否有效?

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似乎並不如此優雅。

有沒有更好的方法來檢查一個枚舉是否有效?

+0

不具有標準的副本,我就會撕開這麼說,沒有引用它,所以我會讓它評論:在我看到每個C或C++實現,'enum'值都是按遞增的數字順序分配的。所以你所要做的就是在'enum'中加入'firstEnum = typeA,lastEnum = typeC',然後用'if(int(inputEnum) int(lastEnum) ){/ *處理錯誤* /}'。 – 2012-02-06 14:49:51

回答

18

一個常見的約定是做這樣的事情:

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會自動更新並且您的錯誤檢查代碼無需更改。

+0

你的枚舉聲明後'myenum_t'是什麼意思? [C#參考](http://msdn.microsoft.com/en-us/library/sbbt4032.aspx)似乎沒有提及它;在大括號之後,他們的例子都沒有任何東西。 – 2013-08-12 17:02:44

+0

@PatrickM它在C中是必需的,但在C++或C#中不需要,因爲在C中不能使用枚舉標記作爲類型。然而,在上面的答案中,我希望在'enum'關鍵字之前看到'typedef'關鍵字,並聲明'myenum_t'與'enum myenum'是同一類型。 – 2013-11-15 18:27:47

+0

如果這個枚舉是公開的,那麼你將num_types公開給這個世界。有沒有辦法解決這個問題? – duhanebel 2015-05-06 14:14:06

3

是的。

讓編譯器完成它的工作,不要將int轉換爲enum類型,你應該很好。

+0

但有時我們需要投入 – 2016-09-15 14:20:55

5

你可以使用按位枚舉:

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

這是當然,假設你不爲你的枚舉,這是除非使用逐枚舉相當罕見設置手動值。

+0

如果將更多值添加到枚舉中,這是否工作? – 2012-02-06 14:52:18

+3

「但是,隨着myenum_t越來越多的價值增長」。是不是有'1 << n'溢出的機會? – 2012-02-06 14:54:39

+0

@LuchianGrigore的排序。您必須將變量名稱添加到or語句,但是如果您忘記這麼做,那麼不會。這只是一個更簡潔的方式來檢查它是否是一組三個值。是的,它可能會溢出,取決於您正在開發的機器上的整數大小。然而,根據我的經驗,在一個枚舉中處理超過32個不同的值是很少見的,這是對你所能達到的最大值的一個很好的估計。 – 2012-02-06 14:56:41

0

你能不能也這樣做

enum myEnum {typeA,typeB, typeC}; 

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

編譯器是否有機會優化檢查?如果添加* LastType *,那麼檢查'arg1 dashesy 2012-07-13 18:33:16

0

不幸的是,沒有一個簡單的方法來做到這一點的語言水平(至少C),你只需要確保你只使用變量通過enum定義。

雖然你可以用-Werror啓用以下編譯器警告之一在一起:如果枚舉中的一個被錯過

  • -Wswitch
  • -Wswitch-default
  • -Wswitch-enum

這使得構建失敗內部開關。

0

枚舉在C++已經具有較強的類型比C.

採取以下簡單的程序:

#include <iostream> 

enum E 
{ 
    A, 
    B 
}; 

void f(E 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)’ 

所以你可以看到枚舉成員已經被檢查過。

如果您想要更強大的類型檢查,並且具有支持C++ 11的編譯器,則可以使用更強大的類型檢查枚舉,請參閱http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations

+0

什麼是'e'? – 2015-12-01 15:18:11

+1

@LightnessRacesinOrbit我真的不知道它應該是什麼,我的記憶幾乎四年後有點朦朧...... :)它可能*被認爲是一個整數字面量。 – 2015-12-01 15:25:17

1

一招我在過去使用:

enum foo {FIRST_FOO, BAR, BLETCH, BLURGA, BLAH, LAST_FOO}; 

,然後檢查,看看你的價值> FIRST_FOO && < LAST_FOO

當然,這假定您的枚舉值之間沒有差距。

否則,不,沒有什麼好的方法來做你要求的東西(至少在C中)。


從最新的在線 C Language Standard

6.7.2.2 Enumeration specifiers
...
3 The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted. 109) An enumerator with = defines its enumeration constant as the value of the constant expression. If the first enumerator has no = , the value of its enumeration constant is 0 . Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant. (The use of enumerators with = may produce enumeration constants with values that duplicate other values in the same enumeration.) The enumerators of an enumeration are also known as its members.
相關問題