Intel和微软同时出现的C语言面试题 juB /?'$~
#pragma pack(8) Lklb
Bpp(5
struct s1{ WDF6.i ?
short a; ]F
srk
long b; Q*8efzgs|
}; Ws:+P~8
7T?T0x3>
struct s2{ MCTTm^8O
char c; ?OC&=}
s1 d; d RHw]!.
long long e; mw*KLMo42
}; Erm]uI9`
:nS p
#pragma pack() VLC=>w\,
Cf.(/5X
问 h3V;
J
1.sizeof(s2) = ? naM=oSB(
2.s2的s1中的a后面空了几个字节接着是b? K_-S`-eH
~vKDB$2
WD|pG;Gq
wLKC6@
W
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: v*^'|QyM7
&XB1=b5
网友rwxybh(行云)的答案: r
TK)jxklX
内存布局是 @Uqcym.
1*** 11** K<p)-q
1111 **** JnS@}m
1111 1111 F@1Eg
T1uOp5_]B
所以答案就是24和3 CJt(c,!z
QLb!e"C
下面是一个测试的程序,试一试就知道了,我用的是VC2005 QxiAC>%K
M<xF4L3]
#pragma pack(8) v
K!vA-7
"cGjHy\j`
struct s1{ HJ!P]X_J1
short a; // 2 BYtes \iAs
long b; // 4 Bytes C,,S<=L:
}; B1va]=([)W
struct s2{ 07>Iq8<mu
char c; // 1 Byte H'jo3d~+
s1 d; // 8 Bytes F+9(*|x%
long long e; // 8 Bytes ^\w!D{Y7Q
}; ye`-U?7.
// 1*** 11** 4#ZZwa]y
// 1111 **** u(g9-O
// 1111 1111 8:k-]+#o
// V BjA$.
4B@Ir)^(*
// 00 01 02 03 04 05 06 07 >uwd3XW5
// 00 01 02 03 04 05 06 07 4)d"}j
// 00 01 02 03 04 05 06 07 +krDmU9(
// [ N0"mE<
#pragma pack() (4IH%Ez){
A5,(P$@k
int main(int argc, char* argv[]) s[}cj+0
{ afye$$X
s2 a; (
\7Yo^
char *p = (char *)&a; B dxV [SF
for(int i=0;i<24;++i) DS=Dg@y
p = (char)(i%8); BoofJm
printf("%d\n",sizeof(a)); gNSsT])
printf("c=0x%lx\n",a.c); R
RnT.MU
printf("d.a=0x%x\n",a.d.a); yAu.=Eo7
printf("d.b=0x%x\n",a.d.b); +z+u=)I
printf("e=0x%llx\n",a.e); F<(?N!C?@
return 0; vO8CT-)
} Oox,4&
结果: Duq.`XO
24 $;j{?dvm.
c=0x0 TTo5"r9I8
d.a=0x504 [ip}f4K
d.b=0x3020100 TchByN6oN<
e=0x706050403020100 |qtZb}"|
J+YoAf`hi
D3x
W?$Z
网友 redleaves (ID最吊的网友)的答案和分析: rXVRX#Lh
-!X\xA/KN
如果代码: Ee'wsL
#pragma pack(8)
iM"L%6*I^
struct S1{ ?A~a}bFZ
char a; v+
"9&
long b; +uMK_ds~
}; Q`BB@E
struct S2 { cL:hjr"
char c; 3j w4#GW
struct S1 d; yi,Xs|%.
long long e; bqRO-\vO
}; '|nAGkA
#pragma pack() K4^mG
sizeof(S2)结果为24. )gNVJ
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. r_3=+
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Y{2L[5_1
%
r0AhWv
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; Hf9F:yH
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. zJG=9C?
a b 5>&C.+A 9
S1的内存布局:11**,1111, ^']*UD;
c S1.a S1.b d td|O #R
S2的内存布局:1***,11**,1111,****11111111 [wcp2g3Px
;D}E/'=
这里有三点很重要: w>&g'
1.每个成员分别按自己的方式对齐,并能最小化长度 RNb" O{3
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 PRN%4G
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 .%_=(C<E
rG{,8*
TTz_w-68
网友xue23(xue23) 的答案和分析: [+b&)jN*2
c)zwyBz
有程序查一下各个变量的内存地址得知: Z)G@ahOQ
各个变量在内存中的位置为 77;|PKE /
c***aa** `,)%<}
bbbb**** M$2lK^2L
dddddddd @T~~aQFk
测试代码为: r8Z}
mvLM
s2 ss; 'Jl73#3
cout << "ss.c = " << &ss << endl ; t#=FFQOt
cout << "ss.d.a = " <<&ss.d.a << endl; 5Pd^Sew
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; #LfoG?k1K
print out 各个变量的内存地址不就可以看出来了吗。 D*!9K8<o
%SwhNn
所以答案是24,2. DTCOhUIV
m]/sR3yF
但是我的想像中应该是这样的分布情况: =xM:8
hm
c******* vp`s< ;CA
aa**bbbb YI),yj
dddddddd #80M+m
nfS.0\z
不知为什么会c和a放在一起,组成8位长度。