WinCE 下結(jié)構(gòu)體占用空間問題的分析
年前辭職了,準(zhǔn)備年后找工作。
所以在網(wǎng)上查找一下 C/C++ 基礎(chǔ)方面的面試題,個(gè)人感覺這方面還是要準(zhǔn)備一下。
雖然后面的應(yīng)聘沒有用到所準(zhǔn)備的這些,算是學(xué)習(xí)一下。
在學(xué)習(xí)過程中,注意到一些關(guān)于結(jié)構(gòu)體占用內(nèi)存空間大小(sizeof 與 padding byte)的問題,覺得挺有趣的。
在 WinCE 以前的小系統(tǒng)(嵌入式系統(tǒng))編程時(shí),特別注意內(nèi)存的使用情況;但到了 WinCE 系統(tǒng)后,由于設(shè)備一般都有 128M(或更多)的內(nèi)存,所以在內(nèi)存的使用與優(yōu)化上很多人已經(jīng)不太注意。
嵌入式方面的程序員,還是有必要了解以下關(guān)于結(jié)構(gòu)體占用空間這個(gè)問題。
typedef?struct?TwoBytes_S { char?cOne; char?cTwo; }TwoBytesEml; typedef?struct?FourBytes_S { char?cOne; char?cTwo; char?cThree; char?cFour; }FourBytesEml; typedef?struct?EightBytes_S { char?cOne; char?cTwo; char?cThree; char?cFour; char?cFive; char?cSix; char?cSeven; char?cEight; }EightBytesEml; //?結(jié)構(gòu)體實(shí)際占用的空間大小與結(jié)構(gòu)體中占用空間最大的成員有什么關(guān)系? //?結(jié)論:?結(jié)構(gòu)體的大小為結(jié)構(gòu)體中占用字節(jié)最大的成員的倍數(shù)。? //?對(duì)比?TestOder,?TestOrder3?和?TestOder2?占用內(nèi)存空間的情況 typedef?struct?TestOrder_S { char?cFirst; char?cSecond; int?iFirst; char?cThird; char?cFourth; }TestOrder; typedef?struct?TestOrder2_S { int?iFirst; char?cFirst; char?cSecond; char?cThird; char?cFourth; }TestOrder2; typedef?struct?TestOrder3_S { int?iFirst; char?cFirst; char?cSecond; char?cThird; }TestOrder3; //?對(duì)比?TestShort?和?TestShortEml?占用內(nèi)存空間的情況 typedef?struct?TestShort_S { char?cOne; short?sAlign; }TestShort; typedef?struct?TestShortEml_S { char?cOne; TwoBytesEml?sAlign; }TestShortEml; //?對(duì)比?TestInt?和?TestIntEml?占用內(nèi)存空間的情況 typedef?struct?TestInt_S { char?cOne; int?iAlign; }TestInt; typedef?struct?TestIntEml_S { char?cOne; FourBytesEml?iAlign; }TestIntEml; //?對(duì)比?TestDouble?和?TestDoubleEml?占用內(nèi)存空間的情況 typedef?struct?TestDouble_S { char?cOne; double?dfAlign; }TestDouble; typedef?struct?TestDoubleEml_S { char?cOne; EightBytesEml?dfAlign; }TestDoubleEml; //?#define?_USE_WINDOWS_CE_PLATFORM void?CalcSizeOfStruct(void) { #ifdef?_USE_WINDOWS_CE_PLATFORM RETAILMSG(1,(L"size?of?char?is?%drn",sizeof(char))); RETAILMSG(1,(L"size?of?short?is?%drn",sizeof(short))); RETAILMSG(1,(L"size?of?int?is?%drn",sizeof(int))); RETAILMSG(1,(L"size?of?long?is?%drn",sizeof(long))); RETAILMSG(1,(L"size?of?char?*?is?%drn",sizeof(char?*))); RETAILMSG(1,(L"size?of?float?is?%drn",sizeof(float))); RETAILMSG(1,(L"size?of?double?is?%drn",sizeof(double)); //?對(duì)比?TestOder,?TestOrder3?和?TestOder2?占用內(nèi)存空間的情況 RETAILMSG(1,(L"size?of?struct(char,char,int,char,char)?is?%drn",sizeof(TestOrder))); RETAILMSG(1,(L"size?of?struct(int,char,char,char,char)?is?%drn",sizeof(TestOrder2))); RETAILMSG(1,(L"size?of?struct(int,char,char,char)?is?%drn",sizeof(TestOrder3))); //?對(duì)比?TestShort?和?TestShortEml?占用內(nèi)存空間的情況 RETAILMSG(1,(L"size?of?struct(char,short)?is?%drn",sizeof(TestShort))); RETAILMSG(1,(L"size?of?struct(char,TwoBytesEml(char,char))?is?%drn",sizeof(TestShortEml))); //?對(duì)比?TestInt?和?TestIntEml?占用內(nèi)存空間的情況 RETAILMSG(1,(L"size?of?struct(char,int)?is?%drn",sizeof(TestInt))); RETAILMSG(1,(L"size?of?struct(char,FourBytesEml(char,char,char,char))?is?%drn",sizeof(TestIntEml))); //?對(duì)比?TestDouble?和?TestDoubleEml?占用內(nèi)存空間的情況 RETAILMSG(1,(L"size?of?struct(char,double)?is?%drn",sizeof(TestDouble))); RETAILMSG(1,(L"size?of?struct(char,EightBytesEml(char,char,char,char,char,char,char,char))?is?%drn", sizeof(TestDoubleEml))); #else printf("size?of?char?is?%drn",sizeof(char)); printf("size?of?short?is?%drn",sizeof(short)); printf("size?of?int?is?%drn",sizeof(int)); printf("size?of?long?is?%drn",sizeof(long)); printf("size?of?char?*?is?%drn",sizeof(char?*)); printf("size?of?float?is?%drn",sizeof(float)); printf("size?of?double?is?%drn",sizeof(double)); //?對(duì)比?TestOder,?TestOrder3?和?TestOder2?占用內(nèi)存空間的情況 printf("size?of?struct(char,char,int,char,char)?is?%drn",sizeof(TestOrder)); printf("size?of?struct(int,char,char,char,char)?is?%drn",sizeof(TestOrder2)); printf("size?of?struct(int,char,char,char)?is?%drn",sizeof(TestOrder3)); //?對(duì)比?TestShort?和?TestShortEml?占用內(nèi)存空間的情況 printf("size?of?struct(char,short)?is?%drn",sizeof(TestShort)); printf("size?of?struct(char,TwoBytesEml(char,char))?is?%drn",sizeof(TestShortEml)); //?對(duì)比?TestInt?和?TestIntEml?占用內(nèi)存空間的情況 printf("size?of?struct(char,int)?is?%drn",sizeof(TestInt)); printf("size?of?struct(char,FourBytesEml(char,char,char,char))?is?%drn",sizeof(TestIntEml)); //?對(duì)比?TestDouble?和?TestDoubleEml?占用內(nèi)存空間的情況 printf("size?of?struct(char,double)?is?%drn",sizeof(TestDouble)); printf("size?of?struct(char,EightBytesEml(char,char,char,char,char,char,char,char))?is?%drn", sizeof(TestDoubleEml)); #endif } //?第二部分?Leo.Zheng? struct?TstStruct { ????char?*p; ????char?c; ????long?x; }; struct?TstStruct2 { ????char?c;??????/*?1?byte?*/ ????char?pad[7];?/*?7?bytes?*/ ????char?*p;?????/*?4?bytes?*/ ????long?x;??????/*?4?bytes?*/ }; struct?TstStruct3 { ????char?*p;?????/*?4?bytes?*/ ????char?c;??????/*?1?byte?*/ }; struct?TstStruct4 { ????short?s;?????/*?2?bytes?*/ ????char?c;??????/*?1?byte?*/ }; struct?TstStruct5 { ????short?s; ????char?c; ????int?flip:1; ????int?nybble:4; ????int?septet:7; }; struct?TstStruct6 { ????char?c; ????struct?Struct6_Sub ????{ ????????char?*p; ????????short?x; ????}?inner; }; struct?TstStruct6_R { ????struct?Struct6_Sub ????{ ????????char?*p; ????????short?x; ????}?inner; ????char?c; ????short?s; }; struct?TstStruct7 { ????char?c; ????struct?TstStruct7?*p; ????short?x; }; struct?TstStruct8 { ????struct?TstStruct8?*p; ????short?x; ????char?c; }; struct?TstStruct9 { ????struct?foo7_inner ????{ ????????char?*p; ????????short?x; ????}?inner; ????char?c; }; void?CalcSizeOfStruct2(void) { #ifdef?_USE_WINDOWS_CE_PLATFORM RETAILMSG(1,(L"size?of?(struct?TstStruct)????=?%dn",?sizeof(struct?TstStruct))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct2)???=?%dn",?sizeof(struct?TstStruct2))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct3)???=?%dn",?sizeof(struct?TstStruct3))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct4)???=?%dn",?sizeof(struct?TstStruct4))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct5)???=?%dn",?sizeof(struct?TstStruct5))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct6)???=?%dn",?sizeof(struct?TstStruct6))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct6_R)?=?%dn",?sizeof(struct?TstStruct6_R))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct7)???=?%dn",?sizeof(struct?TstStruct7))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct8)???=?%dn",?sizeof(struct?TstStruct8))); ????RETAILMSG(1,(L"size?of?(struct?TstStruct9)???=?%dn",?sizeof(struct?TstStruct9))); #else ????printf("size?of?(struct?TstStruct)????=?%dn",?sizeof(struct?TstStruct)); ????printf("size?of?(struct?TstStruct2)???=?%dn",?sizeof(struct?TstStruct2)); ????printf("size?of?(struct?TstStruct3)???=?%dn",?sizeof(struct?TstStruct3)); ????printf("size?of?(struct?TstStruct4)???=?%dn",?sizeof(struct?TstStruct4)); ????printf("size?of?(struct?TstStruct5)???=?%dn",?sizeof(struct?TstStruct5)); ????printf("size?of?(struct?TstStruct6)???=?%dn",?sizeof(struct?TstStruct6)); ????printf("size?of?(struct?TstStruct6_R)?=?%dn",?sizeof(struct?TstStruct6_R)); ????printf("size?of?(struct?TstStruct7)???=?%dn",?sizeof(struct?TstStruct7)); ????printf("size?of?(struct?TstStruct8)???=?%dn",?sizeof(struct?TstStruct8)); ????printf("size?of?(struct?TstStruct9)???=?%dn",?sizeof(struct?TstStruct9)); #endif } //?在?WinCE?上運(yùn)行輸出如下: /* size?of?char?is?1 size?of?short?is?2 size?of?int?is?4 size?of?long?is?4 size?of?char?*?is?4 size?of?float?is?4 size?of?double?is?8 size?of?struct(char,char,int,char,char)?is?12 size?of?struct(int,char,char,char,char)?is?8 size?of?struct(int,char,char,char)?is?8 size?of?struct(char,short)?is?4 size?of?struct(char,TwoBytesEml(char,char))?is?3 size?of?struct(char,int)?is?8 size?of?struct(char,FourBytesEml(char,char,char,char))?is?5 size?of?struct(char,double)?is?16 size?of?struct(char,EightBytesEml(char,char,char,char,char,char,char,char))?is?9 size?of?(struct?TstStruct)????=?12 size?of?(struct?TstStruct2)???=?16 size?of?(struct?TstStruct3)???=?8 size?of?(struct?TstStruct4)???=?4 size?of?(struct?TstStruct5)???=?8 size?of?(struct?TstStruct6)???=?12 size?of?(struct?TstStruct6_R)?=?12 size?of?(struct?TstStruct7)???=?12 size?of?(struct?TstStruct8)???=?8 size?of?(struct?TstStruct9)???=?12 */ //?在?X86?上運(yùn)行的輸出如下: /* size?of?char?is?1 size?of?short?is?2 size?of?int?is?4 size?of?long?is?4 size?of?char?*?is?4 size?of?float?is?4 size?of?double?is?8 size?of?struct(char,char,int,char,char)?is?12 size?of?struct(int,char,char,char,char)?is?8 size?of?struct(int,char,char,char)?is?8 size?of?struct(char,short)?is?4 size?of?struct(char,TwoBytesEml(char,char))?is?3 size?of?struct(char,int)?is?8 size?of?struct(char,FourBytesEml(char,char,char,char))?is?5 size?of?struct(char,double)?is?16 size?of?struct(char,EightBytesEml(char,char,char,char,char,char,char,char))?is?9 size?of?(struct?TstStruct)????=?12 size?of?(struct?TstStruct2)???=?16 size?of?(struct?TstStruct3)???=?8 size?of?(struct?TstStruct4)???=?4 size?of?(struct?TstStruct5)???=?8 size?of?(struct?TstStruct6)???=?12 size?of?(struct?TstStruct6_R)?=?12 size?of?(struct?TstStruct7)???=?12 size?of?(struct?TstStruct8)???=?8 size?of?(struct?TstStruct9)???=?12 */