枚舉的用法詳細(xì)總結(jié)
1、枚舉enum的用途淺例
寫(xiě)程序時(shí),我們常常需要為某個(gè)對(duì)象關(guān)聯(lián)一組可選alternative屬性.例如,學(xué)生的成績(jī)分A,B,C,D等,天氣分sunny, cloudy, rainy等等。
更常見(jiàn)的,打開(kāi)一個(gè)文件可能有三種狀態(tài):input, output和append. 典型做法是,對(duì)應(yīng)定義3個(gè)常數(shù),即:
const int input = 1;
const int output = 2;
const int append = 3;
然后,調(diào)用以下函數(shù):
bool open_file(string file_name, int open_mode);
比如,
open_file("Phenix_and_the_Crane", append);
這種做法比較簡(jiǎn)單,但存在許多缺點(diǎn),主要的一點(diǎn)就是無(wú)法限制傳遞給open_file函數(shù)的第2個(gè)參數(shù)的取值范圍,只要傳遞int類型的值都是合法的。(當(dāng)然,這樣的情況下的應(yīng)對(duì)措施就是在open_file函數(shù)內(nèi)部判斷第二個(gè)參數(shù)的取值,只有在1,2,3范圍內(nèi)才處理。)
使用枚舉能在一定程度上減輕這種尷尬(注1),它不但能實(shí)現(xiàn)類似于之前定義三個(gè)常量的功能,還能夠?qū)⑦@三個(gè)值組合起來(lái)成為獨(dú)一無(wú)二的組。例如:
enum open_modes {input = 1, output, append};
以上定義了open_modes為枚舉類型enumeration type。每一個(gè)命名了的枚舉都是唯一的類型,是一個(gè)類型標(biāo)示器type specifier。例如,我們可以重新寫(xiě)一個(gè)open_file函數(shù):
bool open_file(string file_name, open_modes om);
在open_modes枚舉中,input, output, append稱為枚舉子enumerator, 它們限定了open_modes定義的對(duì)象的取值范圍。這個(gè)時(shí)候,調(diào)用open_file函數(shù)和之前的方法還是一模一樣:
open_file("Phenix_and_the_Crane", append);
但是,如果傳遞給open_file的第二個(gè)參數(shù)不是open_modes枚舉類型值的話(注1),那么編譯器就會(huì)識(shí)別出錯(cuò)誤;就算該參數(shù)取值等價(jià)于input, output, append中的某個(gè),也一樣會(huì)出錯(cuò)哦!例如:
open_file("Phenix_and_the_Crane", 1);
2、枚舉的定義
一個(gè)枚舉是一個(gè)類型,可以保存一組由用戶刻畫(huà)的值。定義之類,枚舉的使用很像一個(gè)整數(shù)類型。
枚舉的定義具有以下形式,即以關(guān)鍵詞enum開(kāi)頭,接著一個(gè)可選的枚舉名,下來(lái)是由大括號(hào){}包含著一個(gè)由逗號(hào)分隔的枚舉子列表enumerators list:
enum [enumeration name] {enumerator1[=value1], enumerator2[=value2], ...};
3、枚舉子的類型和取值
枚舉子的類型就是它所在的那個(gè)枚舉,例如前面說(shuō)到的open_modes枚舉中,input,output和append等枚舉子的類型都是open_modes。這種做法,其實(shí)是為了賦予用戶和編譯器一些有關(guān)該變量擬議中的用途的提示。
默認(rèn)下,第一個(gè)枚舉子被賦值0,接下來(lái)的枚舉子取值是前面一個(gè)枚舉子的取值+1,例如:
enum weather {sunny, cloudy, rainy, windy};
其中
sunny == 0,
cloudy == 1,
rainy == 2,
windy == 3;
以上是默認(rèn)情況,有時(shí)候我們希望顯式地指定某個(gè)枚舉子的值,那么會(huì)出現(xiàn)什么情況呢?看看:
enum some_fruit {apple = 3, orange, banana = 4, bear};
好了,apple == 3, banana == 4; 那么orange和bear呢?記得前面說(shuō)過(guò)一句,默認(rèn)下”接下來(lái)的枚舉子取值是前面一個(gè)枚舉子的取值+1“。既然這兩個(gè)枚舉子沒(méi)有顯式賦值,那么就按照默認(rèn)規(guī)則辦事,所以 orange == 4, bear == 5.
從這個(gè)例子也可以看出,同一枚舉中枚舉子的取值不需要唯一。這樣有什么用處呢?下面是個(gè)簡(jiǎn)單的例子:
enum some_big_cities {
Guangzhou = 4,
Shenzhen = 4,
Hongkong = 4,
Shanghai = 2,
Beijing = 3,
Chongqi = 3
};
以上簡(jiǎn)單地按區(qū)域,將五個(gè)城市按照華南(4),華東(2), 華北(3)的幾個(gè)城市分類了。
4、枚舉變量的定義、初始化和賦值
既然每個(gè)枚舉都是一個(gè)類型,那么由這個(gè)類型自然可以聲明變量,例如,由前面定義的some_big_cities:
some_big_cities where_I_am;
需要注意的是,在聲明where_I_am時(shí)沒(méi)有初始化,如果這時(shí)打印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;
以上結(jié)果是在Visual C++ 2005 Express中得到,不知道其它編譯器情況如何,也不知為什么得到這樣的結(jié)果。下來(lái)再找找資料。
定義一個(gè)枚舉變量時(shí),可以給它初始化,例如:
some_big_cities wh = Guangzhou;
注意等號(hào)右邊只能取枚舉子中的某一個(gè);特別地,以Guangzhou為例,雖然Guangzhou==4, 但以下初始化是出錯(cuò)的:
some_big_cities wh = 4;
Visual C++ 2005編譯器提示:
error C2440: 'initializing' : cannot convert from 'int' to 'some_big_cities'
可見(jiàn),不能直接地把一個(gè)整型賦值給一個(gè)枚舉變量,因?yàn)槊杜e和整型是不同類型的,除非顯式轉(zhuǎn)換。關(guān)于枚舉與整型的關(guān)系,后面再講。
除了初始化,枚舉變量也有賦值運(yùn)算:
some_big_cities wh;
wh = Guangzhou;
wh = Shanghai;
或者
some_big_cities wh1 = Guangzhou;
some_big_cities wh2 = Shanghai;
wh2 = wh1;
5、枚舉的取值范圍
如果某個(gè)枚舉中所有枚舉子的值均非負(fù),該枚舉的表示范圍就是[0:2^k-1],其中2^k是能使所有枚舉子都位于此范圍內(nèi)的最小的2的冪;如果存在負(fù)的枚舉值,該枚舉的取值范圍就是[-2^k,2^k-1].例如:
enum e1 {dark, light}; //范圍0:1
enum e3 {min = -10, max = 1000}; //范圍-1024:1023
6、枚舉與整型的關(guān)系
整型值只能顯式地轉(zhuǎn)換成一個(gè)枚舉值,但是,如果轉(zhuǎn)換的結(jié)果位于該枚舉取值范圍之外,則結(jié)果是無(wú)定義的。
enum e1 {dark = 1, light = 10};
e1 VAR1 = e1(50); //無(wú)定義
e1 VAR2 = e1(3); //編譯通過(guò)
在這里也說(shuō)明了不允許隱式地從整型轉(zhuǎn)換到枚舉的原因,因?yàn)榇蟛糠终椭翟谔囟ǖ拿杜e里沒(méi)有對(duì)應(yīng)的表示。
至于枚舉可以當(dāng)作特定的整型數(shù)來(lái)用的例子,從open_modes可以體會(huì)。
7、自定義運(yùn)算符
枚舉是用戶自定義類型,所以在用戶可以為它定義自身的操作,例如++或者<<等。但是,在沒(méi)有定義之前,不能因?yàn)槊杜e像整型就可以默認(rèn)使用,例如:
enum SomeCities
{
zhanjiang,
Maoming,
Yangjiang,
Jiangmen,
Zhongshan
};
SomeCities oneCity;
for (oneCity = zhanjiang; oneCity != Zhongshan; ++oneCity)
{
cout<<oneCity<<endl;
}
以上的++OneCity是沒(méi)有定義的,在Visual C++ 6 編譯下得到如下錯(cuò)誤:
error C2675: unary '++' : 'enum main::SomeCities' does not define this operator or a conversion to a type acceptable to the predefined operator
8、Sizeof
一個(gè)枚舉類型的sizeof就是某個(gè)能夠容納其范圍的整型的sizeof, 而且不會(huì)大于sizeof(int), 除非某個(gè)枚舉子的值不能用int或者unsigned int來(lái)表示。
在32位機(jī)器中,sizeof(int)一般等于4。前面介紹的所有枚舉,例如,
enum SomeCities
{
zhanjiang,
Maoming,
Yangjiang,
Jiangmen,
Zhongshan
};
計(jì)算其sizeof, 可能是1,也可能是是4。在我的intel E2160雙核、32位機(jī)器中,得到4。
-----------------------------------------------------------------------------------
[注1, Begin]
由于通過(guò)將整型數(shù)顯式轉(zhuǎn)換就可能得到對(duì)應(yīng)枚舉類型的值,所以聲明一個(gè)枚舉來(lái)達(dá)到限制傳遞給函數(shù)的參數(shù)取值范圍還是力不從心的,
以下是一個(gè)例子:
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通過(guò)顯式轉(zhuǎn)換,為oneCity賦值
printEnum(oneCity); //在VC++ 6 編譯器下得到50輸出
return 0;
}
以上例子說(shuō)明,雖然SomeCities的定義里沒(méi)有賦值為50的枚舉值,但是,由于50在該枚舉的取值范圍內(nèi),所以通過(guò)顯式聲明得到一個(gè)有定義的枚舉值,從而成功傳遞給printEnum函數(shù)。
相關(guān)文章
C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)txt定位指定行的方法,涉及C#針對(duì)文本文件進(jìn)行光標(biāo)定位的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08C#(.net)中按字節(jié)數(shù)截取字符串最后出現(xiàn)亂碼問(wèn)題的解決
這篇文章主要給大家介紹了關(guān)于C#(.net)中按字節(jié)數(shù)截取字符串最后出現(xiàn)亂碼問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-06-06C#判斷頁(yè)面中的多個(gè)文本框輸入值是否有重復(fù)的實(shí)現(xiàn)方法
這篇文章主要介紹了C#判斷頁(yè)面中的多個(gè)文本框輸入值是否有重復(fù)的實(shí)現(xiàn)方法,是一個(gè)非常簡(jiǎn)單實(shí)用的技巧,需要的朋友可以參考下2014-10-10c#實(shí)現(xiàn)ini文件讀寫(xiě)類分享
c#實(shí)現(xiàn)ini文件讀寫(xiě)類分享,大家參考使用吧2013-12-12C#/VB.NET實(shí)現(xiàn)從PPT中提取圖片的示例代碼
PPT是用于制作幻燈片(演示文稿)的應(yīng)用軟件,每張幻燈片中都可以包含文字、圖形、圖形、表格、聲音和影像等多種信息。本文主要介紹了如何實(shí)現(xiàn)從PPT中提取圖片的功能,需要的可以參考一下2023-03-03