[英]Good use cases for declaring enum type tags and variable names in C?
如果您的代碼中需要一些常量,您可以使用枚舉聲明它們:
enum {
DOG,
CAT,
FISH,
};
enum {
CAR,
BUS,
TRAIN,
};
然后根據需要使用DOG
、 BUS
等。 但是枚舉也可以用更詳細的樣式聲明:
enum animals {
DOG,
CAT,
FISH,
} pets;
enum transport {
CAR,
BUS,
TRAIN,
} vehicles;
鑒於枚舉常量具有全局范圍並且不能像結構和聯合那樣被pets.DOG
引用, pets.DOG
詳細樣式有什么好的用例嗎? 對我來說,枚舉的類型標簽和變量名看起來很多余,甚至令人反感,因為它們看起來像結構,但不能像結構一樣使用。 我希望我遺漏了一些東西,它們確實有很好的用處。
有一個相關的SO Q&A ,其中最重要的假設是在使用枚舉時會使用類型標記和變量名稱。 所以我的問題可以重申為“如果我只使用匿名枚舉,我會在哪些任務中失敗?” 因為對我來說,枚舉的全部意義在於DOG
、 CAT
、 CAR
常量,我認為將其中之一分配給枚舉變量沒有用。 我還在學習,所以我確定我一定遺漏了一些東西。
如果您想聲明該類型的變量,您可以為enum
類型命名:
enum animals a1 = DOG;
enum animals a2 = CAT;
或者將它們作為函數參數:
void foo(enum animals a);
雖然枚舉被認為是整數類型,並且您也可以使用int
來存儲這些值之一,但使用enum
類型的變量有助於記錄您的代碼並使您的意圖對讀者清晰。
“對我來說,枚舉的類型標簽和變量名看起來很多余......”
以枚舉列表 ( enum
) 的形式使用命名整數值的順序集合的價值乍一看似乎很微妙,但由於以下幾個原因,在 C 項目中使用時變得非常明顯:
enum
是一個很好的例子,用於枚舉例如大量命令或公司內的職位類型。)switch
語句中用作每個case
語句的常量整數值時。 關於評論: “......但是使用ANML
類型而不是int
的優勢是最小的,......”
enum
列表還提供了記錄約束。 例如使用ANML anml;
而不是int anml;
因為struct
成員將快速向那些將維護/更新源代碼的人(在未來幾個月或幾年內。)指出該成員被限制使用的相關值的關聯列表,而不是任何隨機整數值. 這在使用枚舉列表時很重要,例如。 在 switch 語句中,該語句僅用於處理與該enum
的常量整數值相對應的一組case
語句。這兩個一起是我發現特別有用的用例的一部分,即使用枚舉與字符串數組結合為用戶界面選擇內容,或用於子字符串搜索等。
例如:
typedef enum {
CAT,
DOG,
FISH,
MAX_ANML
}ANML;//for use in struct
char *strings[MAX_ANML] = {"cat","dog","fish"};
typedef struct {
char content[80];
ANML anml;
}SEARCH;
例如,這兩個結構可以與switch
語句結合使用:
bool searchBuf(SEARCH *animal)
{
bool res = FALSE;
switch (animal->anml) {
case CAT:
//use the string animal[type] for a search, or user interface content, etc.
if(strstr(animal->content, strings[CAT]))
res = TRUE;
break;
case DOG:
if(strstr(animal->content, strings[DOG]))
res = TRUE;
break;
case FISH:
if(strstr(animal->content, strings[FISH]))
res = TRUE;
break;
};
return res;
}
int main(void)
{
char buffer[] = {"this is a string containing cat."};
SEARCH search;
strcpy(search.content, buffer);
search.anml = CAT;
bool res = searchBuf(&search);
//use res...
return 0;
}
我在調試時喜歡枚舉而不是 #defines。 debuer 不僅顯示數值,還顯示枚舉名稱 - 非常方便
在許多其他人發布了有用的答案和評論之后,我發布了我自己的答案,我們已經確定枚舉類型名和變量名作為自文檔代碼很有用,並使代碼的意圖清晰(感謝答案作者:ryyker 和 dbush)。
當我正在試驗並尋找使用非匿名枚舉的更有力的理由時,我確定不能有任何定義。 枚舉沒有范圍和邊界檢查,在編譯時 (GCC 6) 和運行時都沒有。 這是一個演示弱點的片段:
enum withType { // enum with type name and variable name
ONE,
TWO,
THREE,
} wtEnum;
enum { // Anonymous enum
TINY,
SMALL,
MID,
LARGE,
BIGGEST,
};
int main(void) {
enum withType wt1 = LARGE; // Overflow!
wtEnum = BIGGEST; // Overflow!
printf("Enum test values: %d, %d, %d\n", THREE, wt1, wtEnum);
return 0;
};
該示例清楚地表明,您可能想要對枚舉類型名稱和變量名稱進行的任何“范圍界定”僅是約定俗成的,並且依賴於編碼人員的紀律,不要跨越枚舉“域”。 我什至聲稱,鑒於這一現實,C 中的枚舉功能是“設計錯誤的”。 它創造了我們在結構和聯合中看到的那種實用程序的印象,但沒有提供任何類似的東西。 在此洞察之后,我認為匿名枚舉是唯一可以使用的安全枚舉!
盡管如此,我已經接受了 ryyker 的回答,因為它很好地展示了枚舉的主流用法。 但我也在這里留下我自己的答案,因為我提出的觀點是有效的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.