C++ 程式設計
enum 關鍵字用於建立一個名為 name 的列舉型別,該型別包含 name-list 中的元素。var-list 引數是可選的,可用於在宣告時建立該型別的例項。
- 語法
enum name {name-list} var-list;
例如,以下程式碼建立了所需的資料型別
enum card_suit {Clubs,Diamonds,Hearts,Spades};
card_suit first_cards_suit=Diamonds;
card_suit second_cards_suit=Hearts;
card_suit third_cards_suit=0; //Would cause an error, 0 is an "integer" not a "card_suit"
card_suit forth_cards_suit=first_cards_suit; //OK, they both have the same type.
這行程式碼建立了一個新的資料型別 "card_suit",它只能取四個可能的值之一:"Clubs"、"Diamonds"、"Hearts" 和 "Spades"。一般來說,enum 命令採用以下形式
enum new_type_name { possible_value_1,
possible_value_1,
/* ..., */
possible_value_n
} Optional_Variable_With_This_Type;
而第二行程式碼建立了一個具有此資料型別的新變數,並將其初始化為 Diamonds 的值。其他行建立了此新型別的其他變數,並展示了一些可能的(和不可能的)初始化。
在內部,列舉型別儲存為整數,從 0 開始,每增加一個新的可能資料型別值就增加 1。
enum apples { Fuji, Macintosh, GrannySmith };
enum oranges { Blood, Navel, Persian };
apples pie_filling = Navel; //error can't make an apple pie with oranges.
apples my_fav_apple = Macintosh;
oranges my_fav_orange = Navel; //This has the same internal integer value as my_favorite_apple
//Many compilers will produce an error or warning letting you know your comparing two different quantities.
if(my_fav_apple == my_fav_orange)
std::cout << "You shouldn't compare apples and oranges" << std::endl;
雖然列舉型別不是整數,但在某些情況下會轉換為整數。例如,當我們嘗試將列舉型別傳送到標準輸出時。
例如
enum color {Red, Green, Blue};
color hair=Red;
color eyes=Blue;
color skin=Green;
std::cout << "My hair color is " << hair << std::endl;
std::cout << "My eye color is " << eyes << std::endl;
std::cout << "My skin color is " << skin << std::endl;
if (skin==Green)
std::cout << "I am seasick!" << std::endl;
將產生以下輸出
My hair color is 0 My eye color is 2 My skin color is 1 I am seasick!
我們可以透過引入一個包含我們列舉型別名稱的陣列來改進此示例,例如
std::string color_names[3]={"Red", "Green", "Blue"};
enum color {Red, Green, Blue};
color hair=Red;
color eyes=Blue;
color skin=Green;
std::cout << "My hair color is " << color_names[hair] << std::endl;
std::cout << "My eye color is " << color_names[eyes] << std::endl;
std::cout << "My skin color is " << color_names[skin] << std::endl;
在這種情況下,hair 在作為索引陣列時會自動轉換為整數。此技術與顏色 Red 在內部儲存為 "0",Green 在內部儲存為 "1",而 Blue 在內部儲存為 "2" 的事實密切相關。小心! 可以覆蓋這些預設的列舉型別內部值的選項。
這可以透過在 enum 中簡單地設定值來完成,例如
enum color {Red=2, Green=4, Blue=6};
事實上,沒有必要為列舉型別的每個值設定整數。在這種情況下,編譯器將簡單地將前一個可能值的數值增加 1。
考慮以下示例
enum colour {Red=2, Green, Blue=6, Orange};
這裡,"Red" 的內部值為 2,"Green" 的內部值為 3,"Blue" 的內部值為 6,"Orange" 的內部值為 7。在使用此功能時要小心,因為內部值不需要是唯一的。
在算術表示式中,列舉型別也會自動轉換為整數。這使得能夠為列舉型別的內部表示選擇特定的整數變得很有用。
可以為標準計算機螢幕的寬度和高度列舉。這可以使程式執行有意義的計算,同時仍然保持列舉型別的優點。
enum screen_width {SMALL=800, MEDIUM=1280};
enum screen_height {SMALL=600, MEDIUM=768};
screen_width MyScreenW=SMALL;
screen_height MyScreenH=SMALL;
std::cout << "The number of pixels on my screen is " << MyScreenW*MyScreenH << std::endl;
需要注意的是,列舉型別中使用的內部值是常量,在程式執行過程中無法更改。
也許值得注意的是,雖然列舉型別可以轉換為整數以便進行算術運算,但它們無法進行迭代。
例如
enum month { JANUARY=1, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER};
for( month cur_month = JANUARY; cur_month <= DECEMBER; cur_month=cur_month+1)
{
std::cout << cur_month << std::endl;
}
這將無法編譯。問題在於 for 迴圈。迴圈中的前兩個語句沒有問題。我們可以建立一個新的 month 變數並對其進行初始化。我們還可以比較兩個月,在這種情況下,它們將作為整數進行比較。我們不能遞增 cur_month 變數。"cur_month+1" 的計算結果為整數,該整數可能無法儲存到 "month" 資料型別中。
在上面的程式碼中,我們可以嘗試透過替換 for 迴圈來修復這個問題
for( int monthcount = JANUARY; monthcount <= DECEMBER; monthcount++)
{
std::cout << monthcount << std::endl;
}
這將有效,因為我們可以遞增整數 "monthcount"。