Intel和微软同时出现的C语言面试题 ef'kG"1
#pragma pack(8) ep8UWxB5
q7CLxv
&QG
struct s1{ pLu5x<
short a; LVUA"'6V
long b; !$NK7-
}; ozY$}|sjDT
H^'%$F?Ss
struct s2{ G&h@
char c; F:jNv3W1
s1 d; _n:RA)4*
long long e; >a975R*g
}; \:@6(e Bh
_OGv2r
#pragma pack() qlM<X?
o}=*E
问 P].Eb7I
1.sizeof(s2) = ? E{)X ;kN=
2.s2的s1中的a后面空了几个字节接着是b? 4rDVCXE
huZ5?'/Fg
!Ge;f/@
S:{xx`6K
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: e#hg,I
O1\4WG%
网友rwxybh(行云)的答案: 5@RcAQb:
内存布局是 (c0L@8L
1*** 11** *-ys}sX
1111 **** T @^ S:K
1111 1111 %f<>Kwr`2
GJWGT`"
所以答案就是24和3 `a52{Wa
Ab[o~X"
下面是一个测试的程序,试一试就知道了,我用的是VC2005 jwjLxt
;HCK iHC
#pragma pack(8) jUD^]Qs
vVMoCG"f
struct s1{ m$C1Ea-wnT
short a; // 2 BYtes ^zTe9:hz/\
long b; // 4 Bytes &w9*pJR %
}; 8AW}7.<5
struct s2{ v#gXXO[P1
char c; // 1 Byte I:t?# )wl
s1 d; // 8 Bytes ^/2HH
long long e; // 8 Bytes gdCit-3
}; H*G(`Zl}
// 1*** 11** }bRn&)e
// 1111 **** CA|l|
t^
// 1111 1111 u3Z]!l
// [f:&aS+
+\["HS7+'0
// 00 01 02 03 04 05 06 07 Pek[j)g}
// 00 01 02 03 04 05 06 07 4"|3pMr
// 00 01 02 03 04 05 06 07 eV%{XR?y
// auGK2i
#pragma pack() BEax[=&W
|(l]Xr&O
int main(int argc, char* argv[]) r<kgYU`
{ *A`ZcO=
s2 a; lV:feX
char *p = (char *)&a; !e<5JO;c
for(int i=0;i<24;++i) v6G1y[Wl
p = (char)(i%8); W;8A{3q%N0
printf("%d\n",sizeof(a)); 8a)4>B
printf("c=0x%lx\n",a.c); iOfO+3'Z_U
printf("d.a=0x%x\n",a.d.a); ;HAvor=?
printf("d.b=0x%x\n",a.d.b); Xl1% c7r.1
printf("e=0x%llx\n",a.e); kIa16m
return 0; ;ZuHv {=
} xtCMK1#
x
结果: u`wD6&y*
24 QDj%m %Xd
c=0x0 c|3oa"6T>
d.a=0x504 iOIq2&sV
d.b=0x3020100 4<tbZP3/6)
e=0x706050403020100 rRe^7xGe7
s[a\m,
"c} en[
网友 redleaves (ID最吊的网友)的答案和分析: CT_tJ
v6DjNyg<x
如果代码: >l8?B L
#pragma pack(8) RSj8T<
struct S1{ /tG as
char a; S@!_{da
long b; q{G8Po$z'
}; }fk3a9j9u
struct S2 { T}z? i
char c; g?|Z/eVJ
struct S1 d; UhDf6A`]
long long e; uX!6:v]
}; ~$>JYJj
#pragma pack() 8.jf6
sizeof(S2)结果为24. 5nBJj
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. )2wf D
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. T~$Eh6
D
!"<rlB,J
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; |wJdp,q R
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. F5+FO^3E
a b M
hW9^?
S1的内存布局:11**,1111, wO.d;SK
c S1.a S1.b d gnzg(Y]5w
S2的内存布局:1***,11**,1111,****11111111 '/XP4B\(E
.|u`s,\
这里有三点很重要: *tT}N@<%
1.每个成员分别按自己的方式对齐,并能最小化长度 PA803R74
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 .7
)oWd!
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 SIm1fC
\>*.+?97
|J`v
w
网友xue23(xue23) 的答案和分析: l
x;87MDs
sZ&6g<8#y
有程序查一下各个变量的内存地址得知: ts(u7CJd
各个变量在内存中的位置为 Gjq7@F'
c***aa** LCS.C(n,
bbbb**** SJX9oVJeZ
dddddddd `-CN\
测试代码为: {HM[ )t0
s2 ss; eD(5+bm
cout << "ss.c = " << &ss << endl ; <z%**gP~G
cout << "ss.d.a = " <<&ss.d.a << endl; &-o5lrq
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; raOuD3
print out 各个变量的内存地址不就可以看出来了吗。 N LQ".mM+
|*w)]2Bl
所以答案是24,2. :zo5`[P
e(0cz6
但是我的想像中应该是这样的分布情况: f*"T]AX0
c******* M `q|GY
aa**bbbb XM+.Hel
dddddddd "(W;rl
dHiir&Rd9`
不知为什么会c和a放在一起,组成8位长度。