Intel和微软同时出现的C语言面试题 ::p-9F
#pragma pack(8) %3]3r*e&5
Sp<hai
struct s1{ 1zdYBb6;j
short a; \1=T
sU&^
long b; ~ GNyE*t/Y
}; GYFgEg}
k
TF z_*6.
struct s2{ .[edln
char c; pO\S#GnX
s1 d; re7!p(W?,
long long e; b0r,h)R
}; zSEr4^Dk4
8lMZ
#pragma pack() YH6snC$u
H"2 U)HJl
问 Q<z)q<e
1.sizeof(s2) = ? *
zd.
2.s2的s1中的a后面空了几个字节接着是b? a^@+%?X
MNkKy(Za
'"Bex`
Zn?8\
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: }phz7N9
OZ eiHX!
网友rwxybh(行云)的答案: 8r2XGR
内存布局是 ,yTN$K%M
1*** 11** {;U} :Dx
1111 **** w+Ad$4Pf"
1111 1111 D*|(
p6v1&
-s{R/ 6:
所以答案就是24和3 [Dnusp7e
RI?NB6U
下面是一个测试的程序,试一试就知道了,我用的是VC2005 aLV~|$:2
cB{%u
'
#pragma pack(8) %rFP#L
}%_qx|(P|t
struct s1{ .8-PB*vb
short a; // 2 BYtes )8:n}w
long b; // 4 Bytes K3Huu!Tr
}; [0K=I64
z
struct s2{ 7}gA0fP9
char c; // 1 Byte Q?Wr7
s1 d; // 8 Bytes ,Yo: &>As
long long e; // 8 Bytes baqn7k"
}; 7^HpVcSM
// 1*** 11** rZ pbu>S
// 1111 **** C=8H)Ef,l
// 1111 1111 cvxIp#FbW
// ,&0Z]*
L+_8QK <
// 00 01 02 03 04 05 06 07 Xu6jHJ@ x
// 00 01 02 03 04 05 06 07 Xz8$Xz,O
// 00 01 02 03 04 05 06 07 <|otZJ'2r
// $,!hD\a
#pragma pack() p#)e:/Qy
,Ie<'>hd
int main(int argc, char* argv[]) bG52s
{ ~Hs=z$
s2 a; cnbo+U
char *p = (char *)&a; fH&zR#T7U4
for(int i=0;i<24;++i) 'wa g |-
p = (char)(i%8); ubD#I{~J
printf("%d\n",sizeof(a)); %@>YNPD`E
printf("c=0x%lx\n",a.c); ACgt"
M.3F
printf("d.a=0x%x\n",a.d.a); $\+"qs)
printf("d.b=0x%x\n",a.d.b); Tu==49
printf("e=0x%llx\n",a.e); D^$]>-^
return 0; gEE9/\>%-
} ,dOMW+{
结果: T{ok +$w2
24 nz>K{(
c=0x0 iL+y(]
d.a=0x504 f;R>Pr;rD
d.b=0x3020100 P>|Ef~j
e=0x706050403020100 $kv@tzO
^[0"vtb
(Bsw/wv
网友 redleaves (ID最吊的网友)的答案和分析: STw oYn
y`({ .L
如果代码: }N@n{bu+
#pragma pack(8) f KHse$?_
struct S1{ 3=IG#6)~C
char a; $%B5$+
long b; _n7%df
}; <H!O:Mf_p
struct S2 { ~bWhth2*
char c; JXL'\De ;
struct S1 d; )t5;d
long long e; >n(F4C-pl
}; s~=g*99H
#pragma pack() KLW&bJ$|j
sizeof(S2)结果为24. S3QaYq"v
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. R#D#{cC(
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Y!F!@`%G
'bl%Y).9w
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; hc"6u\>
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. <M=';h^w2
a b GZ
<nXU>
S1的内存布局:11**,1111, W|0My0y
c S1.a S1.b d sSNCosb
S2的内存布局:1***,11**,1111,****11111111 ) ,yH= 6
IOX:yxj
这里有三点很重要: @bE~@4mOu
1.每个成员分别按自己的方式对齐,并能最小化长度 3Qa?\C&4
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 8+&gp$a$
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 2!BsEvB(
gXF.on4B
/ xs9.w8-
网友xue23(xue23) 的答案和分析: 7pz\ScSe
G#|Hu;C6"
有程序查一下各个变量的内存地址得知: K0LbZMn,/
各个变量在内存中的位置为 .5]{M\aA
c***aa** 4'` C1 a
bbbb**** X'jr|s^s
dddddddd _%;M9Sg3
测试代码为: 3h LqAj
s2 ss; \<=IMa0
cout << "ss.c = " << &ss << endl ; C>NQ-w^
cout << "ss.d.a = " <<&ss.d.a << endl; oikxg!0S
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; Et.j1M|g
print out 各个变量的内存地址不就可以看出来了吗。 ~oo'ky*H!
J+lGh9G
所以答案是24,2. z$66\/V']
=D}4X1l
但是我的想像中应该是这样的分布情况: ~x\Cmu9`
c******* Z~_8P
aa**bbbb g9`[Y~
dddddddd YQ+^
loBtd%wY
不知为什么会c和a放在一起,组成8位长度。