Intel和微软同时出现的C语言面试题 \k9]c3V
#pragma pack(8) d<cqY<y VA
tNG[|Bi#
struct s1{ BIXbdo5F
short a; O<P(UT"
long b; VVw5)O1'
}; Y3JIDT^
:!/ (N
struct s2{ /d*[za'0
char c; p5aqlYb6r
s1 d; $U4[a:
long long e; Vtv~jJ{m
}; ]YrgkC35
9T_fq56Oh6
#pragma pack() rtdEIk
RpwDOG
问 eX$RD9
H
1.sizeof(s2) = ? T,9pd;k
2.s2的s1中的a后面空了几个字节接着是b? AD~_n^
B8~bx%)3T
:(YFIW`59
4YgO1}%G
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: ~wQ M
?h
'Ll'8 ps
网友rwxybh(行云)的答案: ~7wLnB
内存布局是 wlFK#iK
1*** 11** &N*l ?7(
1111 **** c"diNbm[
1111 1111 ;]l`Q,*OXb
"^oU&]KQJ
所以答案就是24和3 cI'su?
+y^'\KN
下面是一个测试的程序,试一试就知道了,我用的是VC2005 #x6EZnG
#wZbG|%
#pragma pack(8) 0|6Y%a\U
aZ8f>t1Q
struct s1{ E(_lm&,4+
short a; // 2 BYtes 84<zTmm
long b; // 4 Bytes cs 58: G5
}; K+|0~/0
struct s2{ (QS 0
char c; // 1 Byte zeD=-3
s1 d; // 8 Bytes r72zWpF!Ss
long long e; // 8 Bytes b%].D(qBy
}; 7ufTmz#j<
// 1*** 11** `SA1V),~
// 1111 **** 3X#Cep20a
// 1111 1111 >FS}{O2c
// Rh%A^j@
BP@V:z
// 00 01 02 03 04 05 06 07 0jt@|3
// 00 01 02 03 04 05 06 07 uNca@xl'
// 00 01 02 03 04 05 06 07 -^JPY)\R
// A{Qo}F<*
#pragma pack() RG 9iTA'
OQVo4yl"
int main(int argc, char* argv[]) XUA%3Xr
{ Ya}}a
s2 a; a@-bw4SD
char *p = (char *)&a; x *a_43`
for(int i=0;i<24;++i) 11%Zx3
p = (char)(i%8); }:S}jo7
printf("%d\n",sizeof(a)); }l&y8,[:
printf("c=0x%lx\n",a.c); r::0\{{r"p
printf("d.a=0x%x\n",a.d.a); T%A"E,#
printf("d.b=0x%x\n",a.d.b); ==S^IBG
printf("e=0x%llx\n",a.e); 8gG;A8
return 0; =7EkN% V:{
} (+}44Ldt
结果: NZ?dJ"eq7
24 rH'|$~a
c=0x0 B>[myx
d.a=0x504 ^\r{72!y
d.b=0x3020100 ikO9p|J
e=0x706050403020100 @k\,XV`T~t
wRZS+^hx
'wWuR@e#&
网友 redleaves (ID最吊的网友)的答案和分析: hxt;sQAo{
c<sq0('`
如果代码: q.j$]?PQ
#pragma pack(8) C=bQ2t=Z
struct S1{ U;M! jj
char a; Tfx-h)oP3
long b; >*\yEH9"
}; g1 =>u
struct S2 { nW`] =
char c; ^V7)V)Z;0
struct S1 d; f ~bgZ
long long e; P0RtS1A
}; >Bu_NoM
#pragma pack() wxN&k$`a
sizeof(S2)结果为24. S4rm K&
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. DQ&\k'"\
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Oc-ia)v1G
T-]UAN"O
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; ZZYtaVF:
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. L* ScSxw
a b Wz#ZkNO
S1的内存布局:11**,1111, g`~;"%u7cn
c S1.a S1.b d /B|"<`-H
S2的内存布局:1***,11**,1111,****11111111 w ~^{V4V
I}m>t}QRI_
这里有三点很重要: YN~1.!F
1.每个成员分别按自己的方式对齐,并能最小化长度 uJ8FzS>[V
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 1^ iLs
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 _Fe=:q
1~j,A[&|<
@jq H8
网友xue23(xue23) 的答案和分析: fAfB.|cd
rV2>;FG
有程序查一下各个变量的内存地址得知: foB&H;A4oC
各个变量在内存中的位置为 m)]|mYjju
c***aa** )@] W=
bbbb**** Pn L?zae
dddddddd w2jB6NQX
测试代码为: :Zo^Uc:*w
s2 ss; .- []po
cout << "ss.c = " << &ss << endl ; 1#8~@CQ ::
cout << "ss.d.a = " <<&ss.d.a << endl; {Z1-B60P
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; %d<UMbS^
print out 各个变量的内存地址不就可以看出来了吗。 LR'~:46#u
,Ek6X)|@
所以答案是24,2. 19RbIG/X
b@sq}8YD|z
但是我的想像中应该是这样的分布情况: \Ym!5,^o
c******* AP8J28I
aa**bbbb 6j!a*u:}"
dddddddd ;iJ}[HUo
ywB0
D`s'
不知为什么会c和a放在一起,组成8位长度。