結構體 位段 列舉 聯合小結

2021-08-16 19:30:44 字數 4524 閱讀 6543

1.

結構體型別建立

struct tag

variable-list;//變數列表

其中,struct是定義結構體的關鍵字,tag是結構體標籤

(1)定義型別的同時,定義變數

struct student

stu;

該例即定義了結構體型別student,同時定義了student結構體型別的結構體變數stu。

(2)定義結構體型別,省略變數列表

struct student

;struct student stu

該例先定義結構體型別student,相當於定義了乙個新型別,在之後使用時定義結構體變數stu。

(3)定義結構體型別,省略結構體標籤tag

struct 

stu;

該例直接定義了結構體變數stu,沒有引入新的型別,在之後想要使用時只能重新定義,平時不建議使用。

(4)定義結構體型別時使用自定義

typedef struct student 

student;

student stu;

該例定義了結構體型別student,同時重定義為student,在之後想要使用該型別時直接使用student定義即可,不用像之前的struct student,較為方便。

2.結構體初始化

//定義的同時初始化

struct student

stu=;

struct student stu = ;

注意:(1)陣列只有在定義時使用{}進行初始化

(2)結構體只允許整體初始化,不允許整體賦值

3.結構體內存對齊

(1)記憶體對齊的原因

1)平台原因(移植原因)

硬體平台不允許在任意位址處獲取任意內容;

2)效能原因

記憶體對齊可以減少訪問次數,保證效能

(2)結構體對齊規則

1)預設第乙個元素是對齊的;

2)其他成員對齊到對齊數的整數倍位址處。對齊數是指編輯器預設對齊數與該成員大小的較小值;

3)結構體總大小為最大對齊數的整數倍;

4)巢狀結構體對齊到自己的最大對齊數的整數倍處。

注意:(1)vs預設對齊數為8,linux預設對齊數為4

(2)第乙個成員也有對齊數

(3)在存放結構體元素時,不一定連續存放,而是保證每個元素在某個自然對齊數上對齊

例1.(vs環境下)

struct s1

;printf("%d\n",sizeof(struct s1));//8

該例中c1佔1位元組,c2佔一位元組,此時2位元組;存放i時,對齊數為4,所以空兩位元組,再存放i,共8位元組。最大對齊數為4,8是4的整數倍,所以結構體s1的大小為8位元組。

例2.(vs環境下)

struct s2

;printf("%d\n",sizeof(struct s2));//24

該例中c1佔1位元組;存放s1時,vs預設對齊數為8,s1本身大小為8,所以對齊數為8,所以空七個位元組,再存放s1,此時共16位元組;存放d時,vs預設對齊數為8,d本身大小為8,所以對齊數為8,此時位址剛好為8的整數倍處,所以直接存放d,共24位元組。該結構體最大對齊數為8,24是8的整數倍,所以結構體s2的大小為8位元組。

例3.(linux環境下)

struct a

;printf("%d\n",sizeof(struct a));//16

struct b

;printf("%d\n",sizeof(struct b));//112

針對結構體a,a佔1位元組;存放b時,linux預設對齊數為4,b本身大小為4,所以對齊數為4,所以空三個位元組,再存放b,此時共8位元組;存放c時,linux預設對齊數為4,c本身大小為8,所以對齊數為4,此時位址剛好為4的整數倍處,所以直接存放c,共16位元組。該結構體最大對齊數為4,16是4的整數倍,所以結構體a的大小為16位元組。

針對結構體b,x佔1位元組;存放結構體型別a的指標變數p時,(結構體指標佔4位元組)對齊數為4,所以空三個位元組,再存放p,此時共8位元組;存放arr陣列時,巢狀結構體對齊自己的最大對齊數的整數倍,即對齊到4的整數倍,此時位址剛好為4的整數倍,所以直接存放arr,此時共88位元組;存放y時,對齊數為4,此時位址剛好為4的整數倍處,所以直接存放y,共96位元組;存放z時,對齊數為4,此時位址剛好為4的整數倍處,所以直接存放z,共100位元組;存放arr1時,對齊數為1,所以直接存放arr1,共103位元組;存放e時,對齊數為4,所以空1位元組,再存放e,共112位元組。該結構體最大對齊數為4,112是4的整數倍,所以結構體b的大小為112位元組。

4.位段

(1)位段的定義

1)位段的成員必須是int、unsigned int、signed int;

2)位段的成員名後面有乙個冒號和乙個數字;

3)位段一般不需要記憶體對齊。

例:

struct a

; printf("%d\n",sizeof(struct a));//8

該例中a就是乙個位段型別,且大小為8位元組。首先_a為int型,故先申請四個位元組。_a使用其中的2個bit位,_b使用其中的5個bit位,_c再使用其中的10個bit位,此時剩下15個bit位,而_d有30個bit位,放不下。故再申請四個位元組,放下_d。所以a位段的大小為8位元組。

(2)位段的記憶體分配

1)位段的空間上是按照4個位元組(int)或是1個位元組(char)的方式來開闢;

2)位段涉及很多不確定因素,位段不跨平台,可移植性差。

(3)位段的跨平台問題

1)int

位段被當成有符號數還是無符號數是不確定的;

2)位段中最大位的數目不能確定;

3)位段中成員在記憶體中從左向右還是從右向左分配未定義;

4)當乙個結構體包含兩個位段,第二個位段成員比較大,無法容納於第乙個位段剩餘位時,剩餘位是捨棄還是利用,這是不確定的。

總結:跟結構體相比,位段可以達到同樣效果,但是可以很好的節省空間,但是有跨平台的位置存在。

5.列舉

(1)列舉的定義

enum color

;

其中,color即為列舉型別,enum為列舉關鍵字,{}中的內容為列舉型別的可能取值,也叫做列舉常量。且列舉常量都是有取值的預設從0開始,依次遞增1。若給列舉常量賦初值,則其後的列舉常量值依舊依次遞增1即可。

(2)列舉的優點

1)增加**的可讀性和可維護性,便於除錯;

2)跟#define定義的識別符號比較,列舉有型別檢查,更為嚴謹;

3)防止了命名汙染;

4)使用方便,一次可定義多個常量。

注意:凡是定義的列舉變數在初始化或賦值時,只能被自身定義的列舉常量賦值。

6.聯合(共用體)

(1)聯合型別的定義

聯合是一種特殊的自定義型別,該型別定義的變數也包含一系列的成員,特徵是這些成員公用同一塊空間。

union un

un;

其中union為聯合關鍵字,定義了un聯合體型別的聯合體變數un,成員包括x,y。

(2)聯合的特點

例1:

union un

un;int main()

因為電腦存在大小端問題,以小端電腦為例,輸出結果為0x11223355。

例2:判斷電腦的大小端

union un

un;int main()

小端:低位存入低位址處,高位存入高位址處;

大端:低位存入高位址處,高位存入低位址處。

因為x為char型,所以輸出結果只能顯示乙個位元組。若該例輸出結果為1,說明電腦為小端,輸出結果為0,說明電腦為大端。

(3)聯合大小的計算

1)聯合的大小至少為最大成員的大小;

2)當最大成員大小不是最大對齊數的整數倍時,就要對齊到最大對齊數的整數倍。

例:

union un1

;union un2

;printf("%d\n", sizeof(union un1));//8

printf("%d\n", sizeof(union un2));//16

對un1來講,聯合最大成員的大小為5,最大對齊數為4,對齊到最大對齊數的整數倍,所以聯合大小為8位元組。

對un2來講,聯合最大成員的大小為7,最大對齊數為4,對齊到最大對齊數的整數倍,所以聯合大小為16位元組。

注意:1

)聯合體的大小通常是指聯合體內最大元素的大小;

2)聯合體的所有成員均可作為聯合體的第乙個元素,甚至在每乙個成員的角度認為聯合體只有自身乙個元素;

3)聯合體以及聯合體內所有成員的位址在數值上是相同的(第乙個位元組的位址)。

結構體,位段,列舉,聯合

結構體是一種可以將不同型別打包在一起的一種使用者自定義型別。描述乙個學生 struct student stu 這裡的定義及使用要遵循以下原則 第乙個 第二次定義變數時 時可採用以下形式進行二次定義 struct student a 第二個 也可用以下形式定義 typedef struct stud...

掌握結構體 位段 列舉 聯合

1.結構體的宣告 struct tag tag是標籤 member list 成員列表 variable 是變數列表 2.結構體可以不完全宣告 也就是可以去掉tag 通過型別建立記憶體空間,例項化 3.結構體成員的訪問 結構體成員可以用符號 來訪問,例如 variable.member 有時我們用結...

自定義型別 結構體 位段 列舉 聯合

include include include 1 結構體 結構是一些值的集合,這些值稱為結構體成員,結構體的每個成員可以是不同型別的變數 struct stu 結構體的自引用 struct node 錯誤的,結構體內不能包含結構體自身 struct node 正確 指標是四個位元組 結構體內存對齊...