結構體struct、聯合體union、枚舉類型enum

1.c語言中的類型

1)內置類型——char,short,int,float,double;html

2)用戶自定義類型(UDT)——struct結構體,union聯合體,enum枚舉類型c++

2.內存對齊

2.1概念

1)內存對齊就是編譯器爲程序中的每一個「數據單元」安排在適當的位置上windows

2)對於內存對齊問題,主要存在於struct和union等複合結構在內存中的分佈狀況網絡

2.2規則

1)對於結構的各個成員,第一個成員位於偏移爲0的位置,之後的每一個數據成員的偏移量 = min ( #pragma pack(n) 指定的n值, 這個數據成員的字節數 ) 的倍數,#pragma pack(n)能夠設置, Windows中默認爲8,Linux中默認爲4;數據結構

2)結構或聯合體自己也要進行對齊,其字節大小=min( #pragram pack(n) ,  長度最長的數據成員 )的倍數性能

struct MyStruct    //MyStruct的內存分佈:*xxx | **** | ** (*表明使用,x表明未使用)
{ char a;    //偏移量爲0
    int b; //偏移量爲4
    short c; //偏移量爲8
}; //windows下MyStruct的字節大小爲:1+4+2=7,變成4的倍數:12

2.3爲何要內存對齊

1)平臺緣由:不是全部的硬件平臺都能訪問任意地址上的任意數據,某些硬件平臺只能在某些地址處取某些特定類型的數據,不然拋出硬件異常url

2)性能提高:通過內存對齊以後,CPU的內存訪問速度大大提高,緣由:spa

  • 內存讀取粒度:cpu把內存當成是一塊一塊的,塊的大小能夠是2,4,8,16 個字節,所以CPU在讀取內存的時候是一塊一塊進行讀取的,塊的大小稱爲(memory granularity)內存讀取粒度
  • 假設CPU要讀取一個4字節大小的數據到寄存器中(假設此CPU內存讀取粒度是4),分兩種狀況討論:
  1.  數據從0字節開始:直接將0~3四個字節徹底讀取到寄存器,完成,這時候沒有任何影響
  2.  數據從1字節開始:首先先將0~3的4個字節讀到寄存器,並再次讀取4~7字節的數據進寄存器,接着把0、五、六、7的數據剔除,最後合併1,2,3,4字節的數據進寄存器,這些額外操做大大下降了CPU的性能

2.union聯合體

2.1概念

1)聯合體union相似於結構體struct(struct概念:不一樣類型數據的集合體).net

2)聯合體用同一段內存單元存放不一樣數據類型的成員,在使用時,一次只能使用其中的一個成員code

3)它的全部成員相對於基地址的偏移量都爲0

4)union的大小取決於它全部的成員中,佔用空間最大的一個成員的大小,而且union的大小要能被其餘成員的大小所整除

union U1 { char s[11]; }; union U2 //s佔11字節,n佔4字節,d佔8字節,因此至少需11字節的空間,但11不能被8整除,因此補充字節到16
{ int n; char s[11]; double d; }; int main() { cout << sizeof(U1) << endl;        //輸出:11
    cout << sizeof(U2) << endl;        //輸出:16

    return 0; }

2.2應用

1)當多個類型的變量要佔用同一片內存時,可使用聯合體:檢測當前機器是採用大端仍是小端

2)當多個事物只取其一時(「n選1」),可使用聯合體:

試題:假設網絡節點A和網絡節點B中的通訊協議涉及 四類報文,報文格式爲「報文類型字段+報文內容的結構體」,四個報文內容的結構體類型分別爲Struct1~ Struct4,請編寫程序以最簡單的方式組織一個統一的報文數據結構。
分析:
報文的格式爲「報文類型+報文內容的結構體」,在真實的通訊中,每次只能發四類報文中的一種,咱們能夠將四類報文的結構體組織爲一個union(共享一段內存,但每次有效的只是一種),而後和報文類型字段統一組織成一個報文數據結構。
//報文內容聯合體
union PacketContent { Struct1 pkt1; Struct2 pkt2; Struct3 pkt1; Struct4 pkt2; }; //統一的報文結構
struct Packet { unsigned char pktType;//報文類型
    PacketContent pktContent;//報文內容
};

4.enum枚舉類型

4.1概念

1)枚舉能夠讓一些數字符號化

2)c語言中枚舉常量是按照int來處理

3)c語言的枚舉變量能夠++,c++的枚舉變量不能夠

4.2定義的格式

enum 枚舉類型名 {枚舉常量0=int常量(可無,默認值爲0),枚舉常量1=int常量(可無,默認值爲1),枚舉常量2,枚舉常量3=int常量(可無,默認值爲3),…};
enum Color { red, blue }; enum Color cfq; cfq = red; ++cfq;    //c語言的枚舉變量能夠++
enum Color { red, orange, blue }; Color hehe; hehe = red; ++hehe;    //錯誤,c++的枚舉變量不能夠++
相關文章
相關標籤/搜索