Intel和微软同时出现的C语言面试题 5b6s4ZyV
#pragma pack(8) 2`=6 %s
ib0g3p-Lc
struct s1{ #9LzY
short a; H2-28XGc
long b; @lUlY2
}; te4= S
VRW]a
struct s2{ AP\ofLmq
char c; v1.q$ f^(
s1 d; vG2b:[W
long long e; <39!G7ny
}; lKEa)KF[
(HN4g;{
#pragma pack() k,Zm GllQ]
p'{xoV
问 })IO#,
1.sizeof(s2) = ? Q:|w%L*E
2.s2的s1中的a后面空了几个字节接着是b? "MiD8wX-
p&K\]l}
Y+/lX 6'
R& =f:sEi
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: Cv=GZGn-
Ok%}|/P4
网友rwxybh(行云)的答案: t^tCA -
内存布局是 |@o6NZ<9N
1*** 11** xkA2g[
1111 **** `$z)$VuP
1111 1111 zSjgx_#U
- &[z\"T
所以答案就是24和3 ;</Twm;:
(w2=
2$
下面是一个测试的程序,试一试就知道了,我用的是VC2005 '?Iif#Z1
$rG<uO
#pragma pack(8) B">yKB:D}t
2#_38=K=@
struct s1{ 5`E))?*"Pe
short a; // 2 BYtes xUYow
long b; // 4 Bytes oaDsk<(j;R
}; /CT(k1>
struct s2{ *[kx F*^
char c; // 1 Byte [B?z1z8l
s1 d; // 8 Bytes f e
$Wu
long long e; // 8 Bytes O(OmGu4%
}; n!N\zx8
// 1*** 11** (3EUy"z-
// 1111 **** M'1HA
// 1111 1111 8HoP(+?
// qvLDfN
C 7nKk/r
// 00 01 02 03 04 05 06 07 !g0cC.'
// 00 01 02 03 04 05 06 07 XSB8z
// 00 01 02 03 04 05 06 07 GF--riyfB
// iY.eJlfH
#pragma pack() KC&`x|
+|C[-W7Sw
int main(int argc, char* argv[]) :J(sXKr[C
{ @PcCiGZ
s2 a; nJVp.*S
char *p = (char *)&a; MMD<I6Iyv
for(int i=0;i<24;++i) zd`=Ih2Wx
p = (char)(i%8); GzdgL"M[
printf("%d\n",sizeof(a)); .T3=Eq&"W
printf("c=0x%lx\n",a.c); Z%v6xP.
printf("d.a=0x%x\n",a.d.a); jFj~]]j
printf("d.b=0x%x\n",a.d.b); vg5NY =O
printf("e=0x%llx\n",a.e); U7%28#@
return 0; 4=p@2g2"H
} }#b
%"I0
结果: Y5jYmP<
24 If}lJ6jZ
c=0x0 ;1LG&h,K
d.a=0x504 KP~-$NR
d.b=0x3020100 i;lE5
e=0x706050403020100 &jJckT
=FBIrw{w
t]TyXAr~
网友 redleaves (ID最吊的网友)的答案和分析: )DZTB
pVOI5>f\
如果代码: ?*K<*wBw#
#pragma pack(8) ,ZK]i CGk
struct S1{ /{G/|a
char a; YhgUCF#
long b; d1NE% hg3
}; OKQLv+q5K)
struct S2 { KF{a$d
char c; `45d"B
I
struct S1 d; POBpJg
long long e; t&"5dM\
}; RWahsJTu
#pragma pack() B/Ba5z"r$
sizeof(S2)结果为24. HtzMDGV<
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. qWB%),`j>
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. q 22/_nSC
%}F"*.
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; xzK>Xi?
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. W#45a.v
a b 6`"ZsO
S1的内存布局:11**,1111, 4!2SS
c S1.a S1.b d f8!l7{2%q
S2的内存布局:1***,11**,1111,****11111111 %UmbDGDWI
;Prg'R[o;
这里有三点很重要: 2k3 z'RLG
1.每个成员分别按自己的方式对齐,并能最小化长度 FR' b`Xv:
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 s,
-*q}
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 EVSK8T,
|!5@xs*T
Y\u_+CG*
网友xue23(xue23) 的答案和分析: /.-m}0h|W-
@}G|R\2P
有程序查一下各个变量的内存地址得知: 6 ">oo-
各个变量在内存中的位置为 fMB4xbpD
c***aa** M+UMR+K
bbbb**** kh&_#,
dddddddd e3rfXhp
测试代码为: S&|VkZR)
s2 ss; td/5Bmj
cout << "ss.c = " << &ss << endl ; nCB[4
cout << "ss.d.a = " <<&ss.d.a << endl; 36i_D6
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; KW:r;BFx
print out 各个变量的内存地址不就可以看出来了吗。 y<uE-4
x9\J1\
所以答案是24,2. J=L`]XE
K-<n`zg3
但是我的想像中应该是这样的分布情况: ./)j5M
c******* J/gQQ.s
aa**bbbb (lb`#TTGx
dddddddd &U0WkW
r1hD
%a
不知为什么会c和a放在一起,组成8位长度。