Intel和微软同时出现的C语言面试题 M]8>5Zx.
#pragma pack(8) &zn|),
_ $PeFE2
struct s1{ %/eG{oh-
short a; yf{\^^ i(
long b; %+r(*Q+0$f
}; za>%hZf\
oy[s])Tg
struct s2{ 51:5rN(_
char c; CI+)0=`<1B
s1 d; HOD?i_
long long e; .J.}}"+U
}; mmQC9nZ
U/c+j{=~
#pragma pack() y^r'4zN'
\]Y<d
问 s-#@t
1.sizeof(s2) = ? /@"mQx~[q
2.s2的s1中的a后面空了几个字节接着是b? (R=ZI
n6[shXH
_Q:ot'(~0-
Gn7\4,C
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: K-YxZAf
Tw \@]fw
网友rwxybh(行云)的答案: 7]@M
内存布局是 l>jrY1u
1*** 11** %2RXrH2&H
1111 **** 6cg,L:j#
1111 1111 aT/2rMKPF
[voc_o7AI
所以答案就是24和3 yO-2.2h
^PdD-tY<
下面是一个测试的程序,试一试就知道了,我用的是VC2005 =$}`B{(H
yI=nu53BV
#pragma pack(8) Z4z|B&
(9bU\4F\
struct s1{ h-.^*=]R6
short a; // 2 BYtes uA`e
long b; // 4 Bytes vkLt#yj~
}; W)`>'X`
struct s2{ EQnU:a
char c; // 1 Byte C&F%
j. <
s1 d; // 8 Bytes kFJ]F |^7
long long e; // 8 Bytes 7<kr|-
}; w2$ L;q
// 1*** 11** 2C0j.Ib
// 1111 **** 2SC'Z>A
// 1111 1111 0#c-qy
// 1`II%mf[
i Q3wi
// 00 01 02 03 04 05 06 07 K[SzE{5=P
// 00 01 02 03 04 05 06 07 ldG8hK
// 00 01 02 03 04 05 06 07 HJr*\%D}1
// G>Bgw>#_
#pragma pack() //G&=i$
**AJFc
int main(int argc, char* argv[]) vU/sQt8
{ qHrIs-NR
s2 a; 5m;pHgkb
char *p = (char *)&a; $sL+k 'dY
for(int i=0;i<24;++i) 3b?-83a
p = (char)(i%8); >$<Q:o}^
printf("%d\n",sizeof(a)); zBrIhL]95
printf("c=0x%lx\n",a.c); tIA)LF
printf("d.a=0x%x\n",a.d.a); lYS4Q`z$
printf("d.b=0x%x\n",a.d.b); qq^[(n
printf("e=0x%llx\n",a.e); u 'ng'j'
return 0; YC{7;=Pf
} Q2|6W E
结果: @8YuMD;
24 9(&$Gwi
c=0x0 ,g P;XRe1
d.a=0x504 z:n
JN%Qb
d.b=0x3020100 R]kH$0`
e=0x706050403020100 PC=s:`Y}R
s5b<KQ.
!/F-EJOH6C
网友 redleaves (ID最吊的网友)的答案和分析: b9f5
11J:>A5zt
如果代码: oOQan
#pragma pack(8) r|jBKq~
struct S1{ qyIy xJ
char a; 6{Bvl[mhI
long b; M~sP|Ha"+
}; RXPl~]k#i
struct S2 { ;?o"{mbb
char c; [woxCfSA
struct S1 d; a`||ePb|W~
long long e; y9:o];/
}; fQU_A
#pragma pack() a.<!>o<t:
sizeof(S2)结果为24. @S012} xH
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. [o'}R`5)
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. +w?1<Z
v|kL7t)}
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; QD[l 6
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. IetV ]Ff6
a b Z${@;lgP
S1的内存布局:11**,1111, B@3>_};Ct
c S1.a S1.b d BW)t2kR&
S2的内存布局:1***,11**,1111,****11111111 zHj_q%A
KrECAc
这里有三点很重要: @0:mP
1.每个成员分别按自己的方式对齐,并能最小化长度 }>Lz\.Z/+[
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 ku5g`ho
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 "%t !+E>nr
g.EKdvY"%H
1 pzd
网友xue23(xue23) 的答案和分析: qr/N ?,
\AR3DDm
有程序查一下各个变量的内存地址得知: 6dCqS
各个变量在内存中的位置为 iu,Bmf^oD
c***aa** 6? (8KsaN
bbbb**** dZbG#4oO
dddddddd )ULxB'Dm
测试代码为: gtP;Qw'
s2 ss; ;/nR[sibN
cout << "ss.c = " << &ss << endl ; fI(H
:N
cout << "ss.d.a = " <<&ss.d.a << endl; 01^W Py9l
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; !FnH;
print out 各个变量的内存地址不就可以看出来了吗。 3412znM&
"V_PWEi
所以答案是24,2. _bq2h%G=8
Eh;~y*k\
但是我的想像中应该是这样的分布情况: |c>A3 P$=B
c******* )6zwprH!
aa**bbbb g>R md[!/
dddddddd d3C*]|gQ
QO~TuC
不知为什么会c和a放在一起,组成8位长度。