轉ios
在面試中,常會考到結構體的對齊方式,所以對其進行總結。面試
一、在沒有#pragma pack宏的狀況下spa
struct sA{ double d1; int i1; double d2; char c1; };
原則1:每一個成員按類型的大小對齊,即相對於結構體地址的成員地址能被類型大小整除.而且結構體的大小(sizeof(A))必須爲成員所含類型中最大值(sizeof(double))的整數倍,不夠就補空字節.code
例1:對象
例如用結構體定義對象A,其第一個成員d1的類型爲double,大小爲8字節,它的地址(也是A的地址)就須要能被4整除,這主要是由於爲A申請內存時,其地址由其成員中所含的最大類型單獨申請內存的規則決定(A中最大類型爲double),int和double類型在單獨申請內存時,其地址爲4的整數倍。第二個成員i1的類型爲int,大小爲4字節,它相對於結構體A地址(00BDF7EC)的成員地址(8)能被4整除,不須要補充空白字節。第三個成員d2的類型爲double,大小爲8字節,它相對於結構體A地址(00BDF7EC)的成員地址(12)不能被8整除,須要補充4個空白字節。第四個成員c1的類型爲char,大小爲1字節,它相對於結構體A地址(00BDF7EC)的成員地址(16)能被1整除,不須要補充空白字節。blog
原則2:結構體做爲成員,類型大小按其成員所含最大類型計算。內存
struct sB{ char c1; sA sA1; };
例2:struct sB裏存有struct sA,其結構體成員sA1的類型大小按8字節計算io
原則3:結構體的總大小,爲其成員中所含最大類型的整數倍。在例1中即爲成員d1類型(double,8)的整數倍。而在例二中即爲成員sA1類型(8)的整數倍。class
二、在有#pragma pack宏的狀況下stream
(1)#pragma pack(1),例1和例2的狀況以下
能夠看到其成員均按1做爲其類型大小進行對齊,結構體的總大小也爲1的整數倍。
(2)#pragma pack(2),例1和例2的狀況以下
能夠看到其成員均按2做爲其類型大小進行對齊,結構體的總大小也爲2的整數倍。
(3)#pragma pack(4),例1和例2的狀況以下
能夠看到其成員均按4做爲其類型大小進行對齊,結構體的總大小也爲4的整數倍。
#include<stdio.h> #include<iostream> using namespace std; #pragma pack(2) struct sA{ double d1; int i1; double d2; char c1; }; struct sB{ char c1; sA sA1; }; int main() { sA A; sB B; cout << "A的地址:" << &A << endl << "A.d1的地址:" << &A.d1 << endl << "A.i1的地址:" << &A.i1 << endl << "A.d2的地址:" << &A.d2 << endl << "A.c1的地址:" <<(void*)&A.c1 << endl << "A的大小:" << sizeof(A) << endl; cout << "B的地址:" << &B << endl << "B.c1的地址:" <<(void*) &B.c1 << endl << "B.sA1的地址:" << &B.sA1 << endl << "B的大小:" << sizeof(B) << endl; while (1); return 0; }