Intel和微软同时出现的C语言面试题 #OJsu
#pragma pack(8) ahhVl=9/ao
s<sqO,!
struct s1{ TEE$1RxV(
short a; RIC'JLWQ
long b; =3a`NO5!
}; |2
g }i\
c5mv4 MC
struct s2{ +7sdQCO(Co
char c; [A
yq%MA
s1 d; '355Pce/
long long e; "@$o'rfT
}; VrQw;-rQ
4Qz
#pragma pack() sog?Mvoq
KG4~t=J`
问 1&i!92:E
1.sizeof(s2) = ? :uu\q7@'
2.s2的s1中的a后面空了几个字节接着是b? -XPGl
G"O%u|7
.J&NM(qeZ
8ftLYMX@
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: HqcXP2
S]K^wj[
网友rwxybh(行云)的答案: w^A8ZT0^7
内存布局是 Kcsje_I-M
1*** 11** F2z^7n.S
1111 **** +M-' K19
1111 1111 U11rj,7
!CPv{c`|qg
所以答案就是24和3 0aQNdi)b
*yiJw\DRN
下面是一个测试的程序,试一试就知道了,我用的是VC2005 O<L/m[]
)n5]+VTZ5
#pragma pack(8) MR#jI
Qk Gr{
struct s1{ h'MX{Wm.
short a; // 2 BYtes qAivsYN*
long b; // 4 Bytes X'7 T" 5!
}; jcXb@FE6
struct s2{ ##}a0\x|
char c; // 1 Byte I"Ju3o?u
s1 d; // 8 Bytes y;;^o6Gnw
long long e; // 8 Bytes h+R}O9BD
}; A>R ^iu
// 1*** 11** }b)?o@9}:
// 1111 **** 5\:#-IYJ
// 1111 1111 s^L\hr
// jM2gu~
o'>jO.|
// 00 01 02 03 04 05 06 07 ""d3ownKhw
// 00 01 02 03 04 05 06 07 ir \ d8.
// 00 01 02 03 04 05 06 07
[GU!],Y
// _L%/NXu,
#pragma pack() SY>N-fW\H:
ds5<4SLj
int main(int argc, char* argv[]) w?oIKj
{ h,TDNR<1L
s2 a; 6&.[:IHw
char *p = (char *)&a; + #S]uC
for(int i=0;i<24;++i) 0kmVP~K
p = (char)(i%8); TD!QqLW
printf("%d\n",sizeof(a)); 8eWb{nuJ>
printf("c=0x%lx\n",a.c); X k<X:,T
printf("d.a=0x%x\n",a.d.a); ,i>5\Yl%
printf("d.b=0x%x\n",a.d.b); h8pc<t\6
printf("e=0x%llx\n",a.e); `\e@O#,^yI
return 0; sAnStS=>
} A3C<9wXx
结果: KXicy_@DC`
24 ?y]3kU
c=0x0 w y:.
d.a=0x504 j><.tA~i
d.b=0x3020100 ${6 ;]ye
e=0x706050403020100 (VC{#^2l
Yw?%>L
Vwm\a]s
网友 redleaves (ID最吊的网友)的答案和分析: h=d&@k\g
qI8{JcFx:
如果代码: "9>#Q3<N
#pragma pack(8) ?>4^e:
struct S1{ -qid.
char a; R^%7|
long b; -PEpy3dMY
}; {{@3r5KGl
struct S2 { ;M@/AAZ
char c; KZ/}Iy>As
struct S1 d; ro^Y$;G
long long e; A6TNtXk
}; )ae/+Q8
#pragma pack() ew}C*4qH
sizeof(S2)结果为24. mgH4)!Z*56
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. //V?rs
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. |_!xA/_U'T
Dugr{Y/0
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
LL kAA?P
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. 0($MN]oZa
a b urXM}^
S1的内存布局:11**,1111, TtkB
c S1.a S1.b d s{$c 8
S2的内存布局:1***,11**,1111,****11111111 zx;x@";p
Fv#ToT:QXe
这里有三点很重要: NpH)K:$#%
1.每个成员分别按自己的方式对齐,并能最小化长度 )Bd+jli|s
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 -I\_v*nA
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 F?5kl/("
1wGd5>GDA
{[)J~kC+
网友xue23(xue23) 的答案和分析: X$PT-~!a
d-xKm2sH
有程序查一下各个变量的内存地址得知: 9dy"Y~c
各个变量在内存中的位置为 pS0-<-\R
c***aa** -pa.-@
bbbb**** C.pNDpx-
dddddddd Gh42qar`
测试代码为: ?Mji'ZW}
s2 ss; #Cbn"iYee
cout << "ss.c = " << &ss << endl ; ]O&TU X@)
cout << "ss.d.a = " <<&ss.d.a << endl; TZ-n)rC)v
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; n'%*vdHKm
print out 各个变量的内存地址不就可以看出来了吗。 s~M!yuH
qXP)R/~OZ
所以答案是24,2. f85j?Jm
\=,+weGw@
但是我的想像中应该是这样的分布情况: CF =#?+x
c******* .^P^lQT]>
aa**bbbb shnfH
dddddddd HTkce,dQ
q&
4Z.(
不知为什么会c和a放在一起,组成8位长度。