結構體列舉與聯合

2021-08-20 01:44:43 字數 3260 閱讀 2798

- 基本介紹

struct是結構體的關鍵字,它將一些相關聯的資料打包成乙個整體,這些相關聯的資料可以是不同的型別。它們被稱為結構體的成員,結構體的成員可以是標量、陣列、指標、或者是其他結構體。

- 結構的宣告

假設我們要建立學生檔案,要納入學生的姓名,年齡和性別三個內容。那麼我們可以通過建立乙個結構體來實現這個過程。

struct student

;

這樣乙個學生資訊的結構體就宣告完成了。其中包含了我們需要的姓名,性別和年齡三個成員。

- 結構體成員的訪問

宣告了結構體之後,接下來就是使用了。我們對於結構體成員的訪問可以通過「.」點操作符或者指標來實現。例如上述學生的結構體,我們現在試著來使用點操作符來訪問成員。

struct student s; //這裡建立了乙個結構體變數

s.age = 10; //通過點操作符給s這個變數裡年齡成員賦值

strcpy(s.name,"jacky"); //同樣通過點操作符給s變數的name成員賦值

上面是通過點操作符來實現對結構體變數實現成員訪問,下面我們來試一試通過指標的方式來訪問結構體的成員。

struct student s;

struct student *p = s; //通過指標指向該結構體變數

p->age = 10; //通過指標加箭頭的方式訪問age成員

strcpy(p->***,"male"); //通過指標訪問***成員

- 結構體的大小計算

提到結構體的大小計算,就必須要理解結構體的記憶體對齊規則:

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

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

3. 結構體總大小為所有成員中最大對齊數的整數倍。

4. 如果巢狀了結構體,那麼巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有成員中(包含巢狀的結構體)最大對齊數的整數倍。

那麼為什麼會有記憶體對齊原則呢,主要是因為(1)不是所有的硬體平台都可以訪問任意位址上的任意資料。(2)處理器如果訪問未對齊的記憶體需要做兩次訪問,如果訪問對齊的記憶體只需要一次訪問。

總的來說就是雖然浪費了一部分空間,但是可以提高處理速度。

接下來我們通過例項來感受結構體大小的計算。

struct c1

;struct c2

;

根據我們上面講的對齊原則,可以算出c1的大小是12個位元組,c2的大小是8個位元組,而他們的成員個數和大小都是一樣的,只是因為位置不一樣,所以由此我們可以看出在宣告結構體的時候,我們可以盡量把佔記憶體比較小的成員集中在一起,這樣就有可能在一定程度上節省記憶體。

位段跟結構體相比,位段可以達到同樣的效果,但是可以更好得節省空間,但是有跨平台的問題存在。位段的宣告和結構體是比較類似的,但是有兩點不同:

1. 位段的成員必須是int,unsigned int,signed int或者char型別。

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

下面舉乙個位段的例子:

struct a

;

a就是乙個位段型別,那麼位段的大小該如何讓計算呢,每個成員冒號後面的數字就是這個成員佔byte的大小,位段是按照需求來進行4個位元組(int)或者1個位元組(char)的開闢,直到能夠放下當前成員。所以按照這個方法來計算的話,struct a占用了8個位元組的大小。

- 位段的跨平台問題

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

2. 位段中的最大位的數目不能被確定。

3. 位段中的成員在記憶體中從左向右還是從優向左分配的標準沒有定義。

4. 當乙個結構包含兩個位段,第二個位段成員較大,無法容納於第乙個位段剩餘的位時,是捨棄還是利用剩餘的位,這是不確定的。

列舉的意思就是把有可能的事件都一一枚舉,例如一周的7天,一年的四季,人的性別等,都可以使用列舉來定義。

接下來我們以星期為例來定義乙個列舉:

enum

day;

這裡的enum就是乙個列舉型別,中的內容是該列舉型別的可能取值,也叫列舉常量。這些列舉常來那個都是有值的,預設從0開始,一次遞增1,在定義時也可以賦初值,舉例如下;

enum

color

- 列舉的優點

1. 增加**的可讀性和可維護性。

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

3. 防止了命名汙染。

4. 便於除錯。

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

聯合也是一種自定義型別,它定義的變數包含一系列的成員,所有的成員共享同一塊空間。所以聯合也叫公用體。

- 聯合的宣告

union n

;

聯合的宣告與結構體類似,都是包括成員和聯合體的名字。聯合體的成員公用一塊空間,所以乙個聯合體的大小至少是最大成員的大小。

當聯合體的大小不是最大對齊數成員對齊數的整數倍時,就要對齊到最大對齊數的整數倍。例如:

union n1

;union n2

printf("%d\n",sizeof(union n1));

printf("%d\n",sizeof(union n2));

輸出結果是 4 和 8 ;

這裡iu可以看出共用體大小的計算方式了。

- 聯合的實際應用

為了加深對聯合的成員共用同一片空間的理解,接下來我們試一試使用聯合來看乙個機器的大小端。

int check()

n1; n1.i = 1;

return n1.c;

}int main()

因為在聯合體中c和i共用同一塊空間,有同一塊起始位址,所以修改了i之後,c也會跟著被改變,因為i是整型占用4個位元組,c占用1個位元組。如果機器是小端儲存,那麼高位存低位址,低位存高位址。當i=1時,c也是1。

結構體,列舉,聯合

結構體 1.結構體的建立 1 在構建結構體之前,必須要對結構體進行宣告。例 struct student 描述乙個學生,student為標籤 此處的分號不能丟,此處也可寫變數 2 成員訪問 2.1在 1 中的 struct student 相當於型別,比如 int型,struct student s...

結構體 聯合 列舉

一般的,在宣告乙個結構提示要使用struct關鍵字,例如 建立乙個學生 struct stu char name 20 名字 int age 年齡 char 5 性別 char id 20 學號 分號不能丟結構體得特殊宣告 沒有結構體名 structx 沒有結構體的標籤,就不能在結構體建立完成之後再...

結構體,列舉,聯合。

今天我們來學習一下結構體,列舉以及聯合等知識。一。首先從結構體開始,結構體與陣列一樣都是聚合型別。1.結構體的宣告 struct tag variable list tag 1 可以省略 2 見名思意 3 盡量不省略。member list 不能為空。variable list 可以省略。例如 描述...