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

2021-10-10 21:21:41 字數 4554 閱讀 7513

結構體

結構體型別的宣告

結構的自引用

結構體變數的定義和初始化

結構體內存對齊

結構體傳參

結構體實現位段(位段的填充&可移植性)

列舉

列舉型別的定義

列舉的優點

列舉的使用

聯合

聯合型別的定義

聯合的特點

聯合大小的計算

結構體的宣告

```c

struct tag

variable-list;

例如宣告乙個學生:

struct stu

char name[20]

;//名字

int age;

//年齡

char ***[5]

;//性別

char id[20]

;//學號

};//分號不能丟

結構的自引用

struct node

;

結構體變數的定義和初始化

struct point

p1;//宣告型別的同時定義變數p1

struct point p2;

//定義結構體變數p2

struct point p3 = ix,y}

;struct stu

//型別宣告

;struct stu s = i"zhangsan",20

};//初始化

struct node

n1 =

,null};

/結構體巢狀初始化

struct node n2 =

,null};

//結構體巢狀初始化

結構體內存對齊

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

其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處。 對齊數 = 編譯器預設的乙個對齊數 與 該成員大小的較小值。 vs中預設的值為8

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

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

//練習1

//vs預設對齊數為8

struct s1

;printf

("%d\n"

,sizeof

(struct s1));

//共佔12個位元組

//練習2

struct s2

;printf

("%d\n"

,sizeof

(struct s2));

//共佔8個位元組

為什麼存在記憶體對齊?

大部分的參考資料都是如是說的:

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

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

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

修改預設對齊數

#pragma pack(8)

//設定預設對齊數為8

結構體傳參

struct s

;struct s s =

,1000};

//結構體傳參

void

print1

(struct s s)

//結構體位址傳參

void

print2

(struct s* ps)

intmain()

位段的宣告和結構是類似的,有兩個不同:

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

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

struct a

;//這就是乙個位段型別

這是位段a的大小:

位段的記憶體分配

位段的成員可以是 int unsigned int signed int 或者是 char (屬於整形家族)型別

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

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

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

把可能的取值一一枚舉。 比如我們現實生活中: 一周的星期一到星期日是有限的7天,可以一一枚舉。

性別有:男、女、保密,也可以一一枚舉。 月份有12個月,也可以一一枚舉

列舉型別的定義

enum day//星期

;enum ***//性別

;enum color//顏色

;

以上定義的 enum day , enum *** , enum color 都是列舉型別。 {}中的內容是列舉型別的可能取 值,也叫

列舉常量 。

這些可能取值都是有值的,預設從0開始,一次遞增1,當然在定義的時候也可以賦初值

列舉的優點

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

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

防止了命名汙染(封裝)

便於除錯

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

列舉的使用

enum color

;enum color clr = green;

//只能拿列舉常量給列舉變數賦值,才不會出現型別的差異。

聯合型別的定義//聯合型別的宣告

union un

;//聯合變數的定義

union un un;

//計算連個變數的大小

printf

("%d\n"

,sizeof

(un)

);

聯合的特點

聯合的成員是共用同一塊記憶體空間的,這樣乙個聯合變數的大小,至少是最大成員的大小(因為 聯合至少得有能力儲存最大的那個成員)。

union un

;union un un ;

un.i = ox11223344;

printf

("%d\n",&

(un.i));

//11223344

printf

("%d\n",&

(un.c));

//44

un.i = ox11223344;un.c =

0x55

;printf

("%x \n", un.i)

;//11223355

printf

("%d\n",&

(un.c));

//55

聯合大小的計算

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

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

union un1

;//聯合共用記憶體 最大成員是5 5不是4的倍數 故為8

union un2

;printf

("%d\n"

,sizeof

(union un1));

//8printf

("%d\n"

,sizeof

(union un2));

//16

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

結構體 所謂結構體,就是將一大堆值放在一起,建立乙個新的型別,這些成員可以是不同型別的變數。struct tag variable list tag 要求 1.見名知意 2.可以省略 3.不建議省略 member list c語言中,不能為空 variable list 變數列表,可以省略,建議省略...

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

首先先說一下c語言的資料型別,其框架型別如圖所示 今天主要說一下結構體,列舉,聯合這三種自定義型別。1,結構體 1.1 結構體的宣告 結構體是一些值的集合,這些值稱為成員變數,結構體的每個成員可以是不同型別得變數。1 結構體的成員 結構體的成員可以是標量,陣列,指標,甚至是其他結構體。2 結構體的宣...

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

結構體的宣告 struct tag variable list 例如描述乙個學生 struct stu 分號不能丟特殊的宣告 在宣告結構的時候,可以不完全的宣告。比如 匿名結構體型別 struct x struct a 20 p 警告 編譯器會把上面的兩個宣告當成完全不同的兩個型別。所以是非法的。結...