Intel和微软同时出现的C语言面试题 ;U=IbK*
#pragma pack(8) oE\Cwd
d.Wq@(ZoA
struct s1{ Q%)da)0:c
short a; .l5y+a'
long b; DuX7
}; ,rj_P
%EkV-%o*
struct s2{ 3Kuu9<0
char c; qn)
VKx=
s1 d; "[M,PI!B
long long e; *W,tq(%tQ
}; :EJ8^'0Q
Lc 4\i
#pragma pack() M"# >?6{
D=Ia$O0.
问 Lt`d
{s
1.sizeof(s2) = ? eGcc' LBr;
2.s2的s1中的a后面空了几个字节接着是b? Ua0fs|t1v
c6/+Ye =h
)y>o;^5'
Ilt!O^
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: 7Nx5n<
4@ EY+p
网友rwxybh(行云)的答案: E57:ap)/
内存布局是 u'Ja9m1
1*** 11** tg =ClZ-
1111 **** v:/+OzY
1111 1111 <ua` WRQr
@
3n;>oi
所以答案就是24和3 [R
V_{F:'
-Pds7}F8
下面是一个测试的程序,试一试就知道了,我用的是VC2005 ZqT8G
=AEl:SY+
#pragma pack(8) {2jetX`@h
Cg{V"B:
struct s1{ .*N]SbU<8
short a; // 2 BYtes uWm,mGd9
long b; // 4 Bytes Dxp8^VL
}; ;Q YUiR
struct s2{ Iw@ou
char c; // 1 Byte "rxhS;
R1>
s1 d; // 8 Bytes RNa59b
long long e; // 8 Bytes 6<aZr\Ufg
}; 3B *b d
// 1*** 11** 4wLN#dpeEy
// 1111 **** YY{0WWua
// 1111 1111 OYnxEdo7
// u7PtGN0r%
4I"%GN[tA
// 00 01 02 03 04 05 06 07 :mP%qG9U
// 00 01 02 03 04 05 06 07 }~B @Z\`O
// 00 01 02 03 04 05 06 07 GjVq"S
// V2Iqk]V%y
#pragma pack() Ih Yso7g
F+
,eJ/]
int main(int argc, char* argv[]) ~yX8p7qr
{ 1P8XVI'
s2 a; ^a>3U l{
char *p = (char *)&a; eXs^YPi
for(int i=0;i<24;++i) _:N+mEF
p = (char)(i%8); T"h@-UcTl
printf("%d\n",sizeof(a)); pr~%%fCh
printf("c=0x%lx\n",a.c); )I~U&sT\/
printf("d.a=0x%x\n",a.d.a); o )\\(^ld
printf("d.b=0x%x\n",a.d.b); h=?V)WSM
printf("e=0x%llx\n",a.e); PhUG}94
return 0; uGXN ciEp`
} nK!yu?mS
结果: 8|]r>L$Wk
24 1gK<dg
c=0x0 c>SFttbU
d.a=0x504 5Z8Zb.
d.b=0x3020100 +qPpPjG;
e=0x706050403020100 ,\){-H/n
J#1-Le8@
U-~6<\Mf
网友 redleaves (ID最吊的网友)的答案和分析: $ ,:3I*}be
cd&^ vQL8
如果代码: ON,sN
#pragma pack(8) z (1zth
struct S1{ dM-qd`
char a; egXHp<bqw
long b; `EBI$;!
}; %-nYK3
struct S2 { X
jPPgI
char c; st_.~m!/
struct S1 d; \*a7o GyH>
long long e; E=*82Y=B
}; xX !`0T7Y
#pragma pack() z_i(o
sizeof(S2)结果为24. |\}&mBR
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. w"PnN
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. f6of8BOg
b(E}W2-t
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; ^uWPbW&/q
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. %#_"Ie
a b Pv#Oea?
S1的内存布局:11**,1111, "=0(a)01p:
c S1.a S1.b d m{v*\e7P
S2的内存布局:1***,11**,1111,****11111111 24g\xNnt
$a@T:zfe
这里有三点很重要: v3*y43
1.每个成员分别按自己的方式对齐,并能最小化长度 ZXJ]==
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 |>Ld'\i8
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 Mzg zOM
KD<smwXjG
4 ZUTF3
网友xue23(xue23) 的答案和分析: 2\4ammwT
04j]W]8#
有程序查一下各个变量的内存地址得知: =8o$
各个变量在内存中的位置为 ]\JLlQ}#H
c***aa** Sux/='
bbbb**** gR\z#Sg
dddddddd aAbK{=/y_!
测试代码为: &g.do?
s2 ss; cko^_V&x
cout << "ss.c = " << &ss << endl ; wB(X(nr
cout << "ss.d.a = " <<&ss.d.a << endl; !&eKq?P{j
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; 7Mj:bm&9
print out 各个变量的内存地址不就可以看出来了吗。 o){\qhLp
{py"Ob_
所以答案是24,2. {`ghX%M(l
YAdk3y~pL
但是我的想像中应该是这样的分布情况: CyV2=o!F w
c******* JhU"akoK
aa**bbbb ufF>I
dddddddd L*8U.{NY
_'*Vcu`Y
不知为什么会c和a放在一起,组成8位长度。