c++ enum用法【轉】

來源:互聯網
上載者:User

標籤:

1、為什麼要用enum 
      寫程式時,我們常常需要為某個對象關聯一組可選alternative屬性.例如,學生的成績分A,B,C,D等,天氣分sunny, cloudy, rainy等等。 
      更常見的,開啟一個檔案可能有三種狀態:input, output和append. 典型做法是,對應定義3個常數,即: 
      const int input = 1; 
      const int output = 2; 
      const int append = 3; 
然後,調用以下函數: 
      bool open_file(string file_name, int open_mode); 
比如, 
    open_file("Phenix_and_the_Crane", append); 
       這種做法比較簡單,但存在許多缺點,主要的一點就是無法限制傳遞給open_file函數的第2個參數的取值範圍,只要傳遞int類型的值都是合法的。(當然,這樣的情況下的應對措施就是在open_file函數內部判斷第二個參數的取值,只有在1,2,3範圍內才處理。) 
       使用枚舉能在一定程度上減輕這種尷尬(注1),它不但能實作類別似於之前定義三個常量的功能,還能夠將這三個值組合起來成為獨一無二的組。例如: 
      enum open_modes {input = 1, output, append}; 
      以上定義了open_modes為枚舉類型enumeration type。每一個命名了的枚舉都是唯一的類型,是一個類型標示器type specifier。例如,我們可以重新寫一個open_file函數: 
      bool open_file(string file_name, open_modes om); 
      在open_modes枚舉中,input, output, append稱為枚舉子enumerator, 它們限定了open_modes定義的對象的取值範圍。這個時候,調用open_file函數和之前的方法還是一模一樣: 
     open_file("Phenix_and_the_Crane", append); 
     但是,如果傳遞給open_file的第二個參數不是open_modes枚舉類型值的話(注1),那麼編譯器就會識別出錯誤;就算該參數取值等價於input, output, append中的某個, 
也一樣會出錯哦!例如: 
     open_file("Phenix_and_the_Crane", 1);


2、枚舉的定義 
      一個枚舉是一個類型,可以儲存一組由使用者刻畫的值。定義之類,枚舉的使用很像一個整數類型。 
枚舉的定義具有以下形式,即以關鍵詞enum開頭,接著一個可選的枚舉名,下來是由大括弧{}包含著一個由逗號分隔的枚舉子列表enumerators list: 
enum [enumeration name] {enumerator1[=value1], enumerator2[=value2], ...};

 

3、枚舉子的類型和取值 
      枚舉子的類型就是它所在的那個枚舉,例如前面說到的open_modes枚舉中,input,output和append等枚舉子的類型都是open_modes。這種做法,其實是為了賦予使用者和編譯器一些有關該變數擬議中的用途的提示。 
      預設下,第一個枚舉子被賦值0,接下來的枚舉子取值是前面一個枚舉子的取值+1,例如: 
      enum weather {sunny, cloudy, rainy, windy}; 
其中 
     sunny == 0, 
      cloudy == 1, 
      rainy == 2, 
      windy == 3; 
       以上是預設情況,有時候我們希望顯式地指定某個枚舉子的值,那麼會出現什麼情況呢?看看: 
       enum some_fruit {apple = 3, orange, banana = 4, bear}; 
       好了,apple == 3, banana == 4; 那麼orange和bear呢?記得前面說過一句,預設下”接下來的枚舉子取值是前面一個枚舉子的取值+1“。既然這兩個枚舉子沒有顯式賦值,那麼就按照預設規則辦事,所以 orange == 4, bear == 5. 
       從這個例子也可以看出,同一枚舉中枚舉子的取值不需要唯一。這樣有什麼用處呢?下面是個簡單的例子: 
       enum some_big_cities { 
                                               Guangzhou = 4, 
                                                Shenzhen    = 4, 
                                               Hongkong   = 4, 
                                               Shanghai    = 2, 
                                               Beijing         = 3, 
                                               Chongqi      = 3 
                                           }; 
以上簡單地按地區,將五個城市按照華南(4),華東(2), 華北(3)的幾個城市分類了。


4、枚舉變數的定義、初始化和賦值 
     既然每個枚舉都是一個類型,那麼由這個類型自然可以聲明變數,例如,由前面定義的some_big_cities: 
     some_big_cities where_I_am; 
     需要注意的是,在聲明where_I_am時沒有初始化,如果這時列印where_I_am的值: 
     enum some_big_cities { 
                                            Guangzhou = 4, 
                                            Shenzhen = 4, 
                                            Hongkong = 4, 
                                             Shanghai = 2, 
                                            Beijing = 3, 
                                             Chongqi = 5}; 
int main(void) 

      some_big_cities wh; 
     cout<<"the value is: "<<wh<<endl; 
     return 0; 

輸出將是the value is: 1. 然而,如果聲明wh為全域變數,則另一種情況: 
enum some_big_cities {Guangzhou = 1 Shenzhen = 1, Hongkong = 1, 
                                       Shanghai = 2, Beijing = 3, Chongqi = 5}; 
some_big_cities wh; 
int main(void) 

   cout<<"the value is: "<<wh<<endl;   
   return 0; 

輸出將是the value is: 0; 
      以上結果是在Visual C++ 2005 Express中得到,不知道其它編譯器情況如何,也不知為什麼得到這樣的結果。下來再找找資料。 
     定義一個枚舉變數時,可以給它初始化,例如: 
     some_big_cities wh = Guangzhou; 
     注意等號右邊只能取枚舉子中的某一個;特別地,以Guangzhou為例,雖然Guangzhou==4, 但以下初始化是出錯的: 
     some_big_cities wh = 4; 
     Visual C++ 2005編譯器提示: 
error C2440: ‘initializing‘ : cannot convert from ‘int‘ to ‘some_big_cities‘ 
      可見,不能直接地把一個整型賦值給一個枚舉變數,因為枚舉和整型是不同類型的,除非顯式轉換。關於枚舉與整型的關係,後面再講。 
      除了初始化,枚舉變數也有賦值運算: 
     some_big_cities wh; 
     wh = Guangzhou; 
     wh = Shanghai; 
或者 
    some_big_cities wh1 = Guangzhou; 
    some_big_cities wh2 = Shanghai; 
    wh2 = wh1;


5、枚舉的取值範圍 
   如果某個枚舉中所有枚舉子的值均非負,該枚舉的表示範圍就是[0:2^k-1],其中2^k是能使所有枚舉子都位於此範圍內的最小的2的冪;如果存在負的枚舉值,該枚舉的取值範圍就是[-2^k,2^k-1].例如: 
   enum e1 {dark, light}; //範圍0:1 
    enum e3 {min = -10, max = 1000}; //範圍-1024:1023


6、枚舉與整型的關係 
    整型值只能顯式地轉換成一個枚舉值,但是,如果轉換的結果位於該枚舉取值範圍之外,則結果是無定義的。 
     enum e1 {dark = 1, light = 10}; 
     e1 VAR1 = e1(50); //無定義 
     e1 VAR2 = e1(3); //編譯通過 
     在這裡也說明了不允許隱式地從整型轉換到枚舉的原因,因為大部分整型值在特定的枚舉裡沒有對應的表示。 
      至於枚舉可以當作特定的整型數來用的例子,從open_modes可以體會。


7、自訂運算子 
      枚舉是使用者自訂類型,所以在使用者可以為它定義自身的操作,例如++或者<<等。但是,在沒有定義之前,不能因為枚舉像整型就可以預設使用,例如: 
   enum SomeCities 

   zhanjiang, 
   Maoming, 
   Yangjiang, 
   Jiangmen, 
   Zhongshan 
}; 
SomeCities oneCity=  Yangjiang; 
for (oneCity = zhanjiang; oneCity != Zhongshan; ++oneCity) 

   cout<<oneCity<<endl;

cout<<oneCity+  Yangjiang<<endl;//正確 

 

cout<<oneCity+oneCity<<endl;//正確 



以上的++OneCity是沒有定義的,在Visual C++ 6 編譯下得到如下錯誤: 
error C2675: unary ‘++‘ : ‘enum main::SomeCities‘ does not define this operator or a conversion to a type acceptable to the predefined operator


8、Sizeof


    一個枚舉類型的sizeof就是某個能夠容納其範圍的整型的sizeof, 而且不會大於sizeof(int), 除非某個枚舉子的值不能用int或者unsigned int來表示。 
      在32位機器中,sizeof(int)一般等於4。前面介紹的所有枚舉,例如, 
enum SomeCities 

   zhanjiang, 
   Maoming, 
   Yangjiang, 
   Jiangmen, 
   Zhongshan 
}; 
計算其sizeof, 可能是1,也可能是是4。在我的intel E2160雙核、32位機器中,得到4。

 


----------------------------------------------------------------------------------- 
[注1, Begin
由於通過將整型數顯式轉換就可能得到對應枚舉類型的值,所以聲明一個枚舉來達到限制傳遞給函數的參數取值範圍還是力不從心的,以下是一個例子: 
enum SomeCities 

zhanjiang=1, //1 
Maoming,     //2 
Yangjiang,   //3 
Jiangmen,   //4 
Zhongshan = 1000 //1000 
}; 
void printEnum(SomeCities sc) 

cout<<sc<<endl; 

int main(void) 

SomeCities oneCity = SomeCities(50); //將50通過顯式轉換,為oneCity賦值 
printEnum(oneCity); //在VC++ 6 編譯器下得到50輸出 
return 0; 

以上例子說明,雖然SomeCities的定義裡沒有賦值為50的枚舉值,但是,由於50在該枚舉的取值範圍內,所以通過顯式聲明得到一個有定義的枚舉值,從而成功傳遞給printEnum函數。 
[注1, End]

c++ enum用法【轉】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.