結構體(對齊規則及舉例)


概念

  1. 一種數據結構;
  2. C語言中聚合數據類型的一類;
  3. 可以被聲明為變量、數組、指針等,用以實現比較復雜的數據結構;
  4. 是一系列元素的集合,這些元素被稱為結構體成員;
  5. 結構體成員需要用結構體名訪問。

結構體聲明

struct A{  //struct是關鍵字, A是結構體標志
    int a; //a,b是結構體成員列表
    char b;
}s1;       //s1是結構體變量

注意事項:

  • 一般情況下,聲明出現三個部分的兩個部分即可(標志或者變量可省略)
  • 結構體可以包含其他結構體,也可以包含指向自己的指針
  • 結構體互相包含時,需要對其中一個進行不完整聲明

結構體對齊規則

  • 計算結構體大小不是元素單純相加;
  • 32位CPU取四個字節比一個字節更高效方便;
  • 若每個元素首地址都是4的整數倍,取數據元素就能更高效方便;
  • 每個特定平台上編譯器都有自己的默認的對齊系數(對齊模數),可通過編譯命令來改變這一系數;
  • #pragma pack(n);//n=1,2,4,8,16,其中n就是你想要指定的系數。
  • 一般情況下32位默認4字節對齊。

對齊原因

  1. 平台原因(移植原因)
    不是所有的硬件平台都能訪問任意地址的任意數據,某些硬件平台只能在某些地址處取某些特定類型的數據的,否則拋出硬件異常。

  2. 性能原因
    數據結構(尤其是棧),應該盡可能在自然邊界上對齊,因為在訪問為對齊的內存時,處理器需要訪問兩次,而對齊的內存處理器只需要訪問一次。

對齊規則

  1. 第一個成員在與結構體變量偏移量(offset)為0的地址處。
  2. 其他成員變量要對齊到對齊數的整數倍的地址處。
    1. 對齊數 = 對齊系數 與 該成員大小的較小值。
    2. #pragma pack(n);中的n就是對齊系數。
    3. VS中默認的值為8;linux中的默認值為4。
  3. 結構體總大小為最大對齊數(每個成員變量除了第一個成員都有一個對齊數)的整數倍。
  4. 如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍。
舉例說明對齊原則
1.下面的結構體大小分別是多大(假設32位機器)?
struct A {
char a; //1
char b; //1
char c; //1
};
//進行整體對齊,最大類型為1<對齊系數4,按1整體對齊,所以1+1+1=3 
struct B {
int a;  //4
char b; //1
short c;//2
};
//進行整體對齊,最大類型為4=對齊系數4,所以按4整體對齊4 1+2=3<4 對齊4 所以4+4=8 
struct C {
char b; //1
int a;  //4
short c;//2
};
//進行整體對齊,最大類型為4=對齊系數4,所以按4整體對齊 1<4(對齊4) 4=4 2<4(對齊4)  所以4+4+4=12 
#pragma pack(2)
struct D {
char b; //1
int a;  //4
short c;//2
};
//進行整體對齊,最大類型為4>對齊系數n(2),所以按2整體對齊 1<2(對齊2)4>2(2的倍數) 2=2 所以2+4+2=8 
答案及解析:3 8 12 8


2. 有一個如下的結構體:
struct A{
 long a1;
 short a2;
 int a3;
 int *a4;
};
請問在64位編譯器下用sizeof(struct A)計算出的大小是多少?
24
28
16
18

答案及解析:24
64位編譯器下:指針8字節(一定不能忘記),題目不說默認4字節對齊
long a1;    //8
 short a2;  //2 8+2=10(不是4的倍數)對齊到4的倍數12
 int a3;    //4 4+12=16(4的倍數)
 int *a4;   //8 8+16=24(4的倍數)




3.在32位cpu上選擇缺省對齊的情況下,有如下結構體定義:
struct A{
    unsigned a : 19;
    unsigned b : 11;
    unsigned c : 4;
    unsigned d : 29;
    char index;
};
則sizeof(struct A)的值為()
9
12
16
20

答案及解析16
題目不說,默認4字節對齊
19+11=30<32bit     4
4+29=33>32bit      4+4
1byte=8bit         1  對齊到 4
4+4+4+4=16

C++中的結構體struct---類

  • 在C++中struct是對於C語言中struct的擴展,因為C++是面向對象的語言,可以描述對象的行為,所以在C++中struct內可以放函數,從而就具有類的功能,但又和class有一定的區別。

class和struct的區別

  • class默認成員是私有的private,struct默認成員是公有的public
  • class繼承默認是私有的private,struct繼承默認是公有的public
  • C++中結構體可以不要struct關鍵字,C語言中除了typedef定義別名之外是必須要struct關鍵字。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM