Intel和微软同时出现的C语言面试题 H-WJp<_
#pragma pack(8) i1UiNJh86
1Rq,a
struct s1{ B|Du@^$
short a; fJ5iS
long b; i3dkYevs?
}; <qtr
=MSr/ O2
struct s2{ z-BXd
char c; $:BKzHmg
s1 d; l~1Oef#y
long long e; &]g}u5J!=
}; -O1>|y2rU
au N6prGe
#pragma pack() ICpAt~3[M
jGJLSEe_
问 .I$qCb|FP
1.sizeof(s2) = ? kd>hhiz|
2.s2的s1中的a后面空了几个字节接着是b? j1^I+j)
1!ii;s^e
VX].3=T8
>i_2OV
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: j@=%_^:i
R}'bP
网友rwxybh(行云)的答案: R(!s
内存布局是 UXeN 8
1*** 11** ;"KJ7p
1111 **** mkMq
1111 1111 @u.58H& }R
WeJl4wF
所以答案就是24和3 `
w=>I
cT<1V!L4
下面是一个测试的程序,试一试就知道了,我用的是VC2005 %huRsQ%}
+Um( h-;
#pragma pack(8) *e<[SZzYZ
//*fSF
struct s1{ o#;b
short a; // 2 BYtes t,QyfN
long b; // 4 Bytes DD7h^-x
}; $g@=Z"
struct s2{ xRJ\E }/7
char c; // 1 Byte M.Y~1c4f
s1 d; // 8 Bytes , qA(\[
long long e; // 8 Bytes ^.1)};i
}; ={_C&57N1
// 1*** 11** !\"EFVH
// 1111 **** 0bz'&
// 1111 1111 ?@BTGUK"C
// V\t.3vT
BD68$y
// 00 01 02 03 04 05 06 07 @"hb) 8ng
// 00 01 02 03 04 05 06 07 nePfuG]Q
// 00 01 02 03 04 05 06 07 5*E]ETo@R
// kEJj=wx
#pragma pack() .GV;+8HzS
zepm!JR1
int main(int argc, char* argv[]) x%}^hiO<q
{ ,">]`|?
s2 a;
7_%"BVb"
char *p = (char *)&a; {`J)j6;
for(int i=0;i<24;++i) Hv!U|L
p = (char)(i%8); `lQ3C{}
printf("%d\n",sizeof(a)); $Oq^jUJ
printf("c=0x%lx\n",a.c); ]*vdSr-J
printf("d.a=0x%x\n",a.d.a); j`oy`78O
printf("d.b=0x%x\n",a.d.b); tU4s'J
printf("e=0x%llx\n",a.e); 3XL#0\im?s
return 0; Qr1 "Tk7s
} mIurA?&7!
结果: ^]7}YF2|
24 (^s>m,h
c=0x0 O9vQp
d.a=0x504 5pj22 s
d.b=0x3020100 9G9fDG#F\I
e=0x706050403020100 "k/;[ Wt]
w0ht
S)lkz'tdk
网友 redleaves (ID最吊的网友)的答案和分析: #EO9UW5
A$<.a'&T!
如果代码: @AGn{q
#pragma pack(8) X59:C3c
struct S1{ 0":ib0=
char a; T29Dt
long b; z,Medw6[
}; @GkILFN
struct S2 { ?
K;dp
char c; sA/pVU
struct S1 d; <<@bl@9'
long long e; 5Eg1Q
YVt
}; 1|RANy
#pragma pack() =5Q]m6-SgV
sizeof(S2)结果为24. 2-7IJ\
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. >XK
PTC5H
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. @*OZx 9
@<&5J7fb
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; j2ve^F: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个字节. ~T9/#-e>BF
a b U[SaY0Z
S1的内存布局:11**,1111, I`p+Qt
c S1.a S1.b d ]j'p :v
S2的内存布局:1***,11**,1111,****11111111 T@G?t0
m=?KZ?U`
这里有三点很重要: w,w{/T+B
1.每个成员分别按自己的方式对齐,并能最小化长度 j:5=s%S
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 :ZTc7}
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 :axRoRg
xGu r
|s"nM<ZNZ
网友xue23(xue23) 的答案和分析: Nd`%5%'::
qm./|#m>
有程序查一下各个变量的内存地址得知: EKA#|^Q:NX
各个变量在内存中的位置为 5V6G=H
c***aa** pNOwDJtK
bbbb**** FB
_pw!z
dddddddd s8-<m,*
测试代码为: _(Sa4Vb=Q6
s2 ss; uxW~uEh
cout << "ss.c = " << &ss << endl ; Z9MdD>uwi
cout << "ss.d.a = " <<&ss.d.a << endl; I^0t2[M
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; Etnb3<^[t
print out 各个变量的内存地址不就可以看出来了吗。 m3
IP7h'
{gkwOMW
所以答案是24,2. b&t[S[P.V
wa3F
但是我的想像中应该是这样的分布情况: ]if;A ) '
c******* c;V D}UD'
aa**bbbb @!H
'+c
dddddddd wL
eHQ]
DzDj)7
不知为什么会c和a放在一起,组成8位长度。