Intel和微软同时出现的C语言面试题 aq"E@fb
#pragma pack(8) ;nj 'C1
d%9I*Qo0,
struct s1{ Q3%a=ba)h
short a; YU76(S9 0#
long b; ,IuO;UV#)
}; (d993~|h
H_;Dq*
struct s2{ mL+}Ka
char c; 7|zt'.56[
s1 d; F~a5yW:R=)
long long e; 3]'=s>UO>^
}; F-k1yZ?^
i#lvt#2J0
#pragma pack() /(n)I
c%pW'UE&
问 _KmpC>J+
1.sizeof(s2) = ? y5a^xRDw
2.s2的s1中的a后面空了几个字节接着是b? _1y|#o
#CV(F$\1{
hl}#bZ8]
o)}b Fw
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: pRc(>P3;
nIph[Vs-Z
网友rwxybh(行云)的答案: a,cDj
内存布局是 &%u,b~cL?
1*** 11** 2!68W
X
1111 **** AG}'
W
1111 1111 F]yclXf('
/UyW&]nK
所以答案就是24和3 `H/HLCt
w?M*n<)
O
下面是一个测试的程序,试一试就知道了,我用的是VC2005 e@]cI/j
n^&QOII@>
#pragma pack(8) ie.cTTOI
D{BH~IM
struct s1{ m$LZ3=v%8
short a; // 2 BYtes
}f&7<E
long b; // 4 Bytes 3pDZ}{ZZU
}; nj7Ri=lyS
struct s2{ ,7%(Jj$
^
char c; // 1 Byte 't)j
s1 d; // 8 Bytes 6w1:3~a
long long e; // 8 Bytes 7KM!\"PM
}; 4zf#zJw
// 1*** 11** KAsS= `
// 1111 **** ;prp6(c
// 1111 1111 38'H-]8q"
// +Z;0"'K'e
e:7aVOm
// 00 01 02 03 04 05 06 07 _cGiuxf
#
// 00 01 02 03 04 05 06 07 Jb
tbW&EH
// 00 01 02 03 04 05 06 07 ~o #
NOfYi
// -;~_]t^a
#pragma pack() R2J3R5S=[
tQl=
int main(int argc, char* argv[]) D3^v[>E2
{ UT{Nly8u
s2 a; 5~[Fh2+
char *p = (char *)&a;
@ics
for(int i=0;i<24;++i) y4?>5{`W
p = (char)(i%8); *M`[YG19!e
printf("%d\n",sizeof(a)); >XZq=q]E!
printf("c=0x%lx\n",a.c); z.H`a+cl
printf("d.a=0x%x\n",a.d.a); O-'T*M>
printf("d.b=0x%x\n",a.d.b); cxv)LOl-
printf("e=0x%llx\n",a.e); ljf9L:L
return 0; n&V(c&C
} rpXw 8
结果: zYs? w=
24 B " B
c=0x0 >C&!#
3
d.a=0x504 eb8_guZ
d.b=0x3020100 .ZJh-cd
e=0x706050403020100 #F6ak,9S4
4Sl^cKb$7
< 1r.p<s
网友 redleaves (ID最吊的网友)的答案和分析: .s9Iymz
y\)w#
如果代码: ;kF p)*i
#pragma pack(8) ;s!H
struct S1{ W UV Q_<i+
char a; 2>r.[
long b; h7w<.zwu
t
}; \G"/Myi
struct S2 { FG(`&S+,
char c; <;T7qEIlo
struct S1 d; =0-qBodbl
long long e; y7Ub~qU
}; N1-LM9S
#pragma pack() R.QcXz?d
sizeof(S2)结果为24. g-s@m}[T
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. M]{!Nx
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. @rF\6I
:({<"H)!'
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; kO#`m]
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. ;wF|.^_2
a b ]aR4U`
S1的内存布局:11**,1111, s [!SG`&
c S1.a S1.b d q8lK6p\:W
S2的内存布局:1***,11**,1111,****11111111 = V , _
gdT_kb5HL8
这里有三点很重要: +OmSR*fA0
1.每个成员分别按自己的方式对齐,并能最小化长度 Y^G3<.B
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 4ca-!pI0
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 *l^'v9
V Y3{1Dlf
cmeyCyV*
网友xue23(xue23) 的答案和分析: f#t^<`7
i<?4iwX%i*
有程序查一下各个变量的内存地址得知: C"{on%
各个变量在内存中的位置为 YMd&+J`
c***aa** Uu+C<j&-
bbbb**** .g~@e_;):
dddddddd rZv+K/6*M
测试代码为: {Jc!T:vJ
s2 ss; U!5*V9T~J
cout << "ss.c = " << &ss << endl ; B,>Fh X>h
cout << "ss.d.a = " <<&ss.d.a << endl; /WfVG\NF
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; sdWl5 "
print out 各个变量的内存地址不就可以看出来了吗。 .7FI%
m=}X$QF`^
所以答案是24,2. A&F4;>dms
^j %UZ
但是我的想像中应该是这样的分布情况: E'8Bw7Tz
c******* =@ZtUjcJx
aa**bbbb )mdNvb[*n
dddddddd r<v%Zp
DeA'D|
不知为什么会c和a放在一起,组成8位长度。