Intel和微软同时出现的C语言面试题 s^/2sjoL
#pragma pack(8) nQG<OVRClS
;VbB]aUg
struct s1{ }*7Gq
short a; 3w+ +F@(
long b; Gg%pU+'T
}; ?_.
SV g
Pxgal4{6
struct s2{ r|ogF8YN
char c; x)f<lZ^L&H
s1 d; '~xiD?:
long long e;
g ~%IA.$c
}; Or-LQ^~
b2~5 LZ
#pragma pack() ix 5\Y
DO~~
问 LftzW{>gI"
1.sizeof(s2) = ? F /"lJ/I
2.s2的s1中的a后面空了几个字节接着是b? /Ur]U
w
$LtCI
B X O,
3Q_)Xs
r`
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: 8cj}9}k
)Zrn?KM
网友rwxybh(行云)的答案: 35YDP|XZb
内存布局是 0VIR=Pbp
1*** 11** vSk1/
1111 **** S0;s
7X#c
1111 1111 cK'}+
;s5JYR
所以答案就是24和3 I3 YSW
3
op{h6
下面是一个测试的程序,试一试就知道了,我用的是VC2005 N^jr
;B;wU.Y"
#pragma pack(8) ?*cCn-|
~ _ko$(;A
struct s1{ && WEBQ
short a; // 2 BYtes S*H
@`Do%d
long b; // 4 Bytes \_/dfmlIZ
}; MFqb_q+
struct s2{ 3*oZol/
char c; // 1 Byte "}:SXAZ5`
s1 d; // 8 Bytes :PBW=W
long long e; // 8 Bytes 4"Mq]_D
}; LKst
QP!I
// 1*** 11** 'Kd-A:K2g
// 1111 **** dRBWJ/ 1T
// 1111 1111 COA>y?
// 8/-hODoT_
5B;;{GR
// 00 01 02 03 04 05 06 07 Y7 e1%,$v
// 00 01 02 03 04 05 06 07 _] us1
// 00 01 02 03 04 05 06 07 (_fovV=
// aQ0pYk~(
#pragma pack() ](z*t+">
,6x>gcR
int main(int argc, char* argv[]) RF'&.RtVa
{ B%z+\<3^q
s2 a; l2kUa'O-
char *p = (char *)&a; 5PE}3he:
for(int i=0;i<24;++i) iT</
p = (char)(i%8); RIFTF
R
printf("%d\n",sizeof(a)); LPkl16yZ
printf("c=0x%lx\n",a.c); |^gnT`+
printf("d.a=0x%x\n",a.d.a); Bm&6
printf("d.b=0x%x\n",a.d.b); ;t4YI7E*
printf("e=0x%llx\n",a.e); (.kzJ\x
return 0; HaQox.v%
} ccy q~
结果: .v['INK9
24 ^_uCSA'X
c=0x0 Ce} m_
d.a=0x504 B\+uRiD8w
d.b=0x3020100 U=[isi+7
e=0x706050403020100 k!d<2Qp W
5)ooE
0*6Q8`I
网友 redleaves (ID最吊的网友)的答案和分析: $rPQ%2eF4
~F>'+9?Sn
如果代码: dAi.^! !
#pragma pack(8) q<4{&omUJ
struct S1{ n39EKH rm%
char a; ?)7UqVyq
long b; t<e3EW@>>
}; @su!9 ]o
struct S2 { ]6,D9^{;
char c; @I?:x4
struct S1 d; &5hs
W1`
long long e; D{JwZL@7k2
}; v(P <_}G
#pragma pack() =:\5*
sizeof(S2)结果为24. T5wVJgN>
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 0+AMN-
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. X=Jt4 h9
dEam|
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; sk@aOv'*(
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. d"thM
a b nY,LQ0r
S1的内存布局:11**,1111, |Gr@Mi5
c S1.a S1.b d AsI.8"
S2的内存布局:1***,11**,1111,****11111111 c!mMH~#
WnA
Y<hZ|
这里有三点很重要: =Ea,8bpn
1.每个成员分别按自己的方式对齐,并能最小化长度 {8,_[?H
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 Pav
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 SME]C ')7
c,#Nd@
@[{5{ y
网友xue23(xue23) 的答案和分析: rVp^s/A^;
@?&
i
有程序查一下各个变量的内存地址得知: (t,mtdD#1
各个变量在内存中的位置为 :0Fc E,1
c***aa** ;Pvnhy
bbbb**** 18]Q4s8E
dddddddd 8tzL.P^
测试代码为: a >k9&
w
s2 ss; yGH')TsjD
cout << "ss.c = " << &ss << endl ; +P.JiH`\=
cout << "ss.d.a = " <<&ss.d.a << endl; l`a_0
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; "e/"$z'ca
print out 各个变量的内存地址不就可以看出来了吗。 =`l><
ovaX_d)cU
所以答案是24,2. \!*F:v0g^
)))AxgM
但是我的想像中应该是这样的分布情况: ?',Wn3A
c******* \\35}
9
aa**bbbb XnRm9%
dddddddd ^=qV)j
Omph(
不知为什么会c和a放在一起,组成8位长度。