由一道面試題來(lái)看
Struct
的對(duì)界
?
本文節(jié)選自宋寶華的C/C++的struct深層探索一文,本人對(duì)其所描述的struct對(duì)齊比較喜歡,為此轉(zhuǎn)來(lái)與大家分享,原文見(jiàn)http://blog.donews.com/21cnbao/archive/2005/09/08/544877.aspx
?
Intel
、微軟等公司曾經(jīng)出過(guò)一道類(lèi)似的面試題:
1. #include <iostream.h>
2. #pragma pack(8)
3. struct example1
4. {
5. ? ??short a;
6. ? ??long b;
7. };
8. struct example2
9. {
10. ?????? ??char c;
11. ?????? ??example1 struct1;
12. ?????? ??short e;
13. };
14. #pragma pack()
?
15. int main(int argc, char* argv[])
16. {
17. ?????? ??example2 struct2;
18. ??cout << sizeof(example1) << endl;
19. ??cout << sizeof(example2) << endl;
20. ??cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2)
<< endl;
21. return 0;
22. }
問(wèn)程序的輸入結(jié)果是什么?
答案是:
8
16
4
不明白?還是不明白?下面一一道來(lái):
1
、
自然對(duì)界
struct
是一種復(fù)合數(shù)據(jù)類(lèi)型,其構(gòu)成元素既可以是基本數(shù)據(jù)類(lèi)型(如
int
、
long
、
float
等)的變量,也可以是一些復(fù)合數(shù)據(jù)類(lèi)型(如
array
、
struct
、
union
等)的數(shù)據(jù)單元。對(duì)于結(jié)構(gòu)體,編譯器會(huì)自動(dòng)進(jìn)行成員變量的對(duì)齊,以提高運(yùn)算效率。缺省情況下,編譯器為結(jié)構(gòu)體的每個(gè)成員按其自然對(duì)界(
natural alignment
)條件分配空間。各個(gè)成員按照它們被聲明的順序在內(nèi)存中順序存儲(chǔ),第一個(gè)成員的地址和整個(gè)結(jié)構(gòu)的地址相同。
自然對(duì)界
(natural alignment)
即默認(rèn)對(duì)齊方式,是指按結(jié)構(gòu)體的成員中
size
最大的成員對(duì)齊。
例如:
struct naturalalign
{
char a;
short b;
char c;
};
在上述結(jié)構(gòu)體中,
size
最大的是
short
,其長(zhǎng)度為
2
字節(jié),因而結(jié)構(gòu)體中的
char
成員
a
、
c
都以
2
為單位對(duì)齊,
sizeof(naturalalign)
的結(jié)果等于
6
;
如果改為:
struct naturalalign
{
char a;
int b;
char c;
};
其結(jié)果顯然為
12
。
?
2
、
指定對(duì)界
一般地,可以通過(guò)下面的方法來(lái)改變?nèi)笔〉膶?duì)界條件:
·
使用偽指令
#pragma pack (n)
,編譯器將按照
n
個(gè)字節(jié)對(duì)齊;
·
使用偽指令
#pragma pack ()
,取消自定義字節(jié)對(duì)齊方式。
注意:如果
#pragma pack (n)
中指定的
n
大于結(jié)構(gòu)體中最大成員的
size
,則其不起作用,結(jié)構(gòu)體仍然按照
size
最大的成員進(jìn)行對(duì)界。
例如:
#pragma pack (n)
struct naturalalign
{
char a;
int b;
char c;
};
#pragma pack ()
當(dāng)
n
為
4
、
8
、
16
時(shí),其對(duì)齊方式均一樣,
sizeof(naturalalign)
的結(jié)果都等于
12
。而當(dāng)
n
為
2
時(shí),其發(fā)揮了作用,使得
sizeof(naturalalign)
的結(jié)果為
8
。