Intel和微软同时出现的C语言面试题 `R[ZY!=+
#pragma pack(8) ,JV0ib,
b]+F/@h~]
struct s1{ Y$r78h=4
short a; YZBh}l6t
long b; JF.Lo;
}; c0@8KW[,
lS.Adl^k
struct s2{ c[dzO.~
char c; ]yU"J:/
s1 d; HB/V4ki
long long e; WVbrbs4
}; fSuykbZ
hi0HEm\
#pragma pack() 8vY-bm,e
>d 2Fa4u3
问 5~JT*Ny
1.sizeof(s2) = ? H$(bSw$
2.s2的s1中的a后面空了几个字节接着是b? ;<AcW.jx
EiW|+@1
/fr> Fd
u]J@65~'b
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: *x"80UXL
#.bW9j/
网友rwxybh(行云)的答案: $"^K~5Q
内存布局是 86r5!@WN
1*** 11** KQdIG9O+6
1111 **** L_8zZ8 o
1111 1111 $7S"4rou
k"(]V
所以答案就是24和3 0M_oFx
xAQtX=FoX+
下面是一个测试的程序,试一试就知道了,我用的是VC2005 C9n%!()>
.V?:&_}_I6
#pragma pack(8) W(s4R,j
|^pev2g
struct s1{ 9 E!le=>
short a; // 2 BYtes Sjpx G@k
long b; // 4 Bytes kXMp()N8`
}; <>cS@V5j
struct s2{ }rTH<!j
char c; // 1 Byte du3f'=q6|
s1 d; // 8 Bytes _IYaMo.n
long long e; // 8 Bytes %BqaVOKJ"f
}; y>^^.
// 1*** 11** IHl q27O
// 1111 **** ^OR0Vp>L
// 1111 1111 _kj]vbG^;
// "s*-dZO
J!6FlcsZm
// 00 01 02 03 04 05 06 07 RLB3 -=9t
// 00 01 02 03 04 05 06 07 *T|B'80
// 00 01 02 03 04 05 06 07 gE-y`2SU
// #WpkL]g2+%
#pragma pack() {meX2Z4
nM
)C^$3<t
int main(int argc, char* argv[]) O !L`0
=%c
{ VM"cpC_8
s2 a; *Z5^WHwg
char *p = (char *)&a; [VCC+_
for(int i=0;i<24;++i) yPm2??5MW>
p = (char)(i%8); /Rp]"S
vt
printf("%d\n",sizeof(a)); [I $+wWW_
printf("c=0x%lx\n",a.c); C|(A/b
printf("d.a=0x%x\n",a.d.a); nV;'UpQw
printf("d.b=0x%x\n",a.d.b); C_.9qo]DT7
printf("e=0x%llx\n",a.e); \oQ]=dDCd%
return 0; DDg\oGLp
} *sho/[~_
结果: ^URCnJ67Se
24 UkV?,P@l
c=0x0 (C2 XFg_
d.a=0x504 Nk`UQ~g$
d.b=0x3020100 Hd|l6/[xz
e=0x706050403020100 p5Q]/DhG
f^WTsh]
--$o$EP`
网友 redleaves (ID最吊的网友)的答案和分析: 1^p/#jt
'=\}dav!
如果代码: h~MV=7
lE
#pragma pack(8) Y Y:BwW:
struct S1{ f&
4_:'-,
char a; JE?p'77C
long b; V|7YRa@
}; L+%"ew
struct S2 { )
nfoDG#O
char c; =P-&dN
struct S1 d; `+JFvn!
long long e; 1SQATUV
}; gt&|T
j
#pragma pack() ~}/Dl#9R!
sizeof(S2)结果为24. l^B.iB
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. E_HB[9
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Qy,^'fSN
B~Q-V&@o
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; f0Q6sV ZHa
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. 15$xa_w}L
a b ;|N:FG
S1的内存布局:11**,1111, Tt[zSlIMx
c S1.a S1.b d )M*w\'M
S2的内存布局:1***,11**,1111,****11111111 'm%{Rz>j
R;& >PFmq
这里有三点很重要: ?HZp@&
1.每个成员分别按自己的方式对齐,并能最小化长度 .=_p6_G
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 eE;tiX/
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 -wlj;U
0ju1>.p
q!c(~UVw
网友xue23(xue23) 的答案和分析: <t%gl5}|
wN2+3LY{
有程序查一下各个变量的内存地址得知: (z?HyxRT
各个变量在内存中的位置为
gwZ<$6
c***aa** &4'<