一、自定義型別基本概念
1、結構體
結構體就是將任意多個內建型別變數包含在一起形成的乙個結構,結構特也可以巢狀定義,不能在內部定義自己結構的變數,因為是不完整的型別,但是可以定義指向自己型別的指標,這也是鍊錶的原理,其定義形式如下:
struct a
2、列舉
列舉型別是由一些項組成的型別,具體看**,列舉型別也可以稱為列舉常量,原因是列舉型別的每個項有乙個值,預設從0開始往後排,如果給某乙個項賦了乙個整形值,會改變其後邊所有項的值,還有一點是列舉型別變數在使用過程中是其中的乙個項:
enum week
3、聯合/共用體
聯合也是將任意多個內建型別變數包含在一起形成的乙個結構,但是所有這些變數共用一塊記憶體空間,其定義形式如下:
union a
二、自定義型別所佔空間大小
這個我們倒著來說
1、聯合
因為聯合體成員共用一塊記憶體空間,所以聯合體大小為成員占用記憶體最大空間的大小。
2、列舉
因為列舉型別變數為其所有項的其中乙個,而每乙個項都是乙個整形常量,所以列舉型別大小為乙個整形大小,始終為4個位元組。
3、結構體
結構體計算記憶體大小比較複雜,也比較重要,涉及到乙個概念,即結構體內存對其,對其規則如下:
(1)系統有乙個對齊數,不同的系統預設對齊數不同,vs2013預設對齊數為8,可以用#pramga pack(n)
設定系統對齊數為n。
(2)每乙個成員變數有乙個對齊數,為其型別所佔空間大小,結構體也有乙個對齊數,為成員最大對齊數。
(3) 結合上邊兩點,成員變數和結構體分別有自己的有效對齊數,為自己的對齊數和系統對齊數較小值。
(4)前邊開闢的空間要向下一級有效對齊數對齊,也就是說第乙個變數空間要向第二個對齊,第一二個的總空間要向第三個對齊,依此類推,所有變數開闢的空間要向結構體對齊,對齊的意思是:開闢的空間必須是下一級有效對齊數的整數倍,如果不是,就補夠盡量小的空間以達到上述要求
好,規則到這,實戰一下:
#pragma pack(8)
struct a
printf
("%d\n"
,sizeof
(a))
;
首先,系統對齊數為8,先為a開闢空間為1個位元組,然後要向b對齊,b對齊數為8,所以有效對齊數為8,因此補7個位元組,再開闢b為8個位元組,加在一起總共為16個位元組,c的對齊數為4,所以有效對齊數為4,16是4的整數倍,不用補,為c開闢空間4個位元組,總共為20個位元組,然後,結構體對齊數為成員最大對齊數8,有效對齊數就為8,所以向結構體對齊需要補4個位元組,因此,結構體總大小空間為24個位元組。
三、位段
結構體允許在成員變數後邊以冒號分割新增乙個變數佔位元位的個數,這一功能會使得相連的幾個相同型別的變數可能在乙份空間裡連續存放,比如:
struct a
上述**本來結構體大小為3個位元組,但是有了位段的存在,a和b可以存放在乙個char型空間內,因此結構體大小為兩個位元組,這一功能對現在而言沒什麼太大用處,但是得掌握,在算結構體大小時要注意。
四、例題
1、結構體
結構體計算大小的經典例題為巢狀定義的型別,由於過程太多,總結一下方法:
先算內部結構體大小,計算過程與外部結構體無關,計算完成再計算外部結構體大小,需要注意的點是,在計算外部結構體時,內部結構體作為其成員,有自己的對齊數,是自己內部對齊數最大值,而不是自己所佔空間大小。
2、聯合體
//小端機器
union a
intmain()
由於聯合體成員共用一塊記憶體,所以在做此類題目的時候一定要將記憶體畫出來,題目指明是小端機器,所以test.a
在記憶體中的儲存如下:
test.b
為char型變數,佔乙個記憶體空間,所以執行test.b = 0x55
時0x55
會覆蓋0x44
,最終得到的結果是:
所以最終輸出的結果為0x11223355
.
c語言 自定義型別
struct stu 分號不能丟 匿名結構體型別 struct x struct a 20 p p x 非法的操作,上面倆種完全是不同的宣告 struct node 結構體的自引用 struct node n1 null 直接初始化 struct node n2 null 結構體巢狀初始化 先來看下...
C語言自定義型別
在學習c語言的時候,它有很多的自定義型別,例如 結構體,列舉,聯合。這些型別在我們的日常使用的時候,或多或少的都會遇見到,下面就系統的介紹一下這幾種型別。一.結構體 1.結構體型別的宣告 通俗點來說,結構就是一些值的集合,這些值稱為成員變數,結構體的每個成員可以是不同型別的成員變數。如下所示 str...
C 自定義型別排序
在編寫程式處理資料時經常需要對自己組織的資料進行排序,有時還是不同形式的排序,在c 中可以自定義結構體重載bool operator函式,也可以自己寫int compare 而在c 中自定義排序,就需要對類的icomparer 介面進行實現,排序時呼叫sort 方法時將實現的排序介面作為引數傳入即可...