Intel和微软同时出现的C语言面试题 A8muQuj]~~
#pragma pack(8) W=N+VqK
Ia SR;/
struct s1{ ^O?/yV?4c
short a; &*M!lxDN
long b; ` Fa~
}; ha]VWt%}
6AAz
struct s2{ Ua:}V n&!
char c; X-bcQ@Oj
s1 d; P78g/p T
long long e; p$S*dr
}; Snj'y,p[
d[iQ`YW5
#pragma pack() z O-z%y
Q*D;U[
问 KjD/o?JUr
1.sizeof(s2) = ? .YtKS
2.s2的s1中的a后面空了几个字节接着是b? D}-/c"':}
\j$&DCv
8SMxw~9$
s:n6rG
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: L^1NY3=$
2=*H 8'k
网友rwxybh(行云)的答案: Tf>bX_L?
内存布局是 #|uCgdi
1*** 11** 5?f ^Rz
1111 **** 3(>B Ke
1111 1111 d-oMQGOklb
/T"+KU*
所以答案就是24和3 Sj3+l7S?
s
n8Qk=K
下面是一个测试的程序,试一试就知道了,我用的是VC2005 sU=H&D99
]_)yIi"
#pragma pack(8) f[]dfLS"W
z}.e]|b^H
struct s1{ 0HZ{Y9]
short a; // 2 BYtes })'B<vq
long b; // 4 Bytes Pd8![Z3
}; =7?4eYHC
struct s2{ 9=s<Ld
char c; // 1 Byte ><4<yj1
s1 d; // 8 Bytes EfqX
y>W
long long e; // 8 Bytes qv-8)MSr
}; irZ])a
// 1*** 11** ___~D
dq
// 1111 **** (O\)_#-D
// 1111 1111 91/Q9xY
// &1Ok`_plO
."g`3tVK
// 00 01 02 03 04 05 06 07 xH ]Ct~md
// 00 01 02 03 04 05 06 07 9p]QM)M
// 00 01 02 03 04 05 06 07 )Om*@;r(
// %O;:af"Ja8
#pragma pack() [z:!j$K
vz&|J
int main(int argc, char* argv[]) #`^}PuQ
{ 6%' QjwM_
s2 a;
_O?`@g?i
char *p = (char *)&a; ,CJWO bn3
for(int i=0;i<24;++i) -E[Kml~U
p = (char)(i%8); /'SNw?&
printf("%d\n",sizeof(a)); poE0{HOU
printf("c=0x%lx\n",a.c); /PVk{3
printf("d.a=0x%x\n",a.d.a); @FAA2d
printf("d.b=0x%x\n",a.d.b); x>K Or,f
printf("e=0x%llx\n",a.e); G/E+L-N#`
return 0; rSY!vkLE\
} cVv=*81\
结果: <sbu;dQ`
24 +Ze}B*0
c=0x0 ^^sE:
d.a=0x504 '@v\{ l
d.b=0x3020100 s S+MqBh&I
e=0x706050403020100 [jQp~&nY
.^`{1%
ZvM(Q=^
网友 redleaves (ID最吊的网友)的答案和分析: h,:m~0gmj
)rU
如果代码: bIDj[-CDG
#pragma pack(8) l:~/<`o
struct S1{ K8|r&`X0
char a; FjHv
long b; n`_{9R
}; >b}o~F^J
struct S2 { Qp5VP@t
char c; C}j"Qi`
struct S1 d; QT5TE: D
long long e; gx/,)> E.
}; 0],r0
#pragma pack() e(&v"}Ef`
sizeof(S2)结果为24. y-b%T|p9
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. d'gfQlDny
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. g}oi!f$|
tKuwpT1Qc
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; df +l%9@
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. oH?b}T=9jz
a b 9rX&uP)j^#
S1的内存布局:11**,1111, e2Pcm_Ahv*
c S1.a S1.b d a5"D @E
S2的内存布局:1***,11**,1111,****11111111 3pROf#M
a5^]20Fa
这里有三点很重要: <NY^M!
1.每个成员分别按自己的方式对齐,并能最小化长度 ,8uqdk-D
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 6Pnjmw.HV
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 H|<[YYk
!-x$L>1$
:RTC!spy
网友xue23(xue23) 的答案和分析: +o{R _
UgSB>V<?
有程序查一下各个变量的内存地址得知: H2\;%K 2
各个变量在内存中的位置为 xt*
3'v
c***aa** ~W'{p
bbbb**** {lDd.Fn
dddddddd =o(5_S.u;
测试代码为: wssRA?9<
s2 ss; dL 1tl
cout << "ss.c = " << &ss << endl ; /t57!&
cout << "ss.d.a = " <<&ss.d.a << endl; aiUY>M#|
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; =:Fc;n>c<K
print out 各个变量的内存地址不就可以看出来了吗。 N)| yu1S
kZ
.gO
所以答案是24,2. \ZFGw&yN
Qj.#)R
但是我的想像中应该是这样的分布情况: "Yv_B3p
c******* ,eW%{[g(
aa**bbbb Gr'
CtO
dddddddd 34O
`@j0-3
@f~RdO3
不知为什么会c和a放在一起,组成8位长度。