自定義型別

2021-09-26 20:14:30 字數 3404 閱讀 1992

結構體宣告、定義及初始化

struct stu   //宣告

;int main()

; //定義及初始化

return 0;

}

先說乙個熟悉的 int  a;在這裡,要說明的的是struct stu是這個結構體的型別,相當於int。s1是這個結構體的變數,相當於a。

結構體成員訪問

結構體傳參

struct s

;void print1(struct s s) //傳變數

//void print2(struct s* s) //傳位址

int main()

, 1000 };

print1(s); //傳變數

// print(&s); //傳位址

return 0;

}

選擇哪個?? 

每次呼叫函式就要開闢一塊空間。傳值的的話,每次呼叫都要開闢乙個空間。而且,函式傳參的時候,引數是需要壓棧的。 如果傳遞乙個結構體物件的時候,結構體過大,引數壓棧的的系統開銷比較大,所以會導致效能的下降。

結構體大小(記憶體對齊)

1.記憶體對齊規則:

① 第乙個成員在與結構體變數偏移量為0的位址處。

② 其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處。

③結構體總大小為最大對齊數(每個成員變數都有乙個對齊數)的整數倍。

④ 如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。

ps:對齊數 = 編譯器預設的乙個對齊數 與 該成員大小的較小值。

vs中預設的值為8

linux中的預設值為4

讓占用空間小的成員盡量集中在一起, 既能滿足對齊,又能節省空間。

2.例項

我把s3很拙劣的畫了出來,s4的道理也是一樣,只是要注意巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。

3.為什麼要浪費這麼多空間實現記憶體對齊呢??

① 平台原因(移植原因): 不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址 處取某些特定型別的資料,否則丟擲硬體異常。

② 效能原因: 資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。 原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問。

總體來說: 結構體的記憶體對齊是拿空間來換取時間的做法

4.那麼我們可不可以修改預設對齊數呢?

這是當然的,使用#pragma預處理命令

#include #pragma pack(1)   //設定預設對齊數為1

struct s1

;#pragma pack() //取消設定的預設

int main()

這樣算下來,結構體大小就為6個位元組了。但是不要忘了取消設定的預設哦。。

位斷

1.位斷的宣告和結構體類似,有兩點不同

①位段的成員必須是 int、unsigned int 或signed int 。

②位段的成員名後邊有乙個冒號和乙個數字。

struct a ;
2.記憶體分配

① 位段的成員可以是

int unsigned int signed int

或者是

char

(屬於整形家族)型別

②位段的空間上是按照需要以4

個位元組(

int

)或者1

個位元組(

char

)的方式來開闢的。

③位段涉及很多不確定因素,位段是不跨平台的,注重可移植的程式應該避免使用位段。

3.位斷的跨平台問題

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

②位段中最大位的數目不能確定。(16位機器最大16,32位機器最大32,寫成27,在16位機器會出問題。

③位段中的成員在記憶體中從左向右分配,還是從右向左分配標準尚未定義。

④ 當乙個結構包含兩個位段,第二個位段成員比較大,無法容納於第乙個位段剩餘的位時,是捨棄剩餘的位

還是利用,這是不確定的。

ps:位段在能實現功能的情況下,盡可能節省空間。

1.定義:把可能的取值一一枚舉。

enum day//星期

;int main()

以上定義的 enum day 是列舉型別。 {}中的內容是列舉型別的可能取值,也叫 列舉常量 。這些可能取值都是有值的,預設從0開始,一次遞增1。也可以在定義的時候也可以賦初值。

2.列舉優點:

① 增加**的可讀性和可維護性

② 和#define定義的識別符號比較列舉有型別檢查,更加嚴謹。

③使用方便,一次可以定義多個常量

④防止了命名汙染(封裝),define定義的是全域性變數。

⑤便於除錯  define除錯時該變數會被值替換,列舉除錯時還是它本身。

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

聯合也叫共用體)。 

union un

;int main()

結果並不是最大成員的大小4,而是8。因為因為聯合體存在記憶體對齊,當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍。

2.應用-解決大小端問題

}還有另外一種方法求大小端:

int check_sys()

else }

int main()

else

return 0;

}

完結......

自定義型別

typedef型別 typedef 已有型別 新建型別 示例 typedef double area,volume typedef int number number i1 area a enum enum 列舉型別名 enum week 預設sun 0,可以比較 如果修改必須形如enum week...

自定義型別

下面列舉幾種c語言中常用的自定義資料型別 1.結構體型別 當描述乙個整型變數時,可以用int,描述字元型變數時,可以用char,但要描述乙個學生時,因為這個學生包含的資訊很多,比如姓名,性別,年齡等,不能通過單一的型別來描述,所以,這裡引入結構體型別,將某個事物的共有屬性集合在一起,宣告乙個結構體型...

自定義型別

列舉從字面意思理解就是將可能取的值一一枚舉出來,列舉型別沒有成員 可言,裡邊存放的是可能取值。列舉型別的定義 enum day enum color printf d n red printf d n green printf d n blue 執行結果 day和color都是定義的列舉型別,中的內...