Intel和微软同时出现的C语言面试题 6G<t1?_yD
#pragma pack(8) =!G3YZ
>tq,F"2amC
struct s1{ @R|Gz/
short a;
.3B3Z&vr
long b; ?Q`Sx
}; 4)BPrWea1
e%v<nGN.-
struct s2{ jDp]}d|f)
char c; J#0oL_xY#
s1 d; Q/%(&4>'y
long long e; EzDj,!!<w
}; `J>76WN
;?y*@*2u
#pragma pack() 5PJB<M_m:
&?@gUk74"
问 6;lJs,I1w{
1.sizeof(s2) = ? PC_#kz
2.s2的s1中的a后面空了几个字节接着是b? ? 9.V@+i
p<|I!n&9
#nE%.k|R~
z|Hc=AU8y
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: FA.h?yfr
Q}J'S5%
网友rwxybh(行云)的答案: %0PdN@I
内存布局是 &AMW?vO
1*** 11** ZwLD7j*)
1111 **** b"ypS7
_
1111 1111 n.{+\M6k
u7=jtB
所以答案就是24和3 VK*2`Z1
H:X=v+W
下面是一个测试的程序,试一试就知道了,我用的是VC2005 VWlOMqL995
U8Pnt|0 M
#pragma pack(8) H<M
ggs-
]U]22I'+$2
struct s1{ o@`&
h}
$
short a; // 2 BYtes [mSK!Y@u
long b; // 4 Bytes ^KU:5Bn
}; FQR{w
struct s2{ >-Qg4%m
char c; // 1 Byte o|7]8K=
s1 d; // 8 Bytes ^N!l$&=
long long e; // 8 Bytes }LH>0v_<Y
}; web=AQ5I4
// 1*** 11** D!.
r$i)
// 1111 ****
Wt&tu2
// 1111 1111 BX|+"AeF
// JM#jg-z,~
d9XX^nY.
// 00 01 02 03 04 05 06 07 sW~Z?PFP
// 00 01 02 03 04 05 06 07 g8yWFqE!T
// 00 01 02 03 04 05 06 07 `A.!<bO)]
// <}RU37,W
#pragma pack() 5#zwdoQ
~RVx~hh
int main(int argc, char* argv[]) J?XEF@?'G
{ Ve,_;<F]S
s2 a; `x"0
char *p = (char *)&a; `0rEV_$
for(int i=0;i<24;++i) J}7iXTh
p = (char)(i%8); 71+J{XOC
printf("%d\n",sizeof(a)); K?_4|
printf("c=0x%lx\n",a.c); //G5lW/*
printf("d.a=0x%x\n",a.d.a); jfyV9)
printf("d.b=0x%x\n",a.d.b); zh$[UdY6
printf("e=0x%llx\n",a.e); q/,W'lQ\;
return 0; p6(n\eg R
} % Ke:%##Y
结果: "HW~|M7>(
24 pa&*n=&cL
c=0x0 R1z\b~@"
d.a=0x504 l1~>{:mq
d.b=0x3020100 4WnB{9
i`I
e=0x706050403020100 R/
7G
"t+VF4r
?op6_a-wm
网友 redleaves (ID最吊的网友)的答案和分析: hq.z:D
E+$vIYq:W
如果代码: x. r~e)x=
#pragma pack(8) t;9f7~
struct S1{ [8/E ;h
char a; 3LZ0EYVL
long b; @]Ye36v0#L
}; tvptawA.
struct S2 { XljiK8q;%
char c; rUkiwqr~E
struct S1 d; M:OY8=V
long long e; EA4aZ6%
}; m,3?*0BMp=
#pragma pack() cpB$b C](
sizeof(S2)结果为24. M:c^[9)y
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. S%b7NK
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. ZoB?F
7-+X -Y?
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; "k\W2,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个字节. VrhG=CK
a b B`a5%asJn
S1的内存布局:11**,1111, w
.l2
c S1.a S1.b d 7ZHM;_
-
S2的内存布局:1***,11**,1111,****11111111
SX|b0S,
$kJvPwRO
这里有三点很重要: GLA,,i'i9
1.每个成员分别按自己的方式对齐,并能最小化长度 @R >4b
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 +nRO<
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 mq~7v1kw
u >H^bCXI
De[!^/f;T
网友xue23(xue23) 的答案和分析: ,,oiL
Vw=e C"
有程序查一下各个变量的内存地址得知: =^4 vz=2
各个变量在内存中的位置为 )'M<q,@<(
c***aa** mFOuE5
bbbb**** <tAn2e!
dddddddd 7Xv.C&jzd
测试代码为: AFL* a*
s2 ss; qgw:Q
cout << "ss.c = " << &ss << endl ; 5aw#!K=J'
cout << "ss.d.a = " <<&ss.d.a << endl; w-[WJ:2.
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; 02&m