Intel和微软同时出现的C语言面试题 ||XIWKF<n2
#pragma pack(8) M%|f+u &
!)nD xM`p
struct s1{ I-bF{
short a; d/lffNS=
long b; R:f7LRF/\
}; -%H%m`wD
[IMQIX
struct s2{ 'bPk'pj9
char c; wFb@1ae\
s1 d; =hGJAU
long long e; '#<> "|
}; Z\' wm'
PtqGX=u
#pragma pack() Oy%Im8.-A#
:!']p2B
问 'W(xgOP1
1.sizeof(s2) = ? (AuPZ
2.s2的s1中的a后面空了几个字节接着是b? n/ AW?'
e3g_At\
rREzM)GA
7*;^UqGjz
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: x6%#wsvS
{xToz]YA
网友rwxybh(行云)的答案: Ye@t_,)x
内存布局是 n,sY\=vB
1*** 11** rVcBl4&1*g
1111 **** OX^3Q:Z=
1111 1111 s/h7G}Mu
wVE:X3Ei
所以答案就是24和3 M~p=#V1D
~#Aa Ldq
下面是一个测试的程序,试一试就知道了,我用的是VC2005 r)8z#W>s
f?maa5S
#pragma pack(8) gz4UV/qr/
d;44;*D
struct s1{ a:b^!H>#
short a; // 2 BYtes :<%vE !$
long b; // 4 Bytes @)b^^Fp
}; ;(S|cm'>}
struct s2{ ="3,}qR
char c; // 1 Byte K}K)`bifw
s1 d; // 8 Bytes h)@InYwu7
long long e; // 8 Bytes J=9 #mOcg"
}; n`.#59-Hx
// 1*** 11** > 0T
Za
// 1111 **** D%gGRA
// 1111 1111 KuXkI;63J>
// H`el#tt_
NnOI:X {
// 00 01 02 03 04 05 06 07 gc,Ps
// 00 01 02 03 04 05 06 07 8^vArS;
// 00 01 02 03 04 05 06 07 H;y}-=J+
// !.-.#<<_a
#pragma pack() )8'jxiGs
4|f}F
int main(int argc, char* argv[]) `)tA
YH
{ HTR1)b
s2 a; H#Q;"r 3
char *p = (char *)&a; M BVOfEMj
for(int i=0;i<24;++i) R&Ci/
p = (char)(i%8); .[(P
printf("%d\n",sizeof(a)); TY6
rwU
printf("c=0x%lx\n",a.c); +NR n0
z(
printf("d.a=0x%x\n",a.d.a); * <q4S(l
printf("d.b=0x%x\n",a.d.b); K(OaW)j
printf("e=0x%llx\n",a.e); Y 1y E
return 0; FUqt)YHi
} ^Plc}W7h
结果: Ue! Q. "
24 v20~^gKo=m
c=0x0 P7r4ePtLk{
d.a=0x504 C0(sAF@
d.b=0x3020100 8W,*eke?
e=0x706050403020100 d.cCbr:
C0<YH "
U&Ab#m;
网友 redleaves (ID最吊的网友)的答案和分析: |^iA6)Q
y\z > /q
如果代码: 6#|qg*OS
#pragma pack(8) 41}/w3Z4
struct S1{ DxfMqH[vs
char a; YxyG\J\|,
long b; ANb"oX c
}; n_P(k-^U*
struct S2 { }p{;^B
char c; a.,i.2
struct S1 d; GA@ Ue9
long long e; nq@5j0fK
}; (yGQa5v
#pragma pack() Hg whe=P
sizeof(S2)结果为24. jb3.W
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. Spo+@G
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.
i6 L
F`srE6H
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; EneAX&SG
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. *l-`<.
a b m^A]+G#/
S1的内存布局:11**,1111, )Mi'(C;
c S1.a S1.b d n$W"=Z;`
S2的内存布局:1***,11**,1111,****11111111 U`1l8'W}:#
2d~LNy
这里有三点很重要: F.0d4:A+
1.每个成员分别按自己的方式对齐,并能最小化长度 1ktHN: ta
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 Z"DW 2k
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 N7pt:G2~%
q^]tyU!w
Q!]IG;3Sx|
网友xue23(xue23) 的答案和分析: (YrR8
w[sR7T9*
有程序查一下各个变量的内存地址得知: [Xh\mDU.
各个变量在内存中的位置为 [>p6
c***aa** b0YNac.l
bbbb**** \u8,!) 4i
dddddddd ~p^7X2% !
测试代码为: Qc3?}os2
s2 ss; u-39r^`5
cout << "ss.c = " << &ss << endl ; 3agNB F2
cout << "ss.d.a = " <<&ss.d.a << endl; : I)G v
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; Bk@WW#b
print out 各个变量的内存地址不就可以看出来了吗。 {82rne`[
UE;Bb*<
所以答案是24,2. R,b59,&3/
v
F[CWV.
但是我的想像中应该是这样的分布情况: x~Agm_Tu+'
c******* 0[9I0YBJ
aa**bbbb Mr.JLW
dddddddd -#%X3F7/w
PGY9*0n
不知为什么会c和a放在一起,组成8位长度。