2010年8月20日 星期五

enum 的用途

enum 可以用來定義常數,翻譯作 "列舉"


enum 名稱 {元素a, 元素b, 元素c, 元素d, ...}; // 名稱可省略


如此宣告即可得到元素 a=0、元素 b=1、元素 c=2,以此類推,以前我實在不解這麼做有什麼好處,自己一個一個宣告不行嗎?後來我發現它蠻好用的,所以記一下,

若你有一群相同類型的類別,就可以派上用場了,例如你要利用陣列將全部元件的位置存下來,元件數量又有可能會改變,陣列宣告又只能寫常數,又不想每次去更改 [] 內的數字,這時就可以利用 enum 宣告為常數的特性。


enum {Rect_TitleLabel, Rect_Logo, Rect_SystemBar, Rect_Count};
CRect m_arc[Rect_Count];


之後若要多記下整個 Client 的位置,就在 Rect_Count 前任一位置加上 Rect_Client 即可,宣告陣列的地方就不用理他了。

另一個常用的地方是限制整數變數的範圍,


typedef enum {PAGE_LOGIN, PAGE_SHOPPINT, PAGE_BUYCAR, PAGE_WEBATM} PAGE_TYPE;





enum PAGE_TYPE{PAGE_LOGIN, PAGE_SHOPPINT, PAGE_BUYCAR, PAGE_WEBATM}
// 再如此宣告一個變數
PAGE_TYPE m_pgtClientCurrentPage;


這時 m_pgtClientCurrentPage 就只能被賦值為此列舉中的值,可以安全的控管記下來的頁面資訊不會出現索引外的值,也不可以被 ++ 或 --

比較要注意的是,enum 的列舉值可以被隱轉型成 int 整數,
但 int 卻不能隱轉型為 enum
所以若要將 m_pgtClientCurrentPage 等於某個整數,要醬


int nGoToPage = 3; // 用戶指定到線上 ATM
m_pgtClientCurrentPage = (PAGE_TYPE)nGoToPage;


也因為可以利用轉型指定整數的關係,需注意列舉的合法範圍,


enum PAGE_TYPE{PAGEA, PAGEB, PAGED=5};


這時m_pgtClientCurrentPage = (PAGE_TYPE)(3);也是合法的哦,
所以要用來控制範圍的列舉最好照順序宣告元素。

還有其他可以用來取代#define的地方例如


#define VAL1 7
#define VAL2 8
#define VAL3 99


一樣基於 #define 只會被前置處理器處理,不夠安全,我們改為


enum {VAL1 = 7, VAL2, VAL3 = 100};


另外,宣告同樣數值的元素也是可以的


enum {zero, null = 0, numberA, numberB, numberC};

2 則留言: