Intel和微软同时出现的C语言面试题 qP<wf=wY
#pragma pack(8) tmF->~|
Mq!03q6
struct s1{ Y_n^6 ;
short a; y>T:fu
long b; j8*fa
}; /PbN!r<1
{7!WtH;-
struct s2{ +qsNz*@p"
char c; ]r;-Lx{F
s1 d; Gj]*_"T
long long e; z-*/jFE
}; z_vFf0
%jKbRiz1u
#pragma pack() FVOR~z
c?;~Z
问 [!E pv<G
1.sizeof(s2) = ? k
9 Xi|Yj
2.s2的s1中的a后面空了几个字节接着是b? ml$"C
mF\r]ovVm
{S4^;Va1
Iuk!A?XV
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: '&{`^l/MH
.K>rao'
网友rwxybh(行云)的答案: 6XPf0Gl
内存布局是 ..RCR_DIp
1*** 11** 9mW95YI S
1111 **** / $7E
1111 1111 $Il?[4FF
~Aul 7[IH
所以答案就是24和3 a>jiq8d]4
Y#Pl)sRr
下面是一个测试的程序,试一试就知道了,我用的是VC2005 ndEW$?W,
AZ~=]1
#pragma pack(8) =H&@9=D*
~3bn?'`
struct s1{ Jsf-t
short a; // 2 BYtes Yoy}Zdu}h
long b; // 4 Bytes _Wn5*
Pi%Z
}; -gZI^EII
struct s2{ Qzbelt@Wx
char c; // 1 Byte !"{+|heU9p
s1 d; // 8 Bytes
lIHSy
long long e; // 8 Bytes R1Jj 3k
}; >q0c!,Ay
// 1*** 11** .iFd
// 1111 **** HhkubG)\
// 1111 1111 DuJbWtA
// 6A$
\I44
cl s-x@
Kd
// 00 01 02 03 04 05 06 07 FFGG6r
// 00 01 02 03 04 05 06 07 5yO%| )
// 00 01 02 03 04 05 06 07 NsYeg&>`
// v^_OX$=,
#pragma pack() H2oAek(
|pB[g>~V
int main(int argc, char* argv[]) )r_zM~jI
{ Wt2+D{@8
s2 a; ]DcQ8D
char *p = (char *)&a; |/B2Bm
for(int i=0;i<24;++i) i}mvKV?!|1
p = (char)(i%8); (~t/8!7N
printf("%d\n",sizeof(a)); k[3J5 4`g1
printf("c=0x%lx\n",a.c); f(Jz*el
S
printf("d.a=0x%x\n",a.d.a); V 4Y w"J
printf("d.b=0x%x\n",a.d.b); h\GlyH~
printf("e=0x%llx\n",a.e); HS!O;7s'
return 0; -'
7I|r
} :G?6Hl)~)
结果: &y-(UOqbkP
24 Q)oO*CnM!-
c=0x0 S0+nQM%
d.a=0x504 $7%e|0jC
d.b=0x3020100 }$-;P=k
e=0x706050403020100 }Xv2I$J
@?,iy?BSG
`8$gaA*
网友 redleaves (ID最吊的网友)的答案和分析: ~x`BV+R
afEhC0j
如果代码: e-vwve
#pragma pack(8) tjw4.L<r
struct S1{ 9L+dN%C
char a; &_cMbFLBP
long b; \
UCOe
}; bL>J0LWQ
struct S2 { Y>}[c
char c; *,Bo $:(n
struct S1 d; /$v0Rq9
long long e; Ik_u34U
}; $ K>.|\
#pragma pack() y#-mj,e
sizeof(S2)结果为24. % j4
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. &HdzbKO=
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. I8=p_Ie
G-?y;V 1
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; E;7vGGf]
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. ]mEY/)~7
a b MpZ
#
S1的内存布局:11**,1111, Ra%" +=
c S1.a S1.b d l*;Isz:
S2的内存布局:1***,11**,1111,****11111111 V@6,\1#`|
:sD/IM",},
这里有三点很重要: hiKgV|ZD
1.每个成员分别按自己的方式对齐,并能最小化长度 RLkP)+t
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 eq)8V x0
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 v`i9LD0(
: ]&O