Intel和微软同时出现的C语言面试题 ;Z:z'';Lm
#pragma pack(8) .r)WDR
U5jY/e_
struct s1{ O$J'BnPpw
short a; lY[>}L*H8
long b; yL^1s\<ddW
};
0|9(oP/:
ELeR5xT
struct s2{ <1.].A@b*
char c; :!;BOCTYI
s1 d; $74ZC
M
long long e; +?zyFb]Km
}; EJO:3aKa
L,of@>
#pragma pack() P1]ucu_y,
d i`}Y&
问 =L{lt9qQz
1.sizeof(s2) = ? _SjS^z~
2.s2的s1中的a后面空了几个字节接着是b? a"&@G=M@d
"tBdz V
e2*0NT^R
&_HSrU
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: lSC3m=4g
cRsLt/Wr
网友rwxybh(行云)的答案: %gSqc
}v*
内存布局是 &NZN_%
1*** 11** r+3V+:f
1111 **** FjRJSMwO,
1111 1111 3}= .7qm
1eZ">,F6<
所以答案就是24和3 ?^mgK9^v@
T5)Xl 'Q
下面是一个测试的程序,试一试就知道了,我用的是VC2005 V7%G?
Kg=TPNf"$
#pragma pack(8) .*:SZ3v
f/H rO6~k%
struct s1{ s@OCj0'l
short a; // 2 BYtes X ~%I(?OX
long b; // 4 Bytes @y[Zr6\z
}; aDb@u3X@
struct s2{ -`n>q^A7e
char c; // 1 Byte quN7'5ZC[
s1 d; // 8 Bytes Ij(S"P@
long long e; // 8 Bytes p<?~~7V
}; RQWVjF#
// 1*** 11** t }7hD
// 1111 **** h#@l'Cye
// 1111 1111 A9qCaq{
// ^+oi|y
vC E$)z'"
// 00 01 02 03 04 05 06 07 m~1{~'
// 00 01 02 03 04 05 06 07 i:Pg&474f
// 00 01 02 03 04 05 06 07 ?{?mAbc
// #HWz.Wb
#pragma pack() R[LVx-e7'
w(8q qU+\
int main(int argc, char* argv[]) 0{F"b'h
{ `I ,A7b
s2 a; }X$vriW
char *p = (char *)&a; it=L_zu}
for(int i=0;i<24;++i) [&|Le;h
p = (char)(i%8); 2hEB?ZAQZ
printf("%d\n",sizeof(a)); O_K@\<;~
printf("c=0x%lx\n",a.c); 0*L|rJf
printf("d.a=0x%x\n",a.d.a); nL5Gr:SLo
printf("d.b=0x%x\n",a.d.b); sSd
printf("e=0x%llx\n",a.e); z@>z.d4
return 0; Wa
#,>
} =rl/l8|P
结果: 8A"[n>931
24 pP68jL
c=0x0 aO.'(kk8
d.a=0x504 ;!, ]}2w*X
d.b=0x3020100 `]\4yTd
e=0x706050403020100 'G>Ejh@t
x5v^@_:
jr
2_vE
网友 redleaves (ID最吊的网友)的答案和分析: BnvUPDT&
VD/Wl2DK
如果代码: 96]lI3c
#pragma pack(8) }r]WB)_w
struct S1{ r/HKxXT
char a; @I\Z2-J
long b; jz't!wj
}; $ ;>,
struct S2 { J9)wt ?%j
char c; ]/p0j$Tq$
struct S1 d; M$1+,[^f
long long e; O}NR{B0B3&
}; {*~aVw {k
#pragma pack() 2n?\tOm(V
sizeof(S2)结果为24. &~pj)\_
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. vNLf)B
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 8V_
]}W
fpM4q
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; +1Si>I
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. BS;rit:
a b |~8\{IcZ
S1的内存布局:11**,1111, -le:0NUwI
c S1.a S1.b d G\Hck=P[$3
S2的内存布局:1***,11**,1111,****11111111 ' :g8a=L
`=uCp^+v
这里有三点很重要: mvVVPf9
1.每个成员分别按自己的方式对齐,并能最小化长度 w!:u|
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 .!KlN% As
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 [4
g5{eX
\cPGyeq
`PSr64h:D
网友xue23(xue23) 的答案和分析: nuw90=qj!]
q\O'r[&V
有程序查一下各个变量的内存地址得知: E?y0UD[8J
各个变量在内存中的位置为 3
C=nC
c***aa** _8\Uukm
bbbb**** kOVx]=
dddddddd .Y_RI&B!L
测试代码为: tH5f;mY,
s2 ss; L}nj#z4g
cout << "ss.c = " << &ss << endl ; <%J dQ82?
cout << "ss.d.a = " <<&ss.d.a << endl; |?s%8c'w=
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; ll1?I8}5|
print out 各个变量的内存地址不就可以看出来了吗。 J4j?rLR3p
[Qy]henK
所以答案是24,2. *Zt)J8C
;PaB5TT(
但是我的想像中应该是这样的分布情况: 2-o,4EfHVO
c******* u~LisZ&tP
aa**bbbb ex'd^y
dddddddd #Q 2$v;
>G'
NI?$
不知为什么会c和a放在一起,组成8位长度。