矛盾焦點:
1、結構體的內存對齊方式
字節對齊的目的:
1、提高CPU存儲變量的速度
計算的核心點(默認對齊方式):
1、結構體內的每一個成員的起始地址跟結構體起始地址的偏移量要剛好是自己字節數的整數倍,不足則自動填充。
2、結構體總的字節大小要剛好是結構體的字節邊界數的倍數,不足則自動填充。(字節邊界數:結構體中占用最大空間的類型的字節數)
3、static修飾的結構體成員不占用結構體字節數,因為靜態變量的存儲地址跟結構體的實例地址無關。
4、空結構體的字節數為1,因為必須保證結構體的實例地址唯一。
計算的核心點(#pragma pack設置字節對齊大小):
#pragma pack(push)
#pragma pack(n)
...
#pragma pack(pop)
一、結構體每個成員的地址偏移量
1、如果n大於等於當前成員的字節數,則當前成員的地址偏移量要剛好是自己字節數的整數倍,不足則自動填充。
2、如果n小於當前成員的字節數,則當前成員的地址偏移量要剛好是n的整數倍,不足則自動填充。
二、結構體總的字節數
1、如果n大於等於結構體中占用最大空間的類型的字節數,則結構體總字節數大小要剛好是結構體中占用最大空間的類型的字節數的整數倍。
2、如果n小於結構體中最大空間的類型的字節數,則結構體總字節數的大小要剛好是n的整數倍。
計算的核心(補充):
1、static修飾的結構體成員不占用結構體字節數,因為靜態變量的存儲地址跟結構體的實例地址無關。
2、空結構體的字節數為1,因為必須保證結構體的實例地址唯一。
//try 一 try struct F { char a; short b; double c; float d; char e; }; int FCount = sizeof(F); cout << "F count = " << FCount << endl; //F count = 24 #pragma back(push) #pragma pack(2) struct E { char a; short b; double c; float d; char e; }; #pragma back(pop) int ECount = sizeof(E); cout << "E count = " << ECount << endl; //E count = 18
//n大於等於結構體所占最大空間的類型的字節數的情況,按照默認對齊方式處理
上述代碼有一個疑問點:https://www.cnblogs.com/azbane/p/11299354.html
//try 一 try struct FF { char a; short b; double c; float d; char e; static double h; }; int FFCount = sizeof(FF); cout << "FF count = " << FFCount << endl; //FF count = 24 struct G { }; int GCount = sizeof(G); cout << "G count = " << GCount << endl; //G count = 1
追加:類類型占據字節數跟結構體的計算方法一致。