Intel和微软同时出现的C语言面试题 JxVGzb`8
#pragma pack(8) ~`
tuPk~l
}1#m+ (;
struct s1{ Hv;xaT<}V
short a; u
BEwYQB
long b; qDdO-fPev
}; F-,gj{s
khy'Y&\F;
struct s2{ NW\CEJV
char c;
)@wC6Ij
s1 d; e;.,x 5+
long long e; X$kLBG[o_
}; ~~>m
!5*VBE\
#pragma pack() A]BeI
]Uv,}W
问 L)'G_)Sl
1.sizeof(s2) = ? <pX?x3-'
2.s2的s1中的a后面空了几个字节接着是b? rL5=8l
^Om}9rXw1
T@W:@,34
yT^2;/Z
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: )qxt<
_U~R
网友rwxybh(行云)的答案: %2 r~
内存布局是 '?rR>$s
1*** 11** XM]m%I
1111 **** t&U9Z$LS
1111 1111 d.&_j`\F
=R5W
KX
所以答案就是24和3 yY$^
R|t
|
Y:`>2ev
下面是一个测试的程序,试一试就知道了,我用的是VC2005 UQ0!tFx
4=,J@N-
#pragma pack(8) 5IU!BQU
//@6w;P
struct s1{ 0+\725DJ
short a; // 2 BYtes }c,b]!:
long b; // 4 Bytes TEV DES
}; #0AyC.\
struct s2{ )\+Imn
char c; // 1 Byte fJ}e
s1 d; // 8 Bytes ucl001EK
long long e; // 8 Bytes x;vfmgty
}; $0Y`>3
// 1*** 11** Z %pc"
// 1111 **** \,;glY=M!
// 1111 1111 NO5k1/-
// V!:!c]8F
Jh+;+"
// 00 01 02 03 04 05 06 07 ~ 5}t;
// 00 01 02 03 04 05 06 07 W|<c[S
// 00 01 02 03 04 05 06 07 KM &P5}
// vQ<
~-E
#pragma pack() -ssb|r
'o&d!
int main(int argc, char* argv[]) S*l/
Sa@
{ lT[,w9 $
s2 a; ;@;aeu
char *p = (char *)&a; ^wy
for(int i=0;i<24;++i) $#=d@Nw_
p = (char)(i%8); JA^!i98{
printf("%d\n",sizeof(a)); R>c>wYt'f
printf("c=0x%lx\n",a.c); c]pz&
printf("d.a=0x%x\n",a.d.a); QQAEG#.5
printf("d.b=0x%x\n",a.d.b); "%T~d[M
printf("e=0x%llx\n",a.e); W ^<AUT
return 0; U5"u
h} 3
} "kApGNB
结果: 8u*<GbKGI
24 "ku[b\W
c=0x0 H&s`Xr
d.a=0x504 9~V'Wev
d.b=0x3020100 !*l /Pr^8
e=0x706050403020100 }Y-V!z5z!
hWly8B[I
Ti2cD
网友 redleaves (ID最吊的网友)的答案和分析: ~W@dF~r
OP!R>|
如果代码: (aYu[ML
#pragma pack(8) ?e9tnk3
struct S1{ 21!X[)r
char a; ..yV=idI
long b; $#V'm{Hh
}; 4&E"{d
>
struct S2 { 5 3pW:`
char c; -'c
qepC{T
struct S1 d; _`gF%$]b
long long e; Mmz;
uy_
}; T#*,ME7|m
#pragma pack() K+Him]
b
sizeof(S2)结果为24. yl$Ko
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 1ZFKLI`V
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. !w7/G
-aT-<+?s
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; inW7t2p<s
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. RZW=z}T+H
a b J@>|`9T9$
S1的内存布局:11**,1111, YI0l&'7
c S1.a S1.b d NLZ5 5yo$
S2的内存布局:1***,11**,1111,****11111111 _4oAk @A
^mC~<pP(
这里有三点很重要: :uYZ1O
1.每个成员分别按自己的方式对齐,并能最小化长度 .5 E)dU
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 i?^L",[
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 2wpJ)t*PF
1tbA-+
q&=z^Ln!G
网友xue23(xue23) 的答案和分析: pCkMm)2g!
4$^mLD$>
有程序查一下各个变量的内存地址得知: U_VP\ 03
各个变量在内存中的位置为 F,vkk{Z>
c***aa** {)Wf[2zJ
bbbb**** ?Nt( sZ-
dddddddd pnu?=.O
测试代码为: N:|``n>
s2 ss; \(LD<-a
cout << "ss.c = " << &ss << endl ;
fDYTupKXH
cout << "ss.d.a = " <<&ss.d.a << endl; ]DnAW'm
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; O#.YTTj
print out 各个变量的内存地址不就可以看出来了吗。 =?|$}vDO[
pbKmFweq
所以答案是24,2. v,n 8$,
:G6CWE
但是我的想像中应该是这样的分布情况: 8`S1E0s
c******* ksq4t
aa**bbbb n\;;T1rM
dddddddd pYcs4f!?p
#j7&2L
不知为什么会c和a放在一起,组成8位长度。