Intel和微软同时出现的C语言面试题 lS@0 $
#pragma pack(8) ?YE'J~0A6
-#<6
struct s1{ v:\8
short a; 4/KGrY!ck
long b; KuBN_bd
}; 4'3do>!
loRT+u$&
struct s2{ H<_BnT#
char c; 0RHKzk6~c
s1 d; ` 9;0Y
long long e; A*+pGQ
}; qt_ocOr
#1Zqq([@
#pragma pack() T_t5Tg~i[N
aQ!QrTua-
问 7LEB,bU
1.sizeof(s2) = ? 9mE6Cp.Wv
2.s2的s1中的a后面空了几个字节接着是b? LSewMj
MoAie|MKe
jr/
#(@!:f1
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: h/oRWl0r
X0:V5
e
网友rwxybh(行云)的答案: sX8d8d`}
内存布局是 Xir ERc.e
1*** 11** OBb m?`[
1111 **** z<_&4)2{
1111 1111 s;brs}
1Vf?Rw
所以答案就是24和3 v
C23
HQp \0NC]
下面是一个测试的程序,试一试就知道了,我用的是VC2005 D;nd_{%
$4>(}
#pragma pack(8) k1lo{jw`
NS<C"O
struct s1{ :1*q}R
short a; // 2 BYtes vEy0DHEE
long b; // 4 Bytes ML _$/
}; ATQw=w
3W
struct s2{ Borr
char c; // 1 Byte TWzlF>4N
s1 d; // 8 Bytes T`?7z+2A
long long e; // 8 Bytes * 'eE[/K
}; Clz.
p
// 1*** 11** is~"yE7
// 1111 **** #|PPkg%v<
// 1111 1111 7MWd(n-
// J.EBt3
G]]"Jc
// 00 01 02 03 04 05 06 07 n!aA<
// 00 01 02 03 04 05 06 07 P"(VRc6x
// 00 01 02 03 04 05 06 07 45.<eWH$*(
// }Q2v~eD
#pragma pack() 7xF)\um
18^#:=Z
int main(int argc, char* argv[]) U
g:
{ ?F6L,
s2 a; r` B(ucE
char *p = (char *)&a; D`|8Og
for(int i=0;i<24;++i) $e~MKLd
p = (char)(i%8); N#``(a
printf("%d\n",sizeof(a)); ?rm3Iac0S
printf("c=0x%lx\n",a.c); _:N=
printf("d.a=0x%x\n",a.d.a); eOoqH$
i
printf("d.b=0x%x\n",a.d.b); tJG+k)EE
printf("e=0x%llx\n",a.e); g6
H}a
return 0; mjQZ"h0
} 3S 5`I9I
结果: ! k[JP+;
24 *{_N*p\{
c=0x0 ^h$^j
d.a=0x504 b(IZ:ekZ5
d.b=0x3020100 (himx8Uml2
e=0x706050403020100 <x8I<K
&4O2uEW0
YpOcLxFL
网友 redleaves (ID最吊的网友)的答案和分析: 5cvvdO*C0
H#S`m
如果代码: Y\,aJL$
#pragma pack(8) ["O_Phb|
struct S1{ ZveNe~D7C
char a; `q9n`h1
long b; 8J#U=qYei
}; /[=Yv!
struct S2 { .@Lktc
char c; +v2)'?BS
struct S1 d; ^w!1QH0:/
long long e; _/czH<
}; Y{Ff I+
#pragma pack() 9u6VN]divB
sizeof(S2)结果为24. f, '*f:(
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. cR{F|0X
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Z%Pv,h'Q
zfD@/kU
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; &cWC&Ws"
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. GlHP`&;UH
a b mm9uhlV8
S1的内存布局:11**,1111, =F2`X#x_j
c S1.a S1.b d {2%'=v
S2的内存布局:1***,11**,1111,****11111111 _l"=#i@L
rB|1<jR
这里有三点很重要: pO/vD~C>
1.每个成员分别按自己的方式对齐,并能最小化长度 fN1b+d~*6
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 Vx}e,(i
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 ddS3;Rk2
$bDaZGy
}[{9u#@#
网友xue23(xue23) 的答案和分析: O14\_eAu6
A<]
$[2qPj
有程序查一下各个变量的内存地址得知: ?y]R /?
各个变量在内存中的位置为 !|W.YbS
c***aa** eslvg#Q
bbbb****
_!_^B
dddddddd 'yosDT2{#
测试代码为: Hd\.,2a"
s2 ss; f}~=C2R1<!
cout << "ss.c = " << &ss << endl ; Q#X'.](1
cout << "ss.d.a = " <<&ss.d.a << endl; <O1os"w
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; xk
print out 各个变量的内存地址不就可以看出来了吗。 3RX9LJGX
0h~{K
所以答案是24,2. !{4'=+
)7{r8a
但是我的想像中应该是这样的分布情况: pw&k0?K#
c******* ym p
ik.'
aa**bbbb .l hS
dddddddd ,1g_{dMx
?@z/#3b
不知为什么会c和a放在一起,组成8位长度。