C語(yǔ)言自定義類型之聯(lián)合和枚舉解讀
一、聯(lián)合體
1.1 聯(lián)合體類型的聲明
像結(jié)構(gòu)體?樣,聯(lián)合體也是由?個(gè)或者多個(gè)成員構(gòu)成,這些成員可以是不同的類型。
聲明方式如下圖:

那聯(lián)合體和結(jié)構(gòu)體究竟有什么區(qū)別呢??
下面將重點(diǎn)講解聯(lián)合體的特點(diǎn)?。?/strong>
1.2 聯(lián)合體的特點(diǎn)
1.2.1 特點(diǎn)1
所有成員共?同?塊內(nèi)存空間。所以聯(lián)合體也叫:共?體。

我們可以發(fā)現(xiàn),三個(gè)地址打印出來(lái)是一樣的。那既然都共用一塊空間,那大小有多大呢??
1.2.2 特點(diǎn)2
編譯器只為最大的成員分配?夠的內(nèi)存空間(因?yàn)槁?lián)合體至少得有能力保護(hù)最大的那個(gè)成員)

1.2.3 特點(diǎn)3
給聯(lián)合體其中?個(gè)成員賦值,其他成員的值也跟著變化。

這里為什么打印出來(lái)的是11223355呢,我們根據(jù)3個(gè)特點(diǎn),可以分析畫出un的內(nèi)部布局圖

充分說(shuō)明了特點(diǎn)3!
1.3 聯(lián)合體的大小
特點(diǎn)2提到,編譯器只為聯(lián)合體最大的成員分配足夠的空間,那聯(lián)合體的大小就一定等于最大成員變量的大小嗎??
答案是不對(duì)的,我們可以看看下面的代碼

我們可以驗(yàn)證出,雖然編譯器只為最大的成員分配足夠空間,但不代表聯(lián)合體的大小就是最大成員變量的大小?。?!
聯(lián)合體的大小要遵循以下兩個(gè)特點(diǎn):
1、聯(lián)合的大小?少是最?成員的大小。
2、當(dāng)最?成員大小不是最大對(duì)齊數(shù)的整數(shù)倍的時(shí)候,就要對(duì)?到最?對(duì)?數(shù)的整數(shù)倍。
這說(shuō)明,聯(lián)合體雖然可以節(jié)省空間,但也不是一味地節(jié)省,他也是有自己的對(duì)齊規(guī)則的。
分析上圖代碼:
- Un1的第一個(gè)成員數(shù)組雖然是5個(gè)字節(jié)的大小,但是最大對(duì)齊數(shù)只能取char類型,所以是1,而int是4,所以Un1的最大對(duì)齊數(shù)是4,為了保證能放下5個(gè)字節(jié)的空間,所以最大對(duì)齊數(shù)翻倍變成8!
- Un2的第一個(gè)成員數(shù)組雖然是14個(gè)字節(jié)的大小,但最大對(duì)齊數(shù)只能取short類型,所以是2,而int是4,所以Un2的最大對(duì)齊數(shù)是4,為了保證能放下14個(gè)字節(jié)的空間,所以最大對(duì)齊數(shù)翻4倍變成16!
1.4 相同成員的結(jié)構(gòu)體和聯(lián)合體的對(duì)比
我們?cè)賹?duì)??下相同成員的結(jié)構(gòu)體和聯(lián)合體的內(nèi)存布局情況。


這說(shuō)明使用聯(lián)合體是可以節(jié)省空間的?。?!
1.5 使用聯(lián)合體節(jié)省空間的例子
?如,我們要搞?個(gè)活動(dòng),要上線?個(gè)禮品兌換單,禮品兌換單中有三種商品:圖書(shū)、杯?、襯衫。 每?種商品都有:庫(kù)存量、價(jià)格、商品類型和商品類型相關(guān)的其他信息。
其他信息:
圖書(shū):書(shū)名、作者、?數(shù)
杯?:設(shè)計(jì)
襯衫:設(shè)計(jì)、可選顏?、可選尺?
如果直接用結(jié)構(gòu)體的話

但我們會(huì)發(fā)現(xiàn),如果創(chuàng)建book變量,那設(shè)計(jì)、顏色、尺寸屬性就會(huì)浪費(fèi)掉。如果創(chuàng)建cup變量,那書(shū)名、作者、頁(yè)數(shù)、可選顏色、尺寸屬性就會(huì)浪費(fèi)掉。如果創(chuàng)建shirt變量,那書(shū)名、作者、頁(yè)數(shù)屬性就會(huì)浪費(fèi)掉。這樣就會(huì)導(dǎo)致內(nèi)存出現(xiàn)浪費(fèi),因?yàn)閷?duì)于禮單兌換單的商品來(lái)說(shuō),只有部分屬性是通用的,所以我們就可以將公共屬性單獨(dú)寫出來(lái),剩余屬于各種商品自身屬性使用聯(lián)合體聯(lián)合起來(lái)沒(méi)這樣就可以減少所需的內(nèi)存空間,再一定程度上節(jié)省內(nèi)存,使得程序更加高效運(yùn)行。

因?yàn)槲覀兠總€(gè)變量只使用一次,所以可以直接使用匿名結(jié)構(gòu)體。
1.6 運(yùn)用聯(lián)合體判斷大小端

1.7 利用聯(lián)合體打印存儲(chǔ)的字節(jié)內(nèi)容
既然可以判斷大小端,那其實(shí)也可以直接把存儲(chǔ)的情況打印出來(lái)!!這是一個(gè)很神奇的代碼!

二、枚舉類型
2.1 枚舉類型的聲明
枚舉顧名思義就是??列舉。
把可能的取值??列舉。
?如我們現(xiàn)實(shí)?活中:
?周的星期?到星期?是有限的7天,可以??列舉
性別有:男、女、保密,也可以??列舉
?份有12個(gè)?,也可以??列舉
三原?,也是可以意義列舉

{ }中是枚舉類型的可能取值,也叫做枚舉常量。
這些可能取值本身都是由值的,默認(rèn)是從0開(kāi)始依次遞增1,當(dāng)然我們?cè)诼暶鞯臅r(shí)候也可以自己賦初值,但是定義完成之后,就不能在該類型的外部去修改了??!

2.2 枚舉類型的優(yōu)點(diǎn)
1、增加代碼的可讀性和可維護(hù)性
比如我們?cè)趯?shí)現(xiàn)游戲時(shí)常常會(huì)這樣去寫

此時(shí)如果不和菜單建立聯(lián)系

我們并不能一下子就看出來(lái)case1和case0的含義,可讀性較差,可如果在這邊使用枚舉類型,就可以增加代碼的可讀性,并且后期在維護(hù)的時(shí)候也方便。

2、 和#define定義的標(biāo)識(shí)符?較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。
#define定義的標(biāo)識(shí)符是不過(guò)是一個(gè)符號(hào),而枚舉是一種類型,有類型檢查寫代碼會(huì)更加嚴(yán)謹(jǐn)
3、 便于調(diào)試,預(yù)處理階段會(huì)刪除 #define 定義的符號(hào)

枚舉類型在調(diào)試的時(shí)候會(huì)顯示出成員名,但是#define就不會(huì),標(biāo)識(shí)符會(huì)直接替換成數(shù)字,后期如果需要調(diào)試找錯(cuò)誤就不利于發(fā)現(xiàn)問(wèn)題

4.、使??便,?次可以定義多個(gè)常量
5.、枚舉常量是遵循作?域規(guī)則的,枚舉聲明在函數(shù)內(nèi),只能在函數(shù)內(nèi)使?
枚舉有作用域的概念,在一個(gè)函數(shù)內(nèi)部使用,出了函數(shù)就不能用了,但是#define定義的標(biāo)識(shí)符沒(méi)有作用域概念,他是一個(gè)全局都可以使用的常量。
2.3 枚舉類型的使用

使用方法:使?枚舉常量給枚舉變量賦值
那是否可以拿整數(shù)給枚舉變量賦值呢?
在C語(yǔ)?中是可以的,但是在C++是不?的,C++的類型檢查? 較嚴(yán)格。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(173.二叉搜索樹(shù)迭代器)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(173.二叉搜索樹(shù)迭代器),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
C語(yǔ)言編程內(nèi)存分配通訊錄靜態(tài)實(shí)現(xiàn)示例代碼教程
這篇文章主要為大家介紹了C語(yǔ)言編程實(shí)現(xiàn)靜態(tài)的通訊錄示例代碼教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-10-10
C語(yǔ)言實(shí)現(xiàn)abs和fabs絕對(duì)值
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)abs和fabs絕對(duì)值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
C語(yǔ)言利用EasyX實(shí)現(xiàn)繪制足球圖案
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言如何利用EasyX繪圖庫(kù)實(shí)現(xiàn)繪制一個(gè)簡(jiǎn)單的足球圖案,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-11-11
C++實(shí)現(xiàn)LeetCode(148.鏈表排序)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(148.鏈表排序),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語(yǔ)言 ffmpeg與sdl實(shí)現(xiàn)播放視頻同時(shí)同步時(shí)鐘詳解
使用ffmpeg和sdl實(shí)現(xiàn)播放視頻后,需要再實(shí)現(xiàn)時(shí)鐘同步才能正常的播放視頻,尤其是有音頻的情況,我們通常需要將視頻同步到音頻來(lái)確保音畫同步2022-09-09

