1. 程式人生 > >【C/C++】C和C++11之enum列舉的使用細節

【C/C++】C和C++11之enum列舉的使用細節

作者:李春港 出處:https://www.cnblogs.com/lcgbk/p/14101271.html [toc] # 一、前言 由於C++專案中用了相對比較多的列舉(enum),正常情況下,列舉變數都是佔用一個整形型別的大小,但是專案中列舉(enum)只需要使用到一個位元組的大小,因為是在嵌入式裝置上執行的程式碼,資源比較少,那麼如果列舉都是按照int型大小來使用的話,這無疑是一種資源浪費。 所以就想有沒有一種辦法可以控制列舉(enum)佔用記憶體的辦法。所幸,通過查詢資料,發現C++11的新特性剛好加入了控制列舉大小的機制。那麼接下來我們就來看看,列舉(enum)在C++11標準有哪些變化?以及C和C++11中的列舉(enum)有什麼區別? # 二、C中的列舉(enum) # 2.1 C中列舉的大小 前面有說到,預設情況下,列舉enum的大小是一個整形型別的大小,但是整形型別有很多:int、long int、short int等,所以enum的大小還是不能確定的。在C中enum的大小是不可以通過程式設計師顯式控制的,這個大小是編譯器根據我們給列舉(enum)賦值的大小來選擇合適的整數型別的。 下面舉個例子: ```cpp /***************************************************************************** ** Copyright © 2020 lcg. All rights reserved. ** File name: enum.c ** Description: 測試enum的特性 ** Author: lcg ** Version: 1.0 ** Date: 2020.12.08 *****************************************************************************/ #include enum color1 { RED = 0, GREEN, BLUE }; enum color2 { GRAY = 0x1122334455, YELLOW, PURPLE }; int main(int argc, char *argv[]) { printf("enum color1: %d\n", sizeof(enum color1)); printf("enum color2: %d\n", sizeof(enum color2)); return 0; } ``` 輸出結果: ``` enum color1: 4 enum color2: 8 ``` 我們發現這兩個列舉變數所佔用的大小是不一樣的,enum color2已經超過了4個位元組,所以編譯器會根據實際值的大小來調整列舉變數的大小。 這就存在了一個弊端,當我們定義的一個結構體裡面有列舉變數的時候,當列舉變數值變化的時候,那麼結構體的大小就有可能會跟著變化。在沒有給列舉賦值的時候為結構體申請了堆空間,後面如果給列舉賦了一個超過4個位元組的值,那麼這個時候結構體的實際大小就已經變化了,這樣我們後面程式對該結構體進行操作時就會存在隱患。 ## 2.2 C中列舉的取值範圍 我們繼續使用上面的例程來說明取值範圍: ```cpp /***************************************************************************** ** Copyright © 2020 lcg. All rights reserved. ** File name: enum.c ** Description: 測試enum的特性 ** Author: lcg ** Version: 1.1 ** Date: 2020.12.08 *****************************************************************************/ #include enum color1 { RED = 0, GREEN, BLUE }; enum color2 { GRAY = 1, YELLOW, PURPLE }; int main(int argc, char *argv[]) { enum color1 myClolor1; myClolor1 = RED; printf("myClolor1: %d\n", myClolor1); myClolor1 = GRAY; printf("myClolor1: %d\n", myClolor1); myClolor1 = 10; printf("myClolor1: %d\n", myClolor1); return 0; } ``` 輸出結果: ``` myClolor1: 0 myClolor1: 1 myClolor1: 10 ``` 可以看到,在C下enum定義的變數可以賦規定範圍外的值的,但是在C++11下這是不允許的。在C++11中編譯會不通過,是C++11對C中enum的優化。 # 三、C++11中的列舉(enum) ## 3.1 c++11中新增列舉大小的控制 在C++11中程式設計師就可以對列舉(enum)進行顯式控制其佔用記憶體的大小了,如下示例: ```cpp /***************************************************************************** ** Copyright © 2020 lcg. All rights reserved. ** File name: enum.cpp ** Description: 測試enum的特性 ** Author: lcg ** Version: 1.2 ** Date: 2020.12.08 *****************************************************************************/ #include enum color1 : char { RED = 0, GREEN, BLUE }; enum color2 : int { GRAY = 1, YELLOW, PURPLE }; int main(int argc, char *argv[]) { printf("enum color1: %d\n", sizeof(enum color1)); printf("enum color2: %d\n", sizeof(enum color2)); return 0; } ``` 輸出結果: ``` enum color1: 1 enum color2: 4 ``` C++11這樣的特性就可以很好地解決我在前言所說的那些情況啦,可以節省資源。 ## 3.2 c++11新增有作用域的列舉型別 如上面2.2小節的程式如果在C++11的標準中編譯就會出現以下的報錯: ```cpp 1.cpp:33:15: error: cannot convert ‘color2’ to ‘color1’ in assignment myClolor1 = GRAY; ^ 1.cpp:36:15: error: invalid conversion from ‘int’ to ‘color1’ [-fpermissive] myClolor1 = 10; ``` 在C++11標準中,enum定義的變數是不可以賦規定範圍外的值的。這樣為後期的除錯帶來了很多的便利