Intel和微软同时出现的C语言面试题 &Im-@rV!
#pragma pack(8) :j? MEeu
6xFchdMG{m
struct s1{ Dutc#?bT
short a; ;I*N%a TK
long b; MDBqIL]Hc
}; yxi&80$
%, S{9q
struct s2{ o]WcODJdl
char c; y>cLG5v
s1 d; h.wffk,
long long e; 'e_e*.z3
}; 4X!4S6JfB
gvr&7=p
#pragma pack() !>f:wk2
-s0\ 4
问 <"8F=3:uk
1.sizeof(s2) = ? 4"UH~A;^
2.s2的s1中的a后面空了几个字节接着是b? 2f1Q&S
r4d#;S9{o
y
t7 >,
M9G?^mW1sT
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: %K,cGgp^)
0oZZLi
网友rwxybh(行云)的答案: NkoyEa/^[
内存布局是 6s>io%,:
1*** 11** T-h[$fxR_
1111 **** +F.@n_}p-I
1111 1111 jrpki<D
8n["/5,
所以答案就是24和3 ^\[c][fo
N,UUM|?9_
下面是一个测试的程序,试一试就知道了,我用的是VC2005 m6'9Id-:L
b7'l3m Qjk
#pragma pack(8) \Rs9B .
SYh>FF"
struct s1{ -3 Sb%V\
short a; // 2 BYtes ]$#9B-uB
long b; // 4 Bytes d|8-#.gV
}; ^"~r/@l
struct s2{ ;GKL[tI"
char c; // 1 Byte oF a,IA
s1 d; // 8 Bytes zG{jRth
long long e; // 8 Bytes i'.D=o
}; XMz*}B6GQ
// 1*** 11** {Us^4Xe
// 1111 **** B@S~v+Gr
// 1111 1111 >I-rsw2
// &3J^z7kU
{jv+ JL"5
// 00 01 02 03 04 05 06 07 x!7r7|iV
// 00 01 02 03 04 05 06 07 fg lN_
// 00 01 02 03 04 05 06 07 L2_[M'
// Q}cti/
#pragma pack() lEw;X78+
Yf/e(nV
int main(int argc, char* argv[]) +43~4_Oj
{ ^Ku]8/ga
s2 a; E;9J7Q
4
char *p = (char *)&a; C/QrkTi=
for(int i=0;i<24;++i) $|@pY| f
p = (char)(i%8); a:OM I
printf("%d\n",sizeof(a)); n^b CrvD
printf("c=0x%lx\n",a.c); \RtFF
printf("d.a=0x%x\n",a.d.a); @eutp`xoT\
printf("d.b=0x%x\n",a.d.b); >?_}NZ,y
printf("e=0x%llx\n",a.e); y^[t3XA6Q
return 0; a5aHv/W#P
} 3t9CN
)*
结果: A6J:!sY4A
24 -ssmj8:Q\|
c=0x0 >&ZlCE
d.a=0x504 `7'^y
d.b=0x3020100 C#8A|
e=0x706050403020100 )\PX1 198
IuA4eDr^Y%
f*ABIm
网友 redleaves (ID最吊的网友)的答案和分析: mU
D>;_R
HK
如果代码: "shX~zd5
#pragma pack(8) WnOvU<Z
<
struct S1{ s5 {B1e
char a; 8B]\;m
long b; *&\6x}.I4
}; Jw#7b[a
struct S2 { bBV03_*
char c; q#I'@Jbj
struct S1 d; iBtG@M
long long e; TvS<;0~K
}; 4[&&E7]EX
#pragma pack() N8k=c3|
sizeof(S2)结果为24. V#|/\-@
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. G Y.iCub
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. d[5v A/8O
[La}h2gz
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; D?8(n=#[
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. _ker,;{9C
a b 7&/1K%x9;
S1的内存布局:11**,1111, }s:3_9mE
c S1.a S1.b d *4LRdLMn
S2的内存布局:1***,11**,1111,****11111111 xB[W8gQ6fa
GmE`YW
这里有三点很重要: Ihr[44#
1.每个成员分别按自己的方式对齐,并能最小化长度 9+$IulOvk
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 %W$b2N{l
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 .o5K X*
VbMud]40F
hOkn@F.
网友xue23(xue23) 的答案和分析: ,grx'to(X
^^*L;b>I
有程序查一下各个变量的内存地址得知: |(2#KMEWa
各个变量在内存中的位置为 b:r8r}49
c***aa** e@;'# t
bbbb**** xf8[&?
dddddddd $E[M[1j
测试代码为: S:Jg#1rww-
s2 ss; ]=ZPSLuEm%
cout << "ss.c = " << &ss << endl ; 'h7x@[|
cout << "ss.d.a = " <<&ss.d.a << endl; if*~cPnN
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; aMxj{*v7
print out 各个变量的内存地址不就可以看出来了吗。 ~l?c.CSd
yPe9KN_
所以答案是24,2. ,fTC}>s4
G<k.d"<
但是我的想像中应该是这样的分布情况: mPqKk
c******* :-<30LS$
aa**bbbb nqx0#_K-E
dddddddd 63_#*6Pv28
jUl_ToX
不知为什么会c和a放在一起,组成8位长度。