Intel和微软同时出现的C语言面试题 pn $50c
#pragma pack(8) :
m5u=:t
<dYk|5AdLF
struct s1{ iz^wBQ
short a; (x^|
long b; =-VV`
}; ONGe/CEXT
mW-@-5Wda
struct s2{ I(<G;ft<}
char c; u3. PHZ
s1 d; >rFvT>@NU
long long e; %9D@W*Z
}; /3TorB~Y
I@S<D"af
#pragma pack() KncoIw
'j)eqoj
问 D1Sl+NOV
1.sizeof(s2) = ? E7h}0DX
2.s2的s1中的a后面空了几个字节接着是b? wKeqR$
yY| .
%@&)t?/=
&V:dcJ^Q
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: 7.Mh$?;i9
/*O,T
网友rwxybh(行云)的答案: O^x t
内存布局是 nDOIE)#
1*** 11** B)Q'a3d#
1111 **** a,4g`?
1111 1111 V]O
:;(W_
hrL<jcv|
所以答案就是24和3 _N:h&uw
4By-+C*
下面是一个测试的程序,试一试就知道了,我用的是VC2005 _[phs06A
OX`n`+^D
#pragma pack(8) jF;4
8g@^
d$TW](Bby
struct s1{ ~JNuy"8
short a; // 2 BYtes PW`Tuj
long b; // 4 Bytes jFXU
xf
}; >eTlew<5
struct s2{ CbHNb~
char c; // 1 Byte :9YQX(l8
s1 d; // 8 Bytes -0X> y
long long e; // 8 Bytes @iRVY|t/
}; 1}uDgz^
// 1*** 11** c'B"Onu@m*
// 1111 **** "n6Y^
// 1111 1111 J7_H.RPa
// !:t9{z{Ixg
Xp~]kRm9
// 00 01 02 03 04 05 06 07 9vbh5xX
// 00 01 02 03 04 05 06 07 7xc<vl#:q7
// 00 01 02 03 04 05 06 07 Xdq,
=;
// >" .qFn g
#pragma pack() m%V[&"5%e
UH.cn|R
int main(int argc, char* argv[]) bevT`D
{ K(d!0S
s2 a; \$C4H
char *p = (char *)&a; tAA7
for(int i=0;i<24;++i) 5 q ,
p = (char)(i%8); cMl%)j-
printf("%d\n",sizeof(a)); eFio,
printf("c=0x%lx\n",a.c); 4PWr;&
printf("d.a=0x%x\n",a.d.a); xB(:d'1|
printf("d.b=0x%x\n",a.d.b); x]ti3?w
printf("e=0x%llx\n",a.e); <n\.S
return 0; `g1Oon_
} @EY}iK~
结果: QB[s8"S
24 K|G$s
c=0x0 ja;5:=8A5
d.a=0x504 Vi#im`@
d.b=0x3020100 &XsLp&Do2
e=0x706050403020100 lz (,;I'x
Wn^^Q5U#
L)}V[j#
网友 redleaves (ID最吊的网友)的答案和分析: %jxuH+L
>D/~|`=p
如果代码: A,{D9-%
#pragma pack(8) xiF%\#N
struct S1{ .NT&>X~.V
char a; zcKC5vqb
long b; lAk1ncx
}; i'wF>EBz
struct S2 { V@S/!h+
char c; ?i~/gjp
struct S1 d; }BJ1#<
long long e; hzLGmWN2j8
}; 2mZ/
3u
#pragma pack() wP/9z(US
sizeof(S2)结果为24. RC(D=6+[C
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. y^=oYL
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. *?D2gaCta
@'*#]YU8
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; $-]setdY
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. ^,K.)s
a b 8 uxFXQ
S1的内存布局:11**,1111, Z]TVH8%|k
c S1.a S1.b d ]7t\%_
S2的内存布局:1***,11**,1111,****11111111 z4641q5'm
6B/"M-YME
这里有三点很重要: LH#LBjOZk
1.每个成员分别按自己的方式对齐,并能最小化长度 l :Nxl
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 xD#I&.
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 o'7ju~0L
#L.}CzAz
!2|`aa
网友xue23(xue23) 的答案和分析: %GbPrlu
5vi#ItN}|
有程序查一下各个变量的内存地址得知: 0juIkN#
各个变量在内存中的位置为 ,R}KcZG)
c***aa** "IG$VjgcB
bbbb**** wmE,k1G
dddddddd iT5SuIv
测试代码为: \~t~R q
s2 ss; M5kHD]b
cout << "ss.c = " << &ss << endl ; ^3|$wB=
cout << "ss.d.a = " <<&ss.d.a << endl; bM^A9BxD
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; aRKRy
print out 各个变量的内存地址不就可以看出来了吗。 o:DBOpS
}8M`2HMFR
所以答案是24,2. Gu`Vk/&
**r?
但是我的想像中应该是这样的分布情况: ,,_K/='m
c******* |D`b7h
aa**bbbb @Q\$dneY
dddddddd zXPJ;^Xxa
'&:x_WwVrO
不知为什么会c和a放在一起,组成8位长度。