Intel和微软同时出现的C语言面试题 `R!0uRu
#pragma pack(8) -86 9$
{b<p~3%+Hc
struct s1{ 8n?P'iM
short a; .Ig`v
long b; )U>q><
}; isj<lnQ
Iu2RK
struct s2{ O1JGv8Nr
char c; Fr,>|
s1 d; -F4CHpua
long long e; <&8cq@<
}; U/&?rY^|
$ZK4Ps -$
#pragma pack() !
D'U:)
pb{'t2kk
问 |LcN_,}6
1.sizeof(s2) = ? cwz
% LKh
2.s2的s1中的a后面空了几个字节接着是b? KB&t31aq
@>qzRo
Pgr>qcbql
\hc}xy
0
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: JR$Dp&]I
'hVOK(o0
网友rwxybh(行云)的答案: :?RooJ~#
内存布局是 3.Ni%FF`
1*** 11** qX0IHe
1111 **** I:]s/r7
1111 1111 XsQ<yeun
cI?dvfU?
所以答案就是24和3 S@Yb)">ZQ
JXftQOn
下面是一个测试的程序,试一试就知道了,我用的是VC2005 ah"2^x
UQPd@IVu6
#pragma pack(8) aPcO9
Dd!MG'%hlb
struct s1{ H6/@loO!Xy
short a; // 2 BYtes hNyYk(t^
long b; // 4 Bytes @xtcjB9
}; [@rZ.Hsl
struct s2{
fhL dM
char c; // 1 Byte OB6I8n XW
s1 d; // 8 Bytes l#~Sh3@L(
long long e; // 8 Bytes {u9(qd;;
}; fF_1ZKx+#!
// 1*** 11** kkyn>Wxv
// 1111 **** NX@TWBn%
// 1111 1111 .m;1V6
// uTbI\iq
yIXM}i:
// 00 01 02 03 04 05 06 07 ^(N+s?
// 00 01 02 03 04 05 06 07 "0`r]5 5d
// 00 01 02 03 04 05 06 07 k1$|vzMh
// =(Mv@eA"
#pragma pack() f3y_&I+zl
I?4J69'
int main(int argc, char* argv[]) V F6OC4 K
{ mXz-#Go(
s2 a; $Fc*^8$ryC
char *p = (char *)&a; 42Gr0+Mb
for(int i=0;i<24;++i) qoB
p = (char)(i%8); O*H:CW
printf("%d\n",sizeof(a)); MZ=U}
&F
printf("c=0x%lx\n",a.c); }UXj|SY
printf("d.a=0x%x\n",a.d.a); x@v,qF$K
printf("d.b=0x%x\n",a.d.b); WB6g i2
printf("e=0x%llx\n",a.e); gSZNsiH
return 0; >kz5azV0
} V/"0'H\"1
结果: /B|#GJ\\3
24 #c+N}eX{
c=0x0 QMy;?,
d.a=0x504
*ErTDy(
d.b=0x3020100 aZ*b"3
e=0x706050403020100 ~<Gs<c}z
9s73mu`Twg
R(k6S
网友 redleaves (ID最吊的网友)的答案和分析: z;#}uC
u\^<V)
如果代码: Iy8gQdI
#pragma pack(8) K?-K<3]9f
struct S1{ 45/f}kvy
char a; O5Yk=-_m
long b; c*~/[:}
}; wh|[
"U('
struct S2 { C0i: *1
char c; S &s7]
struct S1 d; lH:TE=|4
long long e; Z:O24{ro5
}; 7fI[yCh
#pragma pack() kzJNdYtdH
sizeof(S2)结果为24. 6}C4 SZ
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. U+@yx>!
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. R!*UU'se
t
Z\
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; f:Nfw+/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个字节. F mh;d*IT
a b w,eYrxR|N
S1的内存布局:11**,1111, [ueT]%
c S1.a S1.b d 75!IzJG
S2的内存布局:1***,11**,1111,****11111111 ukS@8/eJ
Bwb3@vNA
这里有三点很重要: %L/Wc,My
1.每个成员分别按自己的方式对齐,并能最小化长度 ppb]RN|)
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 wA.YEI|CSj
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 4)JrOe&k
(LL4V
3)
n@T4z.*~lA
网友xue23(xue23) 的答案和分析: m`nv4 i#o
wXuHD<<
有程序查一下各个变量的内存地址得知: _m3PAD4
各个变量在内存中的位置为 OjJlGEl w
c***aa** (mt,:hX
bbbb**** [g=yuVXNZZ
dddddddd }4cLU.L8O
测试代码为: U
g]6i+rp
s2 ss; J:#B,2F+^
cout << "ss.c = " << &ss << endl ; oF]0o`U&a
cout << "ss.d.a = " <<&ss.d.a << endl; E`LML?
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; Fd5{ pM3
print out 各个变量的内存地址不就可以看出来了吗。 +Y)rv6}m
J24UUZ9&$
所以答案是24,2. H&mw!=FV0
ReZ|q5*
但是我的想像中应该是这样的分布情况: "E/F{6NH
c******* J%j#gyTU
aa**bbbb 0@*rp7
dddddddd 72~)bu
f]T#q@|lE
不知为什么会c和a放在一起,组成8位长度。