c語言 自定義型別

2021-08-31 16:25:06 字數 2781 閱讀 6311

struct stu//

;//分號不能丟

//匿名結構體型別

struct

x;struct

a[20],

*p;p =

&x//非法的操作,上面倆種完全是不同的宣告

struct node//結構體的自引用

;

struct node

n1 =

,null};

//直接初始化

struct node n2 =

,null};

//結構體巢狀初始化

先來看下面的這個結構體大小應該為多少

struct s1

;printf

("%d\n"

,sizeof

(struct s1)

)//輸出的結果應該為12

再來看另外乙個**

struct s1

;struct s2

;printf

("%d\n"

,sizeof

(struct s2)

)//輸出20

在linux作業系統下(最大對齊數為4)

#pragma pack(4)

//修改預設對齊數

struct s1//結構體大小為12

;

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

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

對齊數 = 編譯器預設的乙個對齊數 與 該成員大小的較小值。 vs中預設的值為8 linux中的預設值為4

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

如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是

所有最大對齊數(含巢狀結構體的對齊數)的整數倍。

s1:char占用乙個位元組偏移量為0,int需要是4的倍數所以偏移到4的位置,char又占用後乙個位元組的空間所以他們一共占用了9個位元組的空間,但是結構體大小需要是最大元素對齊數的倍數所以9之後是4的倍數的值為12.

s2同理,只不過巢狀的那個結構體要在對齊數 與 該成員大小的較小值選乙個所以是8(vs下),所以這也是為什麼他從第8個位置開始占用空間,最後要選擇倆個結構體中最大元素並且對齊值是他的倍數,而最大對齊數是int所以結果是20.

怎麼知道某個型別的偏移量

#define offsetof(s,m) (size_t)&(((s *)0)->m)

//可以列印某個元素的偏移量

1.(s*)將0位址強制 「轉換」 為 s結構型別的指標;

2.((s*)0)->m訪問結構體中m中的成員

3.&((s*)0)->m取出結構中m成員的位址

4.size_t轉換為整形資料輸出。

1.平台原因(移植原因): 不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址

處取某些特定型別的資料,否則丟擲硬體異常。

2 效能原因: 資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。 原因在於,為了訪問未對齊的記憶體,處理

器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問。

總結:以空間換時間。

類似於下面寫法的結構體就叫位段(c和指標中有具體講解)

練習:

struct s1//輸出3

;

位段的跨平台問題

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

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

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

列舉顧名思義就是一一枚舉。

把可能的取值一一枚舉。 比如我們現實生活中:

一周的星期一到星期日是有限的7天,可以一一枚舉。 性別有:男、女、保密,也可以一一枚舉。 月份有12

個月,也可以一一枚舉 顏色也可以一一枚舉。

這裡就可以使用列舉了。

enum day//星期

;enum ***//性別

列舉的優點

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

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

防止了命名汙染(封裝)

便於除錯

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

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

聯合大小的計算:

1.聯合的大小至少是最大成員的大小。

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

#include

union un1

;union un2

;int

main()

C語言自定義型別

在學習c語言的時候,它有很多的自定義型別,例如 結構體,列舉,聯合。這些型別在我們的日常使用的時候,或多或少的都會遇見到,下面就系統的介紹一下這幾種型別。一.結構體 1.結構體型別的宣告 通俗點來說,結構就是一些值的集合,這些值稱為成員變數,結構體的每個成員可以是不同型別的成員變數。如下所示 str...

C語言之自定義型別

結構體型別的建立struct tag stu struct class struct class1 int main 這裡編譯器會把上邊兩個宣告當作不同的型別,而且如果我們在想建立乙個相同成員的結構體class2,就必須的在main 函式前邊建立,這樣及其不方便。struct tag class i...

C語言 自定義型別詳解

目錄 直接上 struct point p1 建立結構體時順便建立變數,分號一定不能掉 struct point p2 單獨建立變數 struct point p3 建立變數時順便賦值 struct node n1 int main struct是建立結構體的關鍵字,point是結構體的名字,p1為...