Intel和微软同时出现的C语言面试题 &}=,8Gt1G
#pragma pack(8) dj**,*s
:e vc
struct s1{ /! G0 g%k
short a; ~,7R*71
long b; Vo8"/]_h
}; ?+L6o C.;
*j :5
struct s2{ YL0RQa
char c; 8[IifF1M=&
s1 d; .Dxrc
long long e; SVz.d/3Y
}; }CqIKoX.
zKT<QM!`
#pragma pack() kO"aE~
-e\56%\~_
问 Vk
T3_f
1.sizeof(s2) = ? f#b[KB^Z,2
2.s2的s1中的a后面空了几个字节接着是b? GdY^}TJrh
XL9lB#v^
a8$pc>2E
JwVv+9hh
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: th|Q NG
aX:$Q
}S
网友rwxybh(行云)的答案: e|y~q0Q$
内存布局是 w Vmy`OV/
1*** 11** #JM*QVzv
1111 **** .JjuY'-Q
1111 1111 biK.HL\V
&|*|
所以答案就是24和3 U++UG5 c
8 EH3zm4
下面是一个测试的程序,试一试就知道了,我用的是VC2005 bc-}Qn
/Vc!N)
#pragma pack(8) D~>P/b)v{j
JwcP[w2
struct s1{ !1R
short a; // 2 BYtes CB)#;
|aDB
long b; // 4 Bytes 7X>3WF
}; c?S402M}
struct s2{ z0Hh8*
char c; // 1 Byte HrxEC)V6#
s1 d; // 8 Bytes 5~QB.m,>
long long e; // 8 Bytes |05LHwb>
}; @DR&e^Zz
// 1*** 11** %Kp}Wo6
// 1111 **** (FHh,y~v
// 1111 1111 )cXc"aj@s
//
!^\/
1^
krU2S-
// 00 01 02 03 04 05 06 07 eyV904<F
// 00 01 02 03 04 05 06 07 .jw)e!<\N
// 00 01 02 03 04 05 06 07 ktRdf6:~
//
VVY\W!
#pragma pack() \
3N#%
3iTjM>+>
int main(int argc, char* argv[]) :8g \B{
{ oY:>pxSz<@
s2 a; K.~U%v}
char *p = (char *)&a; 5N/;'ySAE_
for(int i=0;i<24;++i) )
|a5Qxz
p = (char)(i%8); +0DIN4Y(4
printf("%d\n",sizeof(a)); ~JiA
printf("c=0x%lx\n",a.c); _u;
UU$~
printf("d.a=0x%x\n",a.d.a); HL]?CWtGP
printf("d.b=0x%x\n",a.d.b); xm5D$m3#
printf("e=0x%llx\n",a.e); ?hYe4tc-#
return 0; lvlH5Fc
} &$[{L)D
结果: P@#6.Bb#V
24 &\r%&IX/
c=0x0 $? Rod;
d.a=0x504 q[lqEc
d.b=0x3020100 ?~Des"F6)1
e=0x706050403020100 -_(!
zO,sq%vQn'
/^"TMm
网友 redleaves (ID最吊的网友)的答案和分析: .wywO|
I
uDk9<[b:
如果代码: CgWj9 [
#pragma pack(8) Oc>-jhx?
struct S1{ (ym)q#^
char a; I$&/?ns@O
long b; ` {p5SYj
}; &k nnWm"
struct S2 { bvG
Vfr "
char c; >J1o@0tk
struct S1 d; _%]H}N Q
long long e; B$G8,3 ,:
}; P?F:x=@'|
#pragma pack() \Ip<bbB0
sizeof(S2)结果为24. -h}J%UV
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. {)M4h?.2
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. NKRXY~zHh
7~&Y"&
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; ~Y(M>u.+!
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. 6`i'
a b g7pFOcV
S1的内存布局:11**,1111, }|d:(*
c S1.a S1.b d v|xlI4
S2的内存布局:1***,11**,1111,****11111111 VO9<:R
T7v8}_"-
这里有三点很重要: C+Z"0\{o
1.每个成员分别按自己的方式对齐,并能最小化长度 Smp+}-3O
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 IO4 IaeM
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 SV~xNzo~
y-U(`{[nM
,rKN/{M!
网友xue23(xue23) 的答案和分析: DCm;dh
DuWP)#kg
有程序查一下各个变量的内存地址得知: ~gf$ L9
各个变量在内存中的位置为 ocMf}"
c***aa** ,#A,+!4
bbbb**** >h9U~#G=
dddddddd |Yx8Ez
测试代码为: :1iw_GhJf
s2 ss; O]>Or3oO
cout << "ss.c = " << &ss << endl ; km^AX:r1
cout << "ss.d.a = " <<&ss.d.a << endl; 3O.-'U1K
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; khR3[ju {^
print out 各个变量的内存地址不就可以看出来了吗。 sM-*[Q=_
MG6Tk(3S
所以答案是24,2. \yqiv"'
|lv4X}H
但是我的想像中应该是这样的分布情况: iw{n|&Y#`
c******* cA*%K[9
aa**bbbb /c7j@=0
dddddddd E*%{Nn
OjHBzrK
不知为什么会c和a放在一起,组成8位长度。