Intel和微软同时出现的C语言面试题 Y={&5Mir
#pragma pack(8) QIN."&qC^
I)q,kP@yY
struct s1{ _LAS~x7,
short a; HkV1sT
long b; IX: 25CEI2
}; 2)#K+O3c
8Y0"Cejq
struct s2{ }pk#!N
char c; yc2/~a_Gx
s1 d; <PPNhf8
long long e; wxm:7$4C
}; tx"sH]n
lnovykR
#pragma pack() ;U1UFqZ`
kyAXRwzI
问 O3N0YGhJ
1.sizeof(s2) = ? I$Qs;- (
2.s2的s1中的a后面空了几个字节接着是b? 5qg2Zc~
+jg9$e "
JOjoiA
5Zmw} M
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: oLWJm
<APB11
网友rwxybh(行云)的答案: nf1#tlIJd
内存布局是 IchCACK
1*** 11** ,f}UGd[a
1111 **** ug{R 3SS
1111 1111 hjO*~
WwC 5!kZ
所以答案就是24和3 2([2Pb3<"
vHAg-Avc
下面是一个测试的程序,试一试就知道了,我用的是VC2005 7iHK_\t n
2L AYDaS
#pragma pack(8) V`adWXu
h8\
T
struct s1{ th6+2&B6
short a; // 2 BYtes Qn ^bVhG+
long b; // 4 Bytes o7B[R) 4
}; 5L:1A2Z?c
struct s2{ |AlR^N
char c; // 1 Byte yNm:[bOER
s1 d; // 8 Bytes Z5c~^jL$-
long long e; // 8 Bytes /h v4x9
}; k3+e;[My+
// 1*** 11** >7!6nF3x,
// 1111 **** tb:L\A^:
// 1111 1111 %Pksv}
// l5+gsEux]
izKfU?2]X@
// 00 01 02 03 04 05 06 07 t_ksvWUo
// 00 01 02 03 04 05 06 07 _k^0m
// 00 01 02 03 04 05 06 07 Q]rD}Ckv-
// b 1&i# I?{
#pragma pack() K^_i%~
9]t[J_YM
int main(int argc, char* argv[]) BmHwu{n'
{ tO_H!kP
s2 a; +(uYwdcN
char *p = (char *)&a; F}"] 92
for(int i=0;i<24;++i) 2F%W8Y3
p = (char)(i%8); j)t+jcMUI
printf("%d\n",sizeof(a)); &z"krM]G
printf("c=0x%lx\n",a.c); jCTAKaq
printf("d.a=0x%x\n",a.d.a); +0),xu
printf("d.b=0x%x\n",a.d.b); ;['[?wk
printf("e=0x%llx\n",a.e); 0&ByEN99
return 0; @!&}}"<
} *9)SmSs
结果: b3wM;jv
24 {JV@"t-X3"
c=0x0 o]IjK
d.a=0x504 IVr 2y8K
d.b=0x3020100 >NB?&|
e=0x706050403020100 %4\OPw&
9WJz~SP+vR
E~<`/s
网友 redleaves (ID最吊的网友)的答案和分析: IrMl:+t\
RE.r4uOJg
如果代码: 9Lh|DK,nV/
#pragma pack(8) Le"oAA#[
struct S1{ syip; ;
char a; lnE+Au'
long b; -@>BHC
}; Jc)^49Rf
struct S2 { U/lM\3v/e
char c; nA?Hxos
struct S1 d; zrVC8Wb
long long e; 6h3HDFS7s
}; 6Es?
MW=
#pragma pack() T32BnmB{
sizeof(S2)结果为24. y8VpFa
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. Q-#$Aa
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. l{w#H|]
smG>sEp2
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; _2b tfY1U
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. 1b8p~-LsU
a b iJnU%
S1的内存布局:11**,1111, uP\lCqK,
c S1.a S1.b d iqnJ~g
S2的内存布局:1***,11**,1111,****11111111 Knhp*V?
q9"=mO0J+
这里有三点很重要: ,]}?.g
1.每个成员分别按自己的方式对齐,并能最小化长度 >:=|L%]s;\
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 ]d[ge6
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 lyCW=nc
y/V%&.$o=
GRy-+#,b"
网友xue23(xue23) 的答案和分析: =66Nw(E.
E&Qi@Ty
有程序查一下各个变量的内存地址得知: pj?XLiM54%
各个变量在内存中的位置为 0?WcoPU
c***aa** +h2eqNr
bbbb**** -/]W+[
dddddddd t>B^q3\q?
测试代码为: zo;^m|
s2 ss; J8y0d1SG
cout << "ss.c = " << &ss << endl ; \,!QJp4
cout << "ss.d.a = " <<&ss.d.a << endl; \.XLcz
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; 2cu#lMq
print out 各个变量的内存地址不就可以看出来了吗。 HE<1v@jW
,:+dg(\r
所以答案是24,2. ,wKe
fpV;5
"l={)=R
但是我的想像中应该是这样的分布情况: vaf&X]p
c******* )'l*Tl
aa**bbbb A?G IBjs
dddddddd 4`#F^2r!
?)'~~@NkH
不知为什么会c和a放在一起,组成8位长度。