Intel和微软同时出现的C语言面试题 f4s[R0l
#pragma pack(8) ` 2|~Z
H
6N.mSnp
struct s1{ 0]8+rWp|Nz
short a; FVG|5'V^
long b; 3leg,qd
}; H*|Bukgt/M
&.kg8|s{
struct s2{ t,N-|
char c; v)N6ZOj*C
s1 d; i#lvt#2J0
long long e; m'k`p5[=h
}; &g,K5at
R2Tvo?xI7
#pragma pack() L3q)j\ls
"r cPJX
问 2 T{PIJg3
1.sizeof(s2) = ? \,
n'D
2.s2的s1中的a后面空了几个字节接着是b? BO[Q"g$Kon
UkNC|#l)
H#U{i
aC3\Hs
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: avO+1<`4B
ABhza|
网友rwxybh(行云)的答案: DJ}xD&G
内存布局是 xx;'WL,g
1*** 11** IvIBf2D;Q
1111 **** NL&g/4A[a
1111 1111 &%u,b~cL?
g/z9bOgIX
所以答案就是24和3 8f^URN<x
C==tJog[
下面是一个测试的程序,试一试就知道了,我用的是VC2005 yF0,}
Zpb3>0<R
#pragma pack(8) m)_1->K
/UyW&]nK
struct s1{ [%l+
C~m
short a; // 2 BYtes 58e{WC
long b; // 4 Bytes '4Z%{.;
}; f+xGf6V
struct s2{ m_rR e\
char c; // 1 Byte .e.vh:Sz
s1 d; // 8 Bytes qx0o,oZN!
long long e; // 8 Bytes =5Q;quKu^5
}; (!X:[Ah*$
// 1*** 11** 8" 8{Nf-"
// 1111 **** xDADJ>u2K
// 1111 1111 m$LZ3=v%8
// fil6w</L
73}k[e7e
// 00 01 02 03 04 05 06 07 /Z2*>7HM8[
// 00 01 02 03 04 05 06 07 w5n>hz_5
// 00 01 02 03 04 05 06 07 nj7Ri=lyS
// w5|@vB/pj
#pragma pack() '2[ _U&e
-m'a%aog
int main(int argc, char* argv[]) ?U-p
jjM
{ w4L\@y3
s2 a; ^;@Bz~Z
char *p = (char *)&a; n+uq|sYVa
for(int i=0;i<24;++i) )1x333.[c
p = (char)(i%8); (OG@]|-
printf("%d\n",sizeof(a)); /-|xxy
printf("c=0x%lx\n",a.c); mz\m^g3
printf("d.a=0x%x\n",a.d.a); >MQW{^
printf("d.b=0x%x\n",a.d.b); `}Q;2 F
printf("e=0x%llx\n",a.e); 5,Q('t#J
return 0; A5H[g`&
} &OzJ^G\o
结果: M$&>"%Oi
24 _l8oB)
c=0x0 H~V=TEj
d.a=0x504 W2^eE9
d.b=0x3020100 A{+ZXu}
e=0x706050403020100 -;~_]t^a
#='#`5_5
pu>LC6m3a
网友 redleaves (ID最吊的网友)的答案和分析: um8ZhXq
J7cqn j
如果代码: Yhsb$wu
#pragma pack(8) ,RT\&Ze5
struct S1{ 5<a<!]|C
char a; czZ-C +}%
long b; A(s/Nz>
}; A1'IK.
struct S2 { 'M'LJ.,"/
char c; I"
j7
struct S1 d; =)I{KT:y
long long e; O/-OW: 03
}; +M.|D,wg2
#pragma pack() rW6w1
sizeof(S2)结果为24. &Y#9~$V=
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. HE,wEKp
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 9QX{b+}"e
D3HB`{
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
>=Rb:#UM
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. jgMWjM6.
a b G:&Q)_
S1的内存布局:11**,1111, l{pF^?K
c S1.a S1.b d 4PF4#
S2的内存布局:1***,11**,1111,****11111111 U)l>#gf8
/KV@Ce\
这里有三点很重要: _|Dt6
1.每个成员分别按自己的方式对齐,并能最小化长度 d*AV(g#B
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 &WRoNc
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 ~ZDdzp>
tllg$CQ5
qzmZ/z96
网友xue23(xue23) 的答案和分析: 0WPxzmY
4OIN@n*4
有程序查一下各个变量的内存地址得知: ypifXO;m7
各个变量在内存中的位置为 iH$N HfH
c***aa** Uis
P
8/k
bbbb**** dJ;;l7":~
dddddddd G?V3lQI1n
测试代码为: gSv<.fD"
s2 ss; $N
]P#g?Q
cout << "ss.c = " << &ss << endl ; W ][IHy<
cout << "ss.d.a = " <<&ss.d.a << endl; 23fAc"@ B
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; 9"aTF,'F/
print out 各个变量的内存地址不就可以看出来了吗。 v m$v[
q_K1L
所以答案是24,2. 2>r.[
_HL3XT
但是我的想像中应该是这样的分布情况: [&4y@
c******* tw(2V$J
aa**bbbb ZEMo`O
dddddddd ?@,:\ ,G
:Oj+Tc9A
不知为什么会c和a放在一起,组成8位长度。