Intel和微软同时出现的C语言面试题 $O e 58
#pragma pack(8) $U1kP?pR
'e>sHL
struct s1{ cNo4UZvr
short a; Ccr+SR2
long b; s#4ew}
}; %?oU{KzQ@;
C^" Hj
struct s2{ O)xEF~DaD
char c; |SP.S 0.y
s1 d; tnF9Vj[#%_
long long e; mvA xx`jc
}; .Spi$>v
QHzX
5$IM
#pragma pack() xbrmPGpW$
{vT55i<mk
问 abaQJ|
1.sizeof(s2) = ? DV[ Jbl:)
2.s2的s1中的a后面空了几个字节接着是b? gQh Ccv
mu6xL QdA
PyT}}UKj:
"56?/ jF
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: +B q}>
]X:
rby$
网友rwxybh(行云)的答案: R_Gq8t$
内存布局是 ^s@*ISY
1*** 11** :uwRuPI
1111 **** mrhp)yF
1111 1111 @oz&
22/?JWL>
所以答案就是24和3 9j?hF$L"
BY4 R@)
下面是一个测试的程序,试一试就知道了,我用的是VC2005 "T a9
LbV]JP
#pragma pack(8) %V %#y $l
JQ@`EV9,
struct s1{ 9<A\npD
short a; // 2 BYtes L_gsG|xX
long b; // 4 Bytes Wt+y-ES
}; 2rj/wakd
struct s2{ Wl !!5\
char c; // 1 Byte N^Hn9n
s1 d; // 8 Bytes B)DC,+@$
long long e; // 8 Bytes tT* W5
}; [t
// 1*** 11** =tf@4_
// 1111 **** [)H,zpl
// 1111 1111 ?BDlB0jxzi
// )"_Ff,9Z!
A )RI:?+
// 00 01 02 03 04 05 06 07 6t_ 3%{
// 00 01 02 03 04 05 06 07 b>bgUDq
// 00 01 02 03 04 05 06 07 uq|vNLW26
// Lov.E3S6;
#pragma pack() 3%[)!zKv
miG;]-"^
int main(int argc, char* argv[]) -; us12SZ
{ P^b:?%
s2 a; yul<n>X|
char *p = (char *)&a; 0r0\b*r
for(int i=0;i<24;++i) <t[Z9s$n
p = (char)(i%8); W>?f^C!+m
printf("%d\n",sizeof(a)); F8uRT&m B0
printf("c=0x%lx\n",a.c);
wsf Hd<Z_
printf("d.a=0x%x\n",a.d.a); aT?p>
printf("d.b=0x%x\n",a.d.b); 0H OoKh
printf("e=0x%llx\n",a.e); Ko$ $dkSE
return 0; *h*j%
} C,|nmlDN
结果: &h7smZO5j
24 _@#uIOcE
c=0x0 _OJ0 < {E
d.a=0x504 '<?v:pb9
d.b=0x3020100 ]^*_F
e=0x706050403020100 QH7V_#6bKP
Jb3>vCIn
ko=aa5c
网友 redleaves (ID最吊的网友)的答案和分析: J|gdO+
Ei{(
如果代码: a%Z4_ToLZ
#pragma pack(8) IS,zy+w
struct S1{ DnNt@e2|
char a; j}rgOz.
long b; XlPK3^'N)h
}; N+\oFbE
struct S2 { `7QvwXsH]
char c; ~^lH ^J
struct S1 d; 4i_spF-3
long long e; .Bb$j=
}; 9?u9wuH
#pragma pack() i"%JFj_G
sizeof(S2)结果为24. %uGleY]~
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. wO^$!zB W
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. i7S>RB
.)iO Du
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; +=ZWau
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. :"M9*XeHO
a b -Q<z1vz
S1的内存布局:11**,1111, t(J![wB}
c S1.a S1.b d 0Y5LDP
S2的内存布局:1***,11**,1111,****11111111 G0I~&?nDa
TJHN/Z/
这里有三点很重要: 8%;}LK
1.每个成员分别按自己的方式对齐,并能最小化长度 <Jwi~I=^
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 z>cIiprX
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 F^.om2V|9
ki;!WhF~
B;xZ%M]
网友xue23(xue23) 的答案和分析: iEiu%T>
W<\ kf4Y
有程序查一下各个变量的内存地址得知: r+t ,J|V
各个变量在内存中的位置为 |rr$U
c***aa** snXB`UC
bbbb**** @T<ad7g-2J
dddddddd A#v|@sul
测试代码为: q%OcLZ<,
s2 ss; - *:p.(c
cout << "ss.c = " << &ss << endl ; 5~@?>)TBv
cout << "ss.d.a = " <<&ss.d.a << endl; %/UV_@x&
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; EX[B/YH
print out 各个变量的内存地址不就可以看出来了吗。 4=u+ozCG
'8s>rH5[V
所以答案是24,2. +mJ
:PAy4
=E&b=
但是我的想像中应该是这样的分布情况: zWy
,Om8P
c******* =LlLE<X"%x
aa**bbbb Sp 7u_Pq{
dddddddd M:R8<.{
P7's8KOoS
不知为什么会c和a放在一起,组成8位长度。