結構體,列舉,聯合

audience_fzn發表於2018-08-04

一、結構體:

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

2.結構體的宣告:

struct Stu

{

     char name[20];

     int age;

     char sex[5];

};

3.特殊的宣告:不完全宣告

struct

{

      int a;

      char b;

      float c;

}x;

//省略結構體名稱,直接定義結構體變數

struct

{

        int a;

        char b;

        float c;

}*p,arr[20];

//省略了結構體名稱,直接定義結構體指標,結構體陣列

//p = &x ; 是否合法?

警告:編譯器會把上面的倆個宣告當成完全不同的倆個型別,所以這樣的賦值不合法

4.結構體成員的訪問

  • 結構體變數的成員是通過點操作符(.)來訪問的
  • 結果體指標的成員是通過->來訪問的

5.結構體的記憶體對齊

  • 記憶體對其的原則:

1.第一個成員在與結構體便宜了為0的地址處

2.其他成員變數要對其到對其數的整數倍的地址處

對齊數 = min(編譯器預設的對其數,該成員的大小)

vs預設的值:8

Linux預設的值:4

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

最大對齊數:幾個對齊數中最大的

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

  • 為什麼存在記憶體對齊?

1.平臺原因

並不是所有的硬體都能任意的訪問任意地址上的任意資料,編制並不是對所有的記憶體進行編制,所以有些記憶體不能訪問

2.效能原因:

資料結構一個儘可能地在自然邊界上對齊

如果訪問未對齊的的記憶體,處理器需要做倆次記憶體訪問,而對齊的記憶體訪問僅僅需要一次

結構體的記憶體對齊是一種以空間換時間的做法。

#program pack(4)//設定預設對齊數是4

6.sizeof求空結構體大小

Linux:sizeof(struct)//0;

Windows://報錯,1個結構體/聯合中至少有一個變數

所以結構體定義時,不能為空

7.結構體傳參:

陣列名作為形參傳參時會發生降級

但是如果結構體內含有陣列,以結構體變數作為形參傳參時,結構體內陣列不會發生降級,會直接將整個陣列直接拷貝形成一個臨時變數(耗時,耗空間),所以在使用結構體傳參時,要傳結構體的地址

二、位段

位端的宣告與結構體類似,有倆個不同

  • 位段的成員必須是int ,unsigned int 或 signed int或char(char也屬於整形家族)。
  • 位段的成員名後邊有一個冒號和一個數字

 

struct A

{

int _a:2;

int_b:5;

int _c:10;

int _d:30;

};

位段的記憶體分配:

  • 位段的成員都是整形家族
  • 位段的空間是按照需要以4位元組(int)或者1個位元組(char)的方式來開闢的
  • 位段涉及很多不確定因素,位段是不跨平臺的,注重可一直的程式應該避免使用文段

位段跟結構體相比,位段可以達到相同的效果,但是可以很好的節省空間,但是有跨平臺的問題存在

三、列舉

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

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

列舉的優點:

  1. 增加程式碼的可讀性和可維護性
  2. 和#define定義的識別符號比較列舉有型別檢查,更加嚴謹
  3. 防止了命名汙染(封裝)
  4. 便於除錯
  5. 使用方便,一次可以定義多個常量

四、聯合

聯合也是一種特殊的自定義型別,特徵是這些成員共用一塊空間(所以聯合也叫共用體)

union Un

{

        char c;

        int i;

};

printf("%d\n",sizeof(un));//輸出4

 

聯合的特點:

  • 聯合的成員是共用同一塊記憶體空間的,這樣一個聯合變數的大小,至少是最大成原的大小(因為他要有能力儲存最大的那個成員)
  • 對聯合的每個成員取地址,是同一個地址

聯合的大小:

  • 聯合的大小至少是最大成員的大小
  • 當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍

相關文章