1. 程式人生 > >C語言查缺補漏(九)共用體與列舉型別

C語言查缺補漏(九)共用體與列舉型別

忽略點九:共用體與列舉型別

​ 共用體?What?它是什麼,上了兩年大學的我有點懵逼。共用體已然成了我C語言的盲區。

​ 存在必然有它的意義,所以惡補了一下有關共用體的知識。

​ 在我的理解裡,共用體和上一篇博文所介紹的結構體,都是用來儲存不同資料型別的“容器”。

​ 那麼他們兩個的區別呢?從上上篇查缺補漏系列博文中 跳轉至查缺補漏(七),我們知道結構體不同型別型別成員按照記憶體對齊規則,“排隊”佔用記憶體,而共用體,則是所有型別成員共用同一塊記憶體(也就是說他們的起始位置都是從0開始)。

​ 既然所佔用記憶體都是從0開始,那麼共用體有兩個特徵:

——成員不會同時出現使用

後面出現的成員會覆蓋掉之前成員的內容(也會相互影響),因為兩者的記憶體地址都是從0開始的,例如:

union A {
    int a;
    int b;
};
//省略程式碼
A p1;
p1.a = 1; p1.b = 2;
printf("%d %d\n", p1.a, p1.b);		//結果p1.a,p1.b輸出都為2
p1.a++;
printf("%d %d\n", p1.a, p2.b);		//結果p1.a, p1.b都輸出為3

——收尾:

共用體所佔記憶體的總大小,必須是它內部最大成員所佔記憶體大小的整數倍(像陣列,結構體等成員在計算時按其成員的最大成員所佔記憶體算),不是要補齊

給大家上份程式碼理解一手:

union A {
    int a;		//所佔記憶體地址為0~3
    int b;		//所佔記憶體地址為0~3
    char s[10]; //所佔記憶體為0~9
};				//共用體A總共所佔記憶體地址為0~11

union B {
    double t;	//所佔記憶體地址為0~7
    A a;		//所佔記憶體地址為0~11
    int b[3];	//所佔記憶體記憶體地址0~11
};				//共用體B總共所佔記憶體地址為0~15

在共用體A中:

​ int型別a為4位元組,所以佔用0~3位置

​ int型別a為4位元組,所以佔用0~3位置

​ char型陣列s中最大成員單個char為1位元組,而陣列長度為10,所以佔用0~9位置

​ 在共用體A中,最大成員為int型的4位元組,所用佔用記憶體大小為4的倍數,由於最大佔用空間為10,所以共用體至少佔用記憶體位置為0~11

在共用體B中:

​ double型別t為8位元組,所以佔用0~7位置

​ A型別a中最大成員為int型別為4位元組,A型別總的記憶體佔用為12位元組,所以佔用0~11位置

​ int型陣列b中最大成員單個int為4位元組,而陣列長度為3,所以佔用0~11位置

​ 在共用體B中,最大成員為double型的8位元組,所用佔用記憶體大小為8的倍數,由於最大佔用空間為12,所以共用體至少佔用記憶體位置為0~15

由於共用體特別節省記憶體,所以大家不能學我,它在C語言中是不容忽略的!!!(比如用於儲存IPV4,IPV6地址,可用共用體來儲存)

​ 列舉型別大學期間使用次數僅僅比共用體好上那麼一丟丟,舉個列舉型別的栗子:

enum week {
    Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday			//注意,最後沒有分號!!!!!
};

關於列舉型別只要記住兩點就可以:

——列舉型別只能由整數成員組成,每個成員對應一個整數編號(預設從0開始)

​ 例如上邊程式碼,預設Sunday的值為0,Monday的值為1,一直到Saturday的值為6

——列舉型別的值可相同,未顯性賦值的成員將從它前一個顯性編號的成員以此+1

​ 例如以下程式碼中:

enum week {
    Sunday = 1, Monday, Tuesday, Wednesday = 0, Thursday, Friday, Saturday			//注意,最後沒有分號!!!!!
};

​ 上邊程式碼中,Sunday為1,Monday為2,Tuesday為3,Wednesday為0,Thursday為1,Friday為2, Saturday為3

​ 好啦,共用體和列舉型別查缺補漏完畢!

​ 如果有寫的不對或者不全面的地方 可通過主頁的聯絡方式進行指正,謝謝!