C語言枚舉與聯(lián)合體深入詳解
前言
在C語言中,有三個自定義類型——結(jié)構(gòu)體,枚舉,聯(lián)合,自定義類型出現(xiàn)是為了解決內(nèi)置類型無法解決的問題。例如人這個對象,如果要描述人這樣一個復(fù)雜對象,就不只是一個簡簡單單的int、char、double類型的數(shù)據(jù)能描述的,這時候就需要我們使用自定義類型來描述。
(PS:內(nèi)置類型是指任何語言在設(shè)計(jì)初期定義的類型,如c語言中的int, double, char… 它也是在一種語言中最基本的類型,與編譯器編譯出的代碼具有重大關(guān)系,值得一提的是,不同語言也擁有不同的內(nèi)置類型,但是所有內(nèi)置類型的定義都與計(jì)算機(jī)的運(yùn)算方式相關(guān)。)
對于結(jié)構(gòu)體來說,我們應(yīng)該都不陌生,結(jié)構(gòu)體很重要,內(nèi)容也很多,我之前寫過一篇關(guān)于結(jié)構(gòu)體的文章,不過那篇文章寫的都是結(jié)構(gòu)體的一些基礎(chǔ)內(nèi)容,過兩天會寫一篇進(jìn)階的,所以現(xiàn)在在就先不講結(jié)構(gòu)體了,我們先認(rèn)識一下另外兩個自定義類型。
枚舉
枚舉的定義
枚舉類型的定義要使用enum關(guān)鍵字,舉個例子,如果我要用枚舉常量才定義一下三原色,也就是紅藍(lán)綠(RGB)。請看下面這段代碼:
enum Color { //枚舉常量 RED, GREEN, BLUE };
Color就被定義成了枚舉類型,{}中的內(nèi)容是枚舉類型的可能取值,也就是枚舉常量。(補(bǔ)充:對于#define和嗎枚舉定義的常量 一般把變量名寫成大寫)。
枚舉的使用
如果要用枚舉類型創(chuàng)建變量就要使用enum Color,enum Color就代表著枚舉類型,而創(chuàng)建好的變量的值就只能是{}中的內(nèi)容。如下:
enum Color a = RED; enum Color b = GREEN; enum Color c = BLUE;
枚舉常量是不能改變的。但是這些枚舉常量都是有值的,默認(rèn)從0開始,一次遞增1,當(dāng)然在定義的時候也可以賦初值。給大家解釋一下,看下面這段代碼:
printf("%d\n", RED); printf("%d\n", GREEN); printf("%d\n", BLUE);
我想看到這大家應(yīng)該明白這是什么意思了,枚舉常量是有值的,數(shù)值從0開始依次加1。如果要改變初始的值,只需要給第一個枚舉常量賦值就行。例如:
enum Color { //枚舉常量 RED = 2, GREEN, BLUE };
像這樣,再去打印RED,GREEN和BLUE,值就是2,3,4。
枚舉的優(yōu)點(diǎn)
對于枚舉,我們可以使用 #define 定義常量,為什么非要使用枚舉?
枚舉的優(yōu)點(diǎn):
- 增加代碼的可讀性和可維護(hù)性
- 和#define定義的標(biāo)識符比較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。
- 防止了命名污染(封裝)
- 便于調(diào)試
- 使用方便,一次可以定義多個常量
聯(lián)合(共用體)
在進(jìn)行某些算法的C語言編程的時候,需要使幾種不同類型的變量存放到同一段內(nèi)存單元中。也就是使用覆蓋技術(shù),幾個變量互相覆蓋。這種幾個不同的變量共同占用一段內(nèi)存的結(jié)構(gòu),在C語言中,被稱作“共用體”類型結(jié)構(gòu),簡稱共用體,也叫聯(lián)合體。
聯(lián)合體的定義
聯(lián)合體的定義與結(jié)構(gòu)體比較相似,要先聲明聯(lián)合體,要使用union這個關(guān)鍵字,聲明方式如下:
union MyUnion { int a; char b; };
聯(lián)合體的定義如下:
//union 類型名 變量名 union MyUnion un;
這樣就創(chuàng)建好了un這個聯(lián)合體類型。
聯(lián)合體的特點(diǎn)
先看這段代碼以及運(yùn)行結(jié)果:
union MyUnion { int a;//4 char b;//1 }; int main() { union MyUnion un; printf("%d\n", sizeof(un)); printf("%u\n", &(un)); printf("%u\n", &(un.a)); printf("%u\n", &(un.b)); return 0; }
我們可以看到un的大小是4不是5,而且un,un.a和un.b的地址是一樣的。為什么?
下面我給大家一一解釋:
我們在創(chuàng)建變量時,編譯器就會給我們開辟一些空間,因此我創(chuàng)建un變量時,編譯器就已經(jīng)給我開辟空間了,那么我在打印un地址時,打印的就是un的首地址。在64位環(huán)境下,int是4個字節(jié),char是一個字節(jié),它們的地址和un是一樣的,說明int是從un的首地址開始向后占用4個字節(jié)的空間,char也是從un的首地址開始的。因此打印出來的un.a和un.b的地址是相同的。它們公用同一部分的內(nèi)存空間,這就是聯(lián)合體。
聯(lián)合體大小的計(jì)算
1.聯(lián)合的大小至少是最大成員的大小。
2.當(dāng)最大成員大小不是最大對齊數(shù)的整數(shù)倍的時候,就要對齊到最大對齊數(shù)的整數(shù)倍。
對于第一條,上面的例子證明過了,接下來重點(diǎn)來看第二條??匆幌孪旅孢@段代碼:
union un { char c[5]; int i; }; int main() { printf("%d\n", sizeof(union un)); return 0; }
對于這段代碼,最后輸出的結(jié)果是什么?5?
答案是8.
為什么?
對于un里面有一個長度為5的字符數(shù)組c和一個整型i。我們可以把它看成5個字符變量和一個整型變量。那么在計(jì)算聯(lián)合體大小的時候,對齊數(shù)就是int類型,也就是4個字節(jié),而不是5個字節(jié)。
因此我們計(jì)算聯(lián)合體大小,考慮以多少字節(jié)為對齊數(shù)時,就只需要看數(shù)據(jù)類型就可以了,然后再看多少最大對齊數(shù)的整數(shù)倍能放下最大的變量就可以了。
總結(jié)
自定義類型中枚舉和聯(lián)合體的難度不是很大,也就聯(lián)合體大小的計(jì)算有點(diǎn)難度。大家只要記住計(jì)算聯(lián)合體大小的兩個特點(diǎn)就可以了。(感謝您的觀看,如有錯誤,歡迎指正!感謝!)
到此這篇關(guān)于C語言枚舉與聯(lián)合體深入詳解的文章就介紹到這了,更多相關(guān)C語言枚舉與聯(lián)合體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語言編程中的聯(lián)合體union入門學(xué)習(xí)教程
- C語言中聯(lián)合體union的實(shí)例詳解
- C語言中枚舉與聯(lián)合體的使用方法(enum union)
- C語言結(jié)構(gòu)體,枚舉,聯(lián)合體詳解
- C語言關(guān)于自定義數(shù)據(jù)類型之枚舉和聯(lián)合體詳解
- C語言超詳細(xì)講解結(jié)構(gòu)體與聯(lián)合體的使用
- C語言中聯(lián)合體與共用體和枚舉使用語法示例
- c語言中聯(lián)合體和枚舉用法詳解
- C語言聯(lián)合體類型的實(shí)現(xiàn)
- 一文帶你認(rèn)識C語言的聯(lián)合體和枚舉
- C語言聯(lián)合體的實(shí)現(xiàn)示例
相關(guān)文章
VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法(注冊表修改)
這篇文章主要介紹了VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法,涉及VC++針對注冊表的相關(guān)操作技巧,需要的朋友可以參考下2016-08-08C++ 中 const和static readonly區(qū)別
這篇文章主要介紹了C++ 中 const和static readonly區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-05-05Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)數(shù)據(jù)分組導(dǎo)出
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)數(shù)據(jù)庫數(shù)據(jù)分組導(dǎo)出,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定參考價值,需要的可以了解一下2022-06-06C語言中斐波那契數(shù)列的三種實(shí)現(xiàn)方式(遞歸、循環(huán)、矩陣)
本文主要介紹了C語言中斐波那契數(shù)列的三種實(shí)現(xiàn)方式(遞歸、循環(huán)、矩陣),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01