Intel和微软同时出现的C语言面试题 DmuQE~DV
#pragma pack(8) _xh)]R
[q!]Ds"
_
struct s1{ Gn^lF7yE
short a; @br)m](@
long b; *w*K&$g
}; ,
p}:?uR
W+Mw:,>*s
struct s2{ xS12$ib ~G
char c; `K+%/|!
s1 d; su=MMr>
long long e; |s/N?/qi
}; Nkj$6(N=zJ
2! ,ndLA
#pragma pack() 9Jh&C5\\
#6|ve?`I
问 E3j`e>Yz
1.sizeof(s2) = ? P=,\wM6T|
2.s2的s1中的a后面空了几个字节接着是b? %!A:Ka!m.
!J;Bm,Xn6
ck0%H#BYY
6~0kb_td
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: cKkH*0B5
~L<"]V+B
网友rwxybh(行云)的答案: d'MZ%.#
内存布局是 <t(H+ykh
1*** 11** .^9khKJ;
1111 **** ),`jMd1`
1111 1111 ](R
/4
5<*ES[S
所以答案就是24和3 T.I'c6|
O@@nGSc@
下面是一个测试的程序,试一试就知道了,我用的是VC2005 #$S~QS.g
U=KUx
#pragma pack(8) PUO7Z2
5&p}^hS5
struct s1{ azIhp{rHw
short a; // 2 BYtes PQlA(v+S
long b; // 4 Bytes Tf5m
YCk
}; T:kliM"z
struct s2{ 4Us,DS_/
char c; // 1 Byte In?+
s1 d; // 8 Bytes v=G*K11@
long long e; // 8 Bytes S'|PA7a}h
}; o NA ]G]
// 1*** 11** g`'!Vgd?M[
// 1111 **** Brs6RkRf
// 1111 1111 ~fD\=- S1
// DTA$,1JuD
x f{`uHa8
// 00 01 02 03 04 05 06 07 F5:xrcyC
// 00 01 02 03 04 05 06 07 Sd^I>;
// 00 01 02 03 04 05 06 07 d.w]\
// z@e(y@
#pragma pack() s'N <
[!;sp~
int main(int argc, char* argv[]) ]'%
iR
{ ;Ngk"5
s2 a; g,iW^M
char *p = (char *)&a; ,rN$ah$CL
for(int i=0;i<24;++i) _Cz98VqRk
p = (char)(i%8); hfIP
printf("%d\n",sizeof(a)); }xr0m+/
printf("c=0x%lx\n",a.c); :I&y@@UG
printf("d.a=0x%x\n",a.d.a); _XP}fx7$C
printf("d.b=0x%x\n",a.d.b); mYo~RXKGF
printf("e=0x%llx\n",a.e); 7{M&9| aK
return 0; q M_c-^F
} X(E`cH
|
结果: #]1jvB
24 |)>+&
xk
c=0x0 %pxJ2 7Q
d.a=0x504 rlh:|#GTJ
d.b=0x3020100 y-H9fWi8Y&
e=0x706050403020100 kw z6SObQ
`,~'T [
T$0)un
网友 redleaves (ID最吊的网友)的答案和分析: A405igF
0#'MR.,
如果代码: g"'BsoJ
#pragma pack(8) zx8@4?bK
struct S1{ *^;
MWI
char a; M {'(+a[
long b; e^@ZN9qQ
}; Bt")RG
struct S2 { M1/(Xla3
char c; 'C7R*
P
struct S1 d; q90RTX'CY
long long e; DFZ0~+rh
}; 9xJtDdy-O
#pragma pack() 1l)j(,Zd*
sizeof(S2)结果为24. 7&P70DO
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. yy/'B:g
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Jjj;v2uSK
Ppl :_Of
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; Z>R@
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|+B8&-v
a b _nz_.w0H9
S1的内存布局:11**,1111, Pm^FSw"
c S1.a S1.b d 9 9:.j=
S2的内存布局:1***,11**,1111,****11111111 <<cezSm
`Mg3P_}=
这里有三点很重要: l v:GiA"X
1.每个成员分别按自己的方式对齐,并能最小化长度 'z}9BGR!
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度
ZaaBg
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 4w9=z,
/,~]1&?}1
,f)+|?wz
网友xue23(xue23) 的答案和分析: X6B,Mply
]vR
Ol.
有程序查一下各个变量的内存地址得知: ex~"M&^
各个变量在内存中的位置为 32 j){[PL3
c***aa** 0 5?`W&:9
bbbb**** /YPG_,lRA
dddddddd 8VU(+%X
测试代码为: WQCnkP
s2 ss; &m36h`tM
cout << "ss.c = " << &ss << endl ; POl-S<QV
cout << "ss.d.a = " <<&ss.d.a << endl; E[ -yfP~[
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; C%<Dq0j
print out 各个变量的内存地址不就可以看出来了吗。 aLLI\3
pheu48/f
所以答案是24,2. 1Ci^e7|?
]QY-LO(
但是我的想像中应该是这样的分布情况: =ePwGm1:c
c******* z7?SuJ
aa**bbbb yMkR)HY
dddddddd -@w}}BR
d^~yUk
不知为什么会c和a放在一起,组成8位长度。