您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么在C語(yǔ)言中自定義類型,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個(gè)成員可以是不同類型的變量。
下面舉一個(gè)例子:
struct tag { menber_list; //成員列表 }variable_list; //變量列表
例如我們使用結(jié)構(gòu)體描述一臺(tái)電腦
struct computer { int price;//價(jià)格 char name[20];//名稱 char brand[10];//品牌 }computer; //需要注意的是最后一行的“ ;”不能丟哦,不然編譯器會(huì)報(bào)錯(cuò)提示你。
結(jié)構(gòu)成員的類型
結(jié)構(gòu)成員可以是標(biāo)量數(shù)組、指針、甚至可以是其他的結(jié)構(gòu)體。
示例:pandas 是基于NumPy 的一種工具,該工具是為了解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的。
匿名結(jié)構(gòu)體類型
//匿名結(jié)構(gòu)體類型 struct { int a; char b; float c; }x; struct { int a; char b; float c; }a[20], *p;
上面的代碼中結(jié)構(gòu)體省略掉了結(jié)構(gòu)體標(biāo)簽,我們?cè)谔砑右恍写a
p=&x;
當(dāng)我們編譯時(shí),會(huì)發(fā)現(xiàn)這樣兩個(gè)錯(cuò)誤。
所以這樣是不可行的。
結(jié)構(gòu)體的自引用
就像函數(shù)遞歸一樣,結(jié)構(gòu)體也可以自己引用自己。他們的格式是這樣的。
struct Node { int data; struct Node* next; };
結(jié)構(gòu)體變量的定義和初始化
struct stu { char name[20]; int age; }; struct stu s = { "Geralt ",100};
利維亞的杰洛特,100歲!
結(jié)構(gòu)體內(nèi)存對(duì)齊
各成員變量存放的起始地址相對(duì)于結(jié)構(gòu)的起始地址的偏移量必須為該變量的類型所占用的字節(jié)數(shù)的倍數(shù) 各成員變量在存放的時(shí)候根據(jù)在結(jié)構(gòu)中出現(xiàn)的順序依次申請(qǐng)空間 同時(shí)按照上面的對(duì)齊方式調(diào)整位置 空缺的字節(jié)自動(dòng)填充 同時(shí)為了確保結(jié)構(gòu)的大小為結(jié)構(gòu)的字節(jié)邊界數(shù)(即該結(jié)構(gòu)中占用最大的空間的類型的字節(jié)數(shù))的倍數(shù),所以在為最后一個(gè)成員變量申請(qǐng)空間后 還會(huì)根據(jù)需要自動(dòng)填充空缺的字節(jié)。
簡(jiǎn)單的說(shuō)就是:結(jié)構(gòu)體的內(nèi)存對(duì)齊是拿空間來(lái)?yè)Q取時(shí)間的結(jié)果,提高了效率,浪費(fèi)少許空間。
規(guī)則如下:
第一個(gè)成員在與結(jié)構(gòu)體變量偏移量為0的地址處。
其他成員變量要對(duì)齊到某個(gè)數(shù)字(對(duì)齊數(shù))的整數(shù)倍的地址處。
對(duì)齊數(shù) = 編譯器默認(rèn)的一個(gè)對(duì)齊數(shù) 與 該成員大小的較小值。
結(jié)構(gòu)體總大小為最大對(duì)齊數(shù)(每個(gè)成員變量都有一個(gè)對(duì)齊數(shù))的整數(shù)倍。
如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對(duì)齊到自己的最大對(duì)齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對(duì)齊數(shù)(含嵌套結(jié)構(gòu)體的對(duì)齊數(shù))的整數(shù)倍。
VS編譯器中默認(rèn)對(duì)齊數(shù)是8。
當(dāng)然了,作為創(chuàng)建VS,Linux的我們是可以在C語(yǔ)言中自定義對(duì)齊數(shù)的。
我們可以使用#pragma這個(gè)預(yù)處理指令修改默認(rèn)對(duì)齊數(shù)。
Eg:#pragma pack(4) //修改對(duì)齊數(shù)為4
結(jié)構(gòu)體傳參
struct s { int data[1000]; int num; }; struct s s = { {1,2,3,4},100 }; //結(jié)構(gòu)體傳參 void print1(struct s s) { printf("%d\n", s.num); } //結(jié)構(gòu)體地址傳參 void print2(struct s* ps) { printf("%d\n", ps->num); } int main() { print1(s); print2(&s); return 0;
和函數(shù)傳參一樣,形參是實(shí)參的一份臨時(shí)拷貝,參數(shù)是需要壓棧,會(huì)有時(shí)間和空間上的系統(tǒng)開(kāi)銷,如果傳遞的過(guò)程中結(jié)構(gòu)體過(guò)大,就可能會(huì)導(dǎo)致系統(tǒng)開(kāi)銷大,導(dǎo)致性能的下降。我們不如直接傳過(guò)去一份地址,再對(duì)它進(jìn)行解引用操作符。
位段與結(jié)構(gòu)體不同的地方在于聲明的時(shí)候,1.位段的成員必須是 int、unsigned int 或signed int 。2.位段的成員名后邊有一個(gè)冒號(hào)和一個(gè)數(shù)字。
舉一個(gè)例子:
struct A { int _a:2; int _b:5; int _c:10; int _d:30; };
位段的成員可以是 int unsigned int signed int 或者是 char (屬于整形家族)類型
位段的空間上是按照需要以4個(gè)字節(jié)( int )或者1個(gè)字節(jié)( char )的方式來(lái)開(kāi)辟的。
位段涉及很多不確定因素,位段是不跨平臺(tái)的,注重可移植的程序應(yīng)該避免使用位段。
舉一個(gè)例子
struct S { char a:3; char b:4; char c:5; char d:4; }; struct S s = {0}; s.a = 10; s.b = 12; s.c = 3; s.d = 4;
那么位段的空間是如何開(kāi)辟的呢?一張圖搞定!
總的來(lái)說(shuō),位段和結(jié)構(gòu)體相似,可以更好的節(jié)省空間,但是位段有跨平臺(tái)的問(wèn)題存在。
枚舉枚舉,顧名思義就是把可能出現(xiàn)的取值一一列舉出來(lái)。
比如我們要描述一年的月份:
可以一一列舉,我們要描述計(jì)算機(jī)語(yǔ)言的類型,也可以一一列舉。
下面舉一個(gè)例子
代碼如下(示例):
enum ComputerLangue { C, Java, Python, };
每種結(jié)構(gòu)體都有一定的優(yōu)點(diǎn),那么枚舉有什么優(yōu)點(diǎn)呢?
增加代碼的可讀性和可維護(hù)性
和#define定義的標(biāo)識(shí)符比較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。
防止了命名污染(封裝)
便于調(diào)試
使用方便,一次可以定義多個(gè)常量
聯(lián)合(公用體)
聯(lián)合的特點(diǎn)是成員們公用同一塊空間,因此他們也可以叫共用體
代碼如下(示例):
//聯(lián)合類型的聲明
union Un { char c; int i; };
//聯(lián)合變量的定義 union Un un; //計(jì)算連個(gè)變量的大小 printf("%d\n", sizeof(un));
在VC2013這款編譯器中,這個(gè)結(jié)構(gòu)體所占的空間大小是多少字節(jié)?
typedef struct{ int a; char b; short c; short d; }AA_t;
答案是:12個(gè)字節(jié)
為什么呢?結(jié)構(gòu)體判斷大小,一般向成員中最長(zhǎng)的元素對(duì)齊。
在這4個(gè)結(jié)構(gòu)成員中,最長(zhǎng)的元素為a占四個(gè)字節(jié)。所以其他元素要向四對(duì)齊。a單獨(dú)占四個(gè)字節(jié),b為char類型占一個(gè)字節(jié),c為short和b一起占四個(gè)字節(jié)并且空出一個(gè)字節(jié)。剩下d占一個(gè)字節(jié),空兩個(gè)字節(jié)。所以總占空間大小是4+1+2+2+3=12字節(jié)。
struct A { int a; short b; int c; char d; }; struct B { int a; short b; char c; int d; };
我們?cè)趤?lái)看一道題 :在32位系統(tǒng)環(huán)境,編譯選項(xiàng)為4字節(jié)對(duì)齊,那么sizeof(A)和sizeof(B)是( )
答案是:16、12
最長(zhǎng)的結(jié)構(gòu)成員為int 占4個(gè)字節(jié),b占兩個(gè)字節(jié),空下兩個(gè)字節(jié),c占4個(gè)字節(jié),d占一個(gè)字節(jié),空3個(gè)字節(jié)。
最長(zhǎng)的類型為int,a占4字節(jié),b和c一起占三個(gè)字節(jié),還空下一個(gè)字節(jié),d占4字節(jié)。
所以sizeof(A)sizeof(B)分別是16 12.
上述內(nèi)容就是怎么在C語(yǔ)言中自定義類型,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。