Intel和微软同时出现的C语言面试题 I-fjqo3
#pragma pack(8) X/
\5j
abHW[VP9
struct s1{ |b@H]c;"
short a; y}fF<qih'>
long b; {EoRY/]
}; 98%M`WY
]y4(WG;:
struct s2{ H9x,C/r,
char c; QJcaOXyMS
s1 d; T[z]~MJL
long long e; `sS\8~A
}; ii.L]#3y
nPW?DbH +
#pragma pack() J H%^FF2
e~#"#?
问 ,_JhvPWR,)
1.sizeof(s2) = ? d$3;o&VUNI
2.s2的s1中的a后面空了几个字节接着是b? X}Ey6*D:
]%{.zl!
UN~dzA~V
2 kOFyD
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: p)t1]<,Of
W>ziA
网友rwxybh(行云)的答案: 14[+PoF^A
内存布局是 $[L8UUHY<8
1*** 11** ; bBz<
1111 **** ArFsr
1111 1111 Vvth,
E&\dr;{7
所以答案就是24和3 6m.ChlO/
-8L22t
下面是一个测试的程序,试一试就知道了,我用的是VC2005 F{:ZHCm
b7
pD#v
#pragma pack(8) E%eTjvvxus
WIytgM
struct s1{ (xp<@-
short a; // 2 BYtes S$CO T)7
long b; // 4 Bytes hX-([o
}; Qz T>h
struct s2{ AL%gqt]
char c; // 1 Byte E8TJ*ZU
s1 d; // 8 Bytes U
Hej5-B
long long e; // 8 Bytes yIab3/#`
}; 9uXu V$.
// 1*** 11** U>q&p}z0H
// 1111 **** AN!MFsk
// 1111 1111 [DW}z
// 3)F9:Tzw1
Cm~h\+"
// 00 01 02 03 04 05 06 07 \9U4V>p
// 00 01 02 03 04 05 06 07 y8Q96zi
// 00 01 02 03 04 05 06 07 =h?Q.vad
// .Z,3:3,]
#pragma pack() ;j#$d@VG"
f8ap+][
int main(int argc, char* argv[]) 2?",2x09
{ oYYns%r}{
s2 a; _xg4;W6M=
char *p = (char *)&a; }pE8G#O&
for(int i=0;i<24;++i) \htL\m^$9
p = (char)(i%8); q|E0Y
printf("%d\n",sizeof(a)); R^%uEP
printf("c=0x%lx\n",a.c); *cjH]MQ0Ak
printf("d.a=0x%x\n",a.d.a); e
~X<+3<
printf("d.b=0x%x\n",a.d.b); {K{&__Nk
printf("e=0x%llx\n",a.e); +%Vbz7+!
return 0; )$V &Nf
} vepZod}D
结果: .g CC$
24 x^UE4$oo
c=0x0 E$$pO.\
d.a=0x504 Mo+mO&B
d.b=0x3020100 NDG3mCl
e=0x706050403020100 tMN^"sjf*
~,
hPi
0D[D;MW
网友 redleaves (ID最吊的网友)的答案和分析: $rB20!
dx=\Pq
如果代码: }3t bqFiH
#pragma pack(8) CgLS2
struct S1{ 2b+0}u>a
char a; /?POIn+0o
long b; "W_C%elg
}; _1z|QC
struct S2 { 5rAI[r
9
char c; /Q7cQ2[EU
struct S1 d; :!omog
long long e; j@1rVOmK
}; E,Q>jH
#pragma pack() GCxtW FXH
sizeof(S2)结果为24. o<`)cb }
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. Sz\"*W;>
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. T [w]w
P]bq9!{1
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; V\ud4
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. O[p;IG`
a b Evz;eobW/
S1的内存布局:11**,1111, JHY0J
&4s
c S1.a S1.b d a:C'N4K
S2的内存布局:1***,11**,1111,****11111111 0>
pOP
B,sv! p+q5
这里有三点很重要: 5xZ *U
1.每个成员分别按自己的方式对齐,并能最小化长度 u$%>/cv
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 ,`7;S,f
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 `aFy2x`3
<1(:W[M
j @c
fR
网友xue23(xue23) 的答案和分析: M@a?j<7P,m
.xtjB8gc
有程序查一下各个变量的内存地址得知: F+;{s(wx
各个变量在内存中的位置为 -.A8kJ
c***aa** p100dJvq
bbbb**** :kycIM]s
dddddddd Mis t,H7
测试代码为: 2#4_/5(j*
s2 ss; a8T<f/qW k
cout << "ss.c = " << &ss << endl ; (fgX!G[W
cout << "ss.d.a = " <<&ss.d.a << endl; O_*(:Z
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; !B==cNq
print out 各个变量的内存地址不就可以看出来了吗。 xF)AuGdp\
mU1lEx$
所以答案是24,2. 1sFTXl
WA-`
*m$v
但是我的想像中应该是这样的分布情况: m`<Mzk.u<
c******* RUTlwTdv
aa**bbbb h+mM
dddddddd 2[&3$-]
Jji~MiMn
不知为什么会c和a放在一起,组成8位长度。