wordpress 客戶端源碼分析甘肅搜索引擎網(wǎng)絡優(yōu)化
目錄
- 前言
- 一、聯(lián)合體
- 1.1 聯(lián)合體類型的聲明
- 1.2 聯(lián)合體的特點
- 1.3 相同成員的結(jié)構體和聯(lián)合體對比
- 1.4 聯(lián)合體大小的計算
- 1.5 聯(lián)合體的?個練習
- 總結(jié)
前言
前面我講到C語言中的自定義結(jié)構——結(jié)構體,其實C語言中的自定義結(jié)構不只有結(jié)構體,還有枚舉和聯(lián)合體,我們今天就來學習一下這兩個C語言中的自定義類型的其中一個——聯(lián)合體;話不多說,正文開始:
一、聯(lián)合體
1.1 聯(lián)合體類型的聲明
像結(jié)構體?樣,聯(lián)合體也是由?個或者多個成員構成,這些成員可以不同的類型。
但是編譯器只為最?的成員分配?夠的內(nèi)存空間。聯(lián)合體的特點是所有成員共?同?塊內(nèi)存空間。所以聯(lián)合體也叫:共?體。
給聯(lián)合體其中?個成員賦值,其他成員的值也跟著變化。
這是什么意思呢?
union Un
{char c;int i;
};int main()
{union Un un = { 0 };printf("%zd\n", sizeof(un));return 0;
}
大家可以猜猜這個結(jié)構體是多大字節(jié)的:
為啥是4呢?
1.2 聯(lián)合體的特點
聯(lián)合的成員是共?同?塊內(nèi)存空間的,這樣?個聯(lián)合變量的??,?少是最?成員的??(因為聯(lián)合?少得有能?保存最?的那個成員)。
union Un
{char c;int i;
};int main()
{//聯(lián)合變量的定義union Un un = { 0 };printf("%zd\n", sizeof(un));// 下?輸出的結(jié)果是?樣的嗎?printf("%p\n", &un);printf("%p\n", &(un.i));printf("%p\n", &(un.c));return 0;
}
他們的地址一樣?到這我們就不難理解聯(lián)合體的共用空間是什么意思了:
那也就是說兩個成員不能同時使用,如果同時使用,會互相干擾,我們來驗證一下:
union Un
{char c;int i;
};int main()
{union Un un = { 0 };un.i = 0x11223344;un.c = 0x55;printf("%x ", un.i);return 0;
}
運行結(jié)果:
代碼1輸出的三個地址?模?樣,代碼2的輸出,我們發(fā)現(xiàn)將i的第4個字節(jié)的內(nèi)容修改為55了。我們仔細分析就可以畫出,un的內(nèi)存布局圖。
1.3 相同成員的結(jié)構體和聯(lián)合體對比
我們再對??下相同成員的結(jié)構體和聯(lián)合體的內(nèi)存布局情況。
1.4 聯(lián)合體大小的計算
通過剛剛的例子,我們對聯(lián)合體的大小有了初步的認識,聯(lián)合體的大小是最大成員的大小?
我們來看看下面的例子:
union Un
{char c[5];int i;
};int main()
{union Un un = { 0 };printf("%zd\n", sizeof(un));return 0;
}
這個結(jié)果是否是5,我們來看看結(jié)果:
結(jié)果與我們想的并不一樣,那聯(lián)合體的大小到底如何計算,我們往下看:
? 聯(lián)合的???少是最?成員的??。
? 當最?成員??不是最?對?數(shù)的整數(shù)倍的時候,就要對?到最?對?數(shù)的整數(shù)倍
char [5]的類型是char,所以他的對齊數(shù)就是1,int i的對齊數(shù)就是4,所以聯(lián)合體的大小必須是4的倍數(shù),最小是5,所以結(jié)果為8;
來點練習:
union Un2
{short c[7];int i;
};
int main()
{//下?輸出的結(jié)果是什么?printf("%d\n", sizeof(union Un2));return 0;
}
結(jié)果可以在評論區(qū)打出
使?聯(lián)合體是可以節(jié)省空間的,
舉例:
?如,我們要搞?個活動,要上線?個禮品兌換單,禮品兌換單中有三種商品:圖書、杯?、襯衫。
每?種商品都有:庫存量、價格、商品類型和商品類型相關的其他信息。
圖書:書名、作者、?數(shù)
杯?:設計
襯衫:設計、可選顏?、可選尺?
那我們不耐?思考,直接寫出?下結(jié)構
struct gift_list
{//公共屬性int stock_number;//庫存量double price; //定價int item_type;//商品類型//特殊屬性char title[20];//書名char author[20];//作者int num_pages;//?數(shù)char design[30];//設計int colors;//顏?int sizes;//尺?
};
上述的結(jié)構其實設計的很簡單,?起來也?便,但是結(jié)構的設計中包含了所有禮品的各種屬性,這樣使得結(jié)構體的??就會偏?,?較浪費內(nèi)存。因為對于禮品兌換單中的商品來說,只有部分屬性信息是常?的。?如:
商品是圖書,就不需要design、colors、sizes。
所以我們就可以把公共屬性單獨寫出來,剩余屬于各種商品本?的屬性使?聯(lián)合體起來,這樣就可以介紹所需的內(nèi)存空間,?定程度上節(jié)省了內(nèi)存。
struct gift_list
{int stock_number;//庫存量double price; //定價int item_type;//商品類型union{struct{char title[20];//書名char author[20];//作者int num_pages;//?數(shù)}book;struct{char design[30];//設計}mug;struct{char design[30];//設計int colors;//顏?int sizes;//尺?}shirt;}item;
};
1.5 聯(lián)合體的?個練習
寫?個程序,判斷當前機器是?端?還是?端?
這里我們利用聯(lián)合體共用空間的特點,我們創(chuàng)建一個聯(lián)合體,里面放一個int類型和char類型,我們賦值個int類型1,然后返回char如果是1則是小端,0則是大端;
int check_sys()
{union{int i;char c;}un;un.i = 1;return un.c;//返回1是?端,返回0是?端
}
這個代碼兩個字形容:優(yōu)雅;
我們可以驗證一下:
int check_sys()
{union{int i;char c;}un;un.i = 1;return un.c;//返回1是?端,返回0是?端
}int main()
{if (check_sys() == 1)printf("小端");elseprintf("大端");return 0;
}
結(jié)果是如我們所料,VS是小端存儲;
總結(jié)
到這我們對聯(lián)合體有了基本的了解,再日后通過進一步使用,我們可以掌握聯(lián)合體的使用規(guī)則,到這這期就結(jié)束了,下期我們來講C語言的最后一個自定義類型——枚舉,下期見。