結構體struct,列舉enum,聯合union

2021-08-21 19:16:57 字數 3021 閱讀 7347

什麼是結構體?

結構體是一些值的集合,這些值稱為成員變數。結構體的每個成員可以是不同型別的變數,可以是標量、陣列、指標,甚至是其他結構體。

結構體宣告

struct p

;//struct p名字

typedef struct

s; //重新命名 以後直接可以用s定義變數

struct

x;//可以編譯過,但不推薦,表示為建立了乙個叫x的結構體,這個後續不能再建立變數

結構體的自引用

typedef struct node 

node;

//上面**便是乙個結構體的自引用(結構體內部包含乙個自己的指標)

//如果結構體內部的指標指向下個結構體,依次連線,便形成鍊錶

帶頭節點的單鏈表

結構體的訪問

.「訪問

指標訪問結構體內 用」->

細心的可能會發現,上圖中,結構體a的位址和name的位址相同,age的位址比name的位址高,因此我們可以腦補出a結構體在記憶體中各個變數的大概位置。

我相信這時一定有人要問:

name是9個位元組,可&age - &name = 12(0x88 - 0x7c = 12),多餘的兩個位元組是幹什麼的?

這兒,我們就要引入乙個很重要的…結構體內存對齊

結構體內存對齊:

記憶體儲存:大小端

結構體內存對齊規則:

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

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

結構體總大小為最大對齊數的整數倍。

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

為什麼要記憶體對齊?

效能原因:

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

//下面**中,s1和s2中的成員變數型別數量相等,但大小是否相等?

struct s1

a; struct s2

b; printf("s1 = %d\n", sizeof(a));

printf("s2 = %d\n", sizeof(b));

總結:結構體定義成員變數時,盡可能的讓小的集中且在前

「#pragma pack(4) 」 可修改記憶體對齊數

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

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

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

struct a

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

答案: 4

位段的記憶體分配vs下:

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

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

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

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

enum day

;

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

我們可以使用 #define 定義常量,為什麼非要使用列舉?

列舉的優點:

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

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

防止了命名汙染(封裝)

便於除錯

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

聯合是一種特殊的自定義型別

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

聯合的成員是共用同一塊記憶體空間的,這樣乙個聯合變數的大小,至少是最大成員的大小。

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

列舉類 enum,結構體類 struct

1 列舉型別的值,直觀易於理解,見詞知意。格式 enum 列舉類名 值型別 每個值預設 省略 值型別 以int型資料儲存,從0開始。使用格式 列舉類名 變數 列舉類名.值 namespace demo class program console.readkey 2 結構體類,可以達到整體與區域性的效...

列舉資料型別 struct結構體

列舉通常用來表示一組常量 列舉類似於單項選擇題,只能多軒逸 列舉即可以放在類中也可以放在類外 使用關鍵字enum宣告列舉型別 enum week中間用逗號 半形 間隔,最後一位成員可加可不加 為了區分是最後一位成員,一般不加 列舉預設資料型別為int型,如上 mnday 0 sunday 6 定義乙...

列舉與結構enum

使用 enum 來建立列舉。有如類和其他命名型別,列舉可以有方法。enum rank int let ace rank.ace by gashero let acerawvalue ace.toraw 在如上例子中,原始值的型別是 int 所以可以只指定第乙個原始值。其後的原始值都是按照順序賦值的。...