C語言自定義類型之聯(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)!!
1.2 聯(lián)合體的特點(diǎn)
1.2.1 特點(diǎn)1
所有成員共?同?塊內(nèi)存空間。所以聯(lián)合體也叫:共?體。
我們可以發(fā)現(xiàn),三個(gè)地址打印出來是一樣的。那既然都共用一塊空間,那大小有多大呢??
1.2.2 特點(diǎn)2
編譯器只為最大的成員分配?夠的內(nèi)存空間(因?yàn)槁?lián)合體至少得有能力保護(hù)最大的那個(gè)成員)
1.2.3 特點(diǎn)3
給聯(lián)合體其中?個(gè)成員賦值,其他成員的值也跟著變化。
這里為什么打印出來的是11223355呢,我們根據(jù)3個(gè)特點(diǎn),可以分析畫出un的內(nèi)部布局圖
充分說明了特點(diǎn)3!
1.3 聯(lián)合體的大小
特點(diǎn)2提到,編譯器只為聯(lián)合體最大的成員分配足夠的空間,那聯(lián)合體的大小就一定等于最大成員變量的大小嗎??
答案是不對的,我們可以看看下面的代碼
我們可以驗(yàn)證出,雖然編譯器只為最大的成員分配足夠空間,但不代表聯(lián)合體的大小就是最大成員變量的大?。。?!
聯(lián)合體的大小要遵循以下兩個(gè)特點(diǎn):
1、聯(lián)合的大小?少是最?成員的大小。
2、當(dāng)最?成員大小不是最大對齊數(shù)的整數(shù)倍的時(shí)候,就要對?到最?對?數(shù)的整數(shù)倍。
這說明,聯(lián)合體雖然可以節(jié)省空間,但也不是一味地節(jié)省,他也是有自己的對齊規(guī)則的。
分析上圖代碼:
- Un1的第一個(gè)成員數(shù)組雖然是5個(gè)字節(jié)的大小,但是最大對齊數(shù)只能取char類型,所以是1,而int是4,所以Un1的最大對齊數(shù)是4,為了保證能放下5個(gè)字節(jié)的空間,所以最大對齊數(shù)翻倍變成8!
- Un2的第一個(gè)成員數(shù)組雖然是14個(gè)字節(jié)的大小,但最大對齊數(shù)只能取short類型,所以是2,而int是4,所以Un2的最大對齊數(shù)是4,為了保證能放下14個(gè)字節(jié)的空間,所以最大對齊數(shù)翻4倍變成16!
1.4 相同成員的結(jié)構(gòu)體和聯(lián)合體的對比
我們再對??下相同成員的結(jié)構(gòu)體和聯(lián)合體的內(nèi)存布局情況。
這說明使用聯(lián)合體是可以節(jié)省空間的?。?!
1.5 使用聯(lián)合體節(jié)省空間的例子
?如,我們要搞?個(gè)活動(dòng),要上線?個(gè)禮品兌換單,禮品兌換單中有三種商品:圖書、杯?、襯衫。 每?種商品都有:庫存量、價(jià)格、商品類型和商品類型相關(guān)的其他信息。
其他信息:
圖書:書名、作者、?數(shù)
杯?:設(shè)計(jì)
襯衫:設(shè)計(jì)、可選顏?、可選尺?
如果直接用結(jié)構(gòu)體的話
但我們會(huì)發(fā)現(xiàn),如果創(chuàng)建book變量,那設(shè)計(jì)、顏色、尺寸屬性就會(huì)浪費(fèi)掉。如果創(chuàng)建cup變量,那書名、作者、頁數(shù)、可選顏色、尺寸屬性就會(huì)浪費(fèi)掉。如果創(chuàng)建shirt變量,那書名、作者、頁數(shù)屬性就會(huì)浪費(fèi)掉。這樣就會(huì)導(dǎo)致內(nèi)存出現(xiàn)浪費(fèi),因?yàn)閷τ诙Y單兌換單的商品來說,只有部分屬性是通用的,所以我們就可以將公共屬性單獨(dú)寫出來,剩余屬于各種商品自身屬性使用聯(lián)合體聯(lián)合起來沒這樣就可以減少所需的內(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ǔ)的情況打印出來??!這是一個(gè)很神奇的代碼!
二、枚舉類型
2.1 枚舉類型的聲明
枚舉顧名思義就是??列舉。
把可能的取值??列舉。
?如我們現(xiàn)實(shí)?活中:
?周的星期?到星期?是有限的7天,可以??列舉
性別有:男、女、保密,也可以??列舉
?份有12個(gè)?,也可以??列舉
三原?,也是可以意義列舉
{ }中是枚舉類型的可能取值,也叫做枚舉常量。
這些可能取值本身都是由值的,默認(rèn)是從0開始依次遞增1,當(dāng)然我們在聲明的時(shí)候也可以自己賦初值,但是定義完成之后,就不能在該類型的外部去修改了!!
2.2 枚舉類型的優(yōu)點(diǎn)
1、增加代碼的可讀性和可維護(hù)性
比如我們在實(shí)現(xiàn)游戲時(shí)常常會(huì)這樣去寫
此時(shí)如果不和菜單建立聯(lián)系
我們并不能一下子就看出來case1和case0的含義,可讀性較差,可如果在這邊使用枚舉類型,就可以增加代碼的可讀性,并且后期在維護(hù)的時(shí)候也方便。
2、 和#define定義的標(biāo)識(shí)符?較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。
#define定義的標(biāo)識(shí)符是不過是一個(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)問題
4.、使??便,?次可以定義多個(gè)常量
5.、枚舉常量是遵循作?域規(guī)則的,枚舉聲明在函數(shù)內(nèi),只能在函數(shù)內(nèi)使?
枚舉有作用域的概念,在一個(gè)函數(shù)內(nèi)部使用,出了函數(shù)就不能用了,但是#define定義的標(biāo)識(shí)符沒有作用域概念,他是一個(gè)全局都可以使用的常量。
2.3 枚舉類型的使用
使用方法:使?枚舉常量給枚舉變量賦值
那是否可以拿整數(shù)給枚舉變量賦值呢?
在C語?中是可以的,但是在C++是不?的,C++的類型檢查? 較嚴(yán)格。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(173.二叉搜索樹迭代器)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(173.二叉搜索樹迭代器),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08C語言編程內(nèi)存分配通訊錄靜態(tài)實(shí)現(xiàn)示例代碼教程
這篇文章主要為大家介紹了C語言編程實(shí)現(xiàn)靜態(tài)的通訊錄示例代碼教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-10-10C++實(shí)現(xiàn)LeetCode(148.鏈表排序)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(148.鏈表排序),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語言 ffmpeg與sdl實(shí)現(xiàn)播放視頻同時(shí)同步時(shí)鐘詳解
使用ffmpeg和sdl實(shí)現(xiàn)播放視頻后,需要再實(shí)現(xiàn)時(shí)鐘同步才能正常的播放視頻,尤其是有音頻的情況,我們通常需要將視頻同步到音頻來確保音畫同步2022-09-09