Intel和微软同时出现的C语言面试题 ?)V}_%fVv
#pragma pack(8) _rjLCvv-
r]'Q5l4j6"
struct s1{ I!uGI
short a; 1?5UVv_F
long b; n^7m^1to
}; W99Hq1W;r
xFy%&SKHg
struct s2{ 08JVX'X-mr
char c; .vJt&@NO
s1 d; cA]Ch>]A%
long long e; >(:b\*C
}; qc6eqE
At=l>
#pragma pack() 2W]y9)<c
qtLXdSc
问 vspub^;5\
1.sizeof(s2) = ? 8
y+N l&"V
2.s2的s1中的a后面空了几个字节接着是b? [osm\w49
'-k~qQk)6
?B`Yq\L)
.ugQH<B
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: Yt%
E,U~g
ZUxlk+o9d
网友rwxybh(行云)的答案: !ii'hwFm$
内存布局是 O)i]K`jk
1*** 11** </B5^}
1111 **** Jb4A!g5C
1111 1111 Z/>0P* F
*)H&n>"e
所以答案就是24和3 Vn1hr;i]
7gY^a MW
下面是一个测试的程序,试一试就知道了,我用的是VC2005 d[Lr`=L;
,)JSXo
#pragma pack(8) 2r~&+0sBP
t4E=
struct s1{ N2_9V~!
short a; // 2 BYtes YDMimis\H5
long b; // 4 Bytes Jxy94y*
}; b 7%O[
struct s2{ l-mf~{
char c; // 1 Byte ~0~f
s1 d; // 8 Bytes OK"B`*
long long e; // 8 Bytes :5M7*s)e16
}; ]{<`W5b/
// 1*** 11** @xI:ZtM
// 1111 **** F]SA1ry
// 1111 1111 0u'qu2mV
// +Eh^j3W
Cp@'
k;(
// 00 01 02 03 04 05 06 07 mtON
dI
// 00 01 02 03 04 05 06 07 )KLsa`RV:
// 00 01 02 03 04 05 06 07 %4Thb\ T
// URFp3 qE
#pragma pack() ]O\Oj6C
&
M wvj
int main(int argc, char* argv[]) :z!N_]t
{ -^sbf.
s2 a; 9(/ ;Wutj"
char *p = (char *)&a; :uD*Q/
for(int i=0;i<24;++i) #*<*|AwoW|
p = (char)(i%8); AGN5=K*D
printf("%d\n",sizeof(a)); d:"]*EZ [
printf("c=0x%lx\n",a.c); NZyGC
Vh@
printf("d.a=0x%x\n",a.d.a); }(r%'(.6
printf("d.b=0x%x\n",a.d.b); 6O>GVJbw
printf("e=0x%llx\n",a.e); fiq4|!^h
return 0;
]OZk+DU:
} %;E/{gO
结果: =k1 ,jn+
24 d,G:+
c=0x0 vNhi5EU
d.a=0x504 @L-3&~=
d.b=0x3020100 O,kzU,zOs
e=0x706050403020100 6eqPaIaD
9N [PZD
hK,e<?N^
网友 redleaves (ID最吊的网友)的答案和分析: HCI|6{k
xnW3,:0
如果代码: \p-3P)U
#pragma pack(8) 4Em mh=A
struct S1{ X&[S.$_U
char a; $`Z-,AJc
long b; AAr[xoiYp
}; 3YG[~o|4
struct S2 { PSO9{!
char c; ^qaS
struct S1 d; pb(YA/
long long e; \tj7Jy
}; &;%z1b>F
#pragma pack() o
26R]
sizeof(S2)结果为24. 0Jh^((i*
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 1XAXokxj
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Gyak?.@R
:K ^T@F5n
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; =7JvS~s
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. s0 ZF+6f
a b J2$L[d^
S1的内存布局:11**,1111, +P?!yH,n
c S1.a S1.b d >[=fbL@N<@
S2的内存布局:1***,11**,1111,****11111111 ^
2"r't
nVF?.c
这里有三点很重要: RnN]m!"5
1.每个成员分别按自己的方式对齐,并能最小化长度 JM-spi o
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 cY|?iEVs)
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 pcd*K)
ymdZ#I-
$r`^8/Mq3
网友xue23(xue23) 的答案和分析: JC~L!)f
j9@7\N<
有程序查一下各个变量的内存地址得知: 0,a;N%K-
各个变量在内存中的位置为 +!'\}"q
c***aa**
G[}$s7@k
bbbb**** [i18$q5D
dddddddd HJVi:;o
测试代码为: phu`/1;p
s2 ss; @_Ko<fKSX
cout << "ss.c = " << &ss << endl ; "lcNjyU\O
cout << "ss.d.a = " <<&ss.d.a << endl; ZqhCGHy
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; #,0PLU3%
print out 各个变量的内存地址不就可以看出来了吗。 YRXXutm
+*2 ]R~"M
所以答案是24,2. $niJw@zC
zI5#'<n
但是我的想像中应该是这样的分布情况: Zl69d4vG
c******* }fps~R
aa**bbbb CbmT aEaP
dddddddd /DG+8u
?v4-<ewD
不知为什么会c和a放在一起,组成8位长度。