Intel和微软同时出现的C语言面试题 j!dklQh0
#pragma pack(8) ,\7okf7H,-
N~(}?'y9S
struct s1{ g9JtWgu
short a; fM{Vy])J
long b; ?K"]XXsI
}; jF8ld5|_|
@P?*<b{
struct s2{ ^D)C|T
char c; %94"e7Hy
s1 d; #oI`j
q
long long e; '%N
p9Iqt
}; N1rrKyL!$
COafVlJ,l
#pragma pack() c9@*
wSDDejg
问 E
J1:N*BA
1.sizeof(s2) = ? *KAuyJr
2.s2的s1中的a后面空了几个字节接着是b? rxA<\h,A
P^UcpU,
uJizR
F
nYY U
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: j#,O,\
tp"\
网友rwxybh(行云)的答案: e_SlM=_u
内存布局是 _+i-)
1*** 11** E_P]f%
1111 **** BKk*<WMD
1111 1111 tq[C"| dH
Up:#Zs2
所以答案就是24和3 = j -
U,N4+F}FR
下面是一个测试的程序,试一试就知道了,我用的是VC2005 [}D)73h`
eYFCf;
#pragma pack(8) %?seX+ne
dO2cgY}
struct s1{ EHOdst
short a; // 2 BYtes M6>l%[
long b; // 4 Bytes yd k
}; @gd-lcMYW
struct s2{ PNq#o%q
char c; // 1 Byte f!<mI8H
s1 d; // 8 Bytes Kmtr.]Nj
long long e; // 8 Bytes lU?"\m
}; 1EN5ZN,
// 1*** 11** v|e>zm<
// 1111 **** I`|>'$E[r
// 1111 1111 Ua4} dW[w
// 1D$k:|pP~
Z'E@sc 9
// 00 01 02 03 04 05 06 07 9iUw7-)
// 00 01 02 03 04 05 06 07 Uvp?HZ\Z
// 00 01 02 03 04 05 06 07 Q]\xO/
// 'EQAG' YV
#pragma pack() =vWnqF:
^U1;5+2G+~
int main(int argc, char* argv[]) shD$,!
k
{ >z2{D7
s2 a; -v:Y\=[\
char *p = (char *)&a; ${?Px
c{-
for(int i=0;i<24;++i) ZISR]xay
p = (char)(i%8); ,AJd2i x
printf("%d\n",sizeof(a)); OA8pao~H
printf("c=0x%lx\n",a.c); m$kmoY/
printf("d.a=0x%x\n",a.d.a); x?k6ek
printf("d.b=0x%x\n",a.d.b); *oF{ R^
printf("e=0x%llx\n",a.e); V1+IqOXAIp
return 0; 9wYbY* j
} =J:~AD#
结果: y
Le5,
24 :sf;Fq
c=0x0 ixp %aRRP
d.a=0x504 ;J4_8N-
d.b=0x3020100 ]b[3 th*
e=0x706050403020100 }.Ug`7%G
%V$^CWOy
(wTg aV1
网友 redleaves (ID最吊的网友)的答案和分析: R75sK(oS
54k
Dez
如果代码: It4F;Ah
#pragma pack(8) {uw]s<
6
struct S1{ tlW}lN}
char a; )TxhJB5|
long b; KS%,N _F<
}; DP?gozm
struct S2 { >uVG]
char c; F$caKWzny5
struct S1 d; __a9}m4i7x
long long e; zUOYH4+
}; 4:K9FqU
#pragma pack() }\9qN! ol
sizeof(S2)结果为24. Q5Wb)
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. ]UNmhF!W>u
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 5EU3BVu&u
B%,0zb+-L
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; AojX)_"z
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节.
;HW@ZI
a b A;%fAI2Vr
S1的内存布局:11**,1111, 'RPe5 vB
c S1.a S1.b d J[^-k!9M
S2的内存布局:1***,11**,1111,****11111111 uQ{M<%K
J^u{7K,
这里有三点很重要: v"^G9u
1.每个成员分别按自己的方式对齐,并能最小化长度 [ [Z*n/tr
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 $+Xohtt
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 J~~WV<6
Alrk3I3{
zfS`@{;F`|
网友xue23(xue23) 的答案和分析: H#f
FU
,i'>+Ix<
有程序查一下各个变量的内存地址得知: ?O28Q DUI
各个变量在内存中的位置为 |d{4_o90
c***aa** FvRog<3X
bbbb****
w*aKb
dddddddd d
hh`o\$
测试代码为: 1v`*%95
s2 ss; _- { > e
cout << "ss.c = " << &ss << endl ; NZv1dy`fa
cout << "ss.d.a = " <<&ss.d.a << endl; &Y\`FY\
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; &L_(yJ~-
print out 各个变量的内存地址不就可以看出来了吗。 . }^m8PP
vzfWPjpKW
所以答案是24,2. Nkc=@l{
|_Vlw&qu+
但是我的想像中应该是这样的分布情况: f-
_~rQ
c******* \h :$q E7
aa**bbbb UF?qL1w
dddddddd m'Ran3rp
b8Y-!]F
不知为什么会c和a放在一起,组成8位长度。