Intel和微软同时出现的C语言面试题 U.oksD9v
#pragma pack(8) TJ_=1Y@z
JMa3btLy(
struct s1{ V%ii3
short a; iz^qR={bW
long b; IyUdZ,ba
}; Zj9c9
C*kK)6v`
struct s2{ Kuw^qX"
char c; C"V%# K
s1 d; [3>GGX[Ic
long long e;
Nh!_l
}; 6z,Dyy]tl
7(k^a)~PL
#pragma pack() sfD5!Z9#1
LDj<?'
问 oOU1{[
1.sizeof(s2) = ? Pcd *">v
2.s2的s1中的a后面空了几个字节接着是b? WrGK \Vw[
jA(vTR.`
Ty4S~ClO#'
WCq
/c6 D
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: .IrNa>J~
4vZ4/#(x
网友rwxybh(行云)的答案: #?O&
内存布局是 9(_{`2R8
1*** 11** *|:Q%xr-
1111 **** 7L(eh7
1111 1111 eny/
fm
Ve 3 ;
所以答案就是24和3 B;#J"6w
@4+#Xd7"
下面是一个测试的程序,试一试就知道了,我用的是VC2005 ixfdO\nU
Y}G_Z#- !
#pragma pack(8) IVvtX}
-yH,5vD
struct s1{ UXr5aZ7y
short a; // 2 BYtes 8;gXg
long b; // 4 Bytes 8F5|EpB9M
}; B{6<;u)[
struct s2{ Q(7ob}+jQ
char c; // 1 Byte ~qVz)<
s1 d; // 8 Bytes 2?7(A
long long e; // 8 Bytes M!m?#xz'c
}; t;qP']2
// 1*** 11** K >tf,
// 1111 **** zd%rs~*c
// 1111 1111 %Q"(/jm?
// Tenf:Hm/k
q3e8#R)l
// 00 01 02 03 04 05 06 07 'o4p#`R:8
// 00 01 02 03 04 05 06 07 XFwLz
// 00 01 02 03 04 05 06 07 {<$bAj
// f'En#-?O
#pragma pack() aEVsU|
r|<DqTc6l
int main(int argc, char* argv[]) Ww3wsy x
{ 2B1xUj ]
s2 a; yJx?M
char *p = (char *)&a; 48D?'lW %
for(int i=0;i<24;++i) 7N8H)X
p = (char)(i%8); J1ON,&[J
printf("%d\n",sizeof(a)); BzJ;%ywS
printf("c=0x%lx\n",a.c); .giz=*q+
printf("d.a=0x%x\n",a.d.a); .)XP\m\
printf("d.b=0x%x\n",a.d.b); ^-)txC5{T
printf("e=0x%llx\n",a.e); GRqT-/n"
return 0; nA7M8HB
} C|-pD
结果: AG6K
daJ
24 5r,r%{@K
c=0x0 E)N<lh
d.a=0x504 8AFczeg[[
d.b=0x3020100 I s57F4[}
e=0x706050403020100 IND ]j72
TbVn6V'
< B g8,;
网友 redleaves (ID最吊的网友)的答案和分析: R*pC.QiB~
QfjN"25_
如果代码: H U+ I
#pragma pack(8) E; Y;r"
struct S1{ 62'1X"
char a; "UVFU-Z
long b; s 0u{dqP
}; \6I+K"
struct S2 { e(
X|3h|
char c; LaMLv<)k
struct S1 d; !c#]?b%
long long e; V7Yaks
}; jvy$t$az
#pragma pack() H6TD@kL9Wr
sizeof(S2)结果为24. *>8ce-PV
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. ZAKeEm2A
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 6=hk=2]f
RIn9(r
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; FqFapRX66Z
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. K*-@Q0"KM{
a b h@{_duu
S1的内存布局:11**,1111, |J5 =J
c S1.a S1.b d ecJ6
S2的内存布局:1***,11**,1111,****11111111 xw^.bz|
2.e
vx
这里有三点很重要: +UN <Zp7I/
1.每个成员分别按自己的方式对齐,并能最小化长度 ,3i,P(?(
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 `Nh"
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 %qf V+^
ef! XV7P
{LzH&qu
网友xue23(xue23) 的答案和分析: 7Z,opc
sM[I4.A3
有程序查一下各个变量的内存地址得知: _6@hTen`
各个变量在内存中的位置为 BP[|nL
c***aa** ^ZDBO/
bbbb**** n.oUVr=nX
dddddddd 5~sx:0;
测试代码为: I751 t
s2 ss; sZgRt
cout << "ss.c = " << &ss << endl ; "Ml&[Oge
cout << "ss.d.a = " <<&ss.d.a << endl; ykg# {9+
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; bizTd
print out 各个变量的内存地址不就可以看出来了吗。 #V02hs1
D('2p8;2"7
所以答案是24,2. `?(Bt|<>
U5HKRO
但是我的想像中应该是这样的分布情况: SzDKByi
c******* s)
O[t
aa**bbbb C#V ~Y
dddddddd /Dtd#OAdr
MTGiAFE
不知为什么会c和a放在一起,组成8位长度。