Intel和微软同时出现的C语言面试题 $1Q3Y'Q9
#pragma pack(8) )]0[`iLe
]4LT#
struct s1{ Yc.
~qmG/z
short a; -eSPoZ
long b; mGMinzf
}; "-~D!{rS
5~<a>>
struct s2{ IPr*pQ{;c
char c; (;Dn%kK
s1 d; Z
L6~Eut
long long e; :N+K^gI)
}; u"Hd55"&
/
y":/"h
#pragma pack() :$X4#k<
T_YMM'`
问 a[d{>Fb.
1.sizeof(s2) = ? xv(xweV+d
2.s2的s1中的a后面空了几个字节接着是b? q;Ar&VrlNq
'.}6]l
yNb#Ia
g4.'T51
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: {Q#Fen
;y|
IlC:dA
网友rwxybh(行云)的答案: 32)&;
内存布局是 h0Sy']3m
1*** 11** &K}(A{
1111 **** .SRuyioF&
1111 1111 Le#E! sU
)ZQ9a4%
所以答案就是24和3 4cVs(`g^
#h
#mOJ5
下面是一个测试的程序,试一试就知道了,我用的是VC2005 #qiGOpTF.
[][:/~q!
#pragma pack(8) tnKpn-LPA
TS~Y\Cp
struct s1{ 709Uv5
short a; // 2 BYtes t?#vb}_
long b; // 4 Bytes JQ{zWJlt
}; Hc_hO
struct s2{ U{za m
char c; // 1 Byte R"\ub"]
s1 d; // 8 Bytes C&d"#I
long long e; // 8 Bytes 9L)&n.t1
}; r-\T}e2Gz
// 1*** 11** QB.*R? A
// 1111 **** ;?HZ,"^I
// 1111 1111 M~g~LhsF
// dWq/)%@t
q!9v}R3(
// 00 01 02 03 04 05 06 07 v|,[5IY
// 00 01 02 03 04 05 06 07 3 DO$^JJ.
// 00 01 02 03 04 05 06 07 1>*UbV<R;u
// 0[$Mo3c+'
#pragma pack() rz%[o,s
0D]Yz`n3
int main(int argc, char* argv[]) !Sy'Z6%f
{ '#An+;x{
s2 a; ;&t1FH#=
char *p = (char *)&a; |<+|Du1
for(int i=0;i<24;++i) L]L~TA<D9i
p = (char)(i%8); -XDP-Trk
printf("%d\n",sizeof(a)); 0u&?Zy9&
printf("c=0x%lx\n",a.c); uYFcq
printf("d.a=0x%x\n",a.d.a); q3pN/f;kr,
printf("d.b=0x%x\n",a.d.b); r* /XB0
printf("e=0x%llx\n",a.e); }T1Xds8w)t
return 0; P20]>Hg
} 0F0(]7g^
结果: AN:RY/ %Wo
24 <DlanczziF
c=0x0 (k)gZD9~{?
d.a=0x504 }9+1<mT9a/
d.b=0x3020100 dnWt\>6&
2
e=0x706050403020100 i&s=!`
g$^qQs)^N
$X<<JnsK
网友 redleaves (ID最吊的网友)的答案和分析: uB#B\i
J^+$L"K
如果代码: T~ q'y~9o
#pragma pack(8) yM#trqv5
struct S1{ 5,
"^"*@<
char a; @ !O&b%8X%
long b; y\f 8Ird
}; 51;%\@=
struct S2 { [k&s!Qp
char c; rEpKX
struct S1 d; vdFQf ^l
long long e; pi l*/&pB
}; h
C`p<jp/
#pragma pack() ,%b1 ]zZQ
sizeof(S2)结果为24. (.nJT"&
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 3TvhOC>yG
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Fi3(glgd-
ht74h
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; VL!kX``^F
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节.
rgvc5p
a b t;f
p<z7N.
S1的内存布局:11**,1111, *,XJN_DKj
c S1.a S1.b d s:Ql](/B#
S2的内存布局:1***,11**,1111,****11111111 r1[T:B'
MzW$Sl&:
这里有三点很重要: o?
xR[N-J
1.每个成员分别按自己的方式对齐,并能最小化长度 bHH}x"d[x
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 !.GY~f<d$
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 Q,qylL
]H9HO2wGQ
4.kkxQR7r
网友xue23(xue23) 的答案和分析: )yH#*~X_
JA(q>>4
有程序查一下各个变量的内存地址得知: +?m=f}>W1
各个变量在内存中的位置为 5J2p^$s
c***aa** \iLd6Qo_aq
bbbb**** `kT$Gx4x
dddddddd GC#95
测试代码为: S0QU@e
s2 ss; AJ1$$c
cout << "ss.c = " << &ss << endl ; z'}t@R#H
cout << "ss.d.a = " <<&ss.d.a << endl; :IKp7BS
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; P}u<NPy3Q
print out 各个变量的内存地址不就可以看出来了吗。 ;\&bvGj8V
f'yd{ihFp
所以答案是24,2. e$+? v2.
n\)f.}YD8d
但是我的想像中应该是这样的分布情况: zm S-s\$,
c******* Mn{Rg>X
aa**bbbb p{#7\+}
dddddddd 3eDx@8N
}
]{,=mOk
不知为什么会c和a放在一起,组成8位长度。