Intel和微软同时出现的C语言面试题 RWRqu }a
#pragma pack(8)
_!_^B
'yosDT2{#
struct s1{ Hd\.,2a"
short a; f}~=C2R1<!
long b; Q#X'.](1
}; p+pu_T;~
&mW7FR'(
struct s2{ cyLl,OA
char c; =van<l4b#n
s1 d; y"Pd>61h
long long e; K5rra%a-7
}; P5H_iH
`g_r<EY8/
#pragma pack() m^\&v0
<-mhz`^
问 Y_}_)nE@m
1.sizeof(s2) = ? G!`PP
2.s2的s1中的a后面空了几个字节接着是b? 9[`c"Pd
Lu~E5 ,
k*u6'IKi.4
joDqv,iW8
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: diNAT`|?#
op@=0d??
网友rwxybh(行云)的答案: g${JdxR:
内存布局是 bSz@@s.
1*** 11** @tJ4^<`P{
1111 **** ')}itS8
1111 1111 ,J'_Vi
.hM t:BMf*
所以答案就是24和3 E]v]fy"
Zb&pH~ 7
下面是一个测试的程序,试一试就知道了,我用的是VC2005 !g`I*ZE+e
lX-i <0`
#pragma pack(8) q'/o=De
o%f:BJS
struct s1{ v`c;1 ?=,q
short a; // 2 BYtes eh%{BXW[p
long b; // 4 Bytes uts>4r>+
}; H0!$aO
struct s2{ @( \R@`#
char c; // 1 Byte mlCBstt{
s1 d; // 8 Bytes j/_&]6!
long long e; // 8 Bytes o<J6KTLv
}; ^Vhl@
// 1*** 11** qe'ssX;
// 1111 **** pGfGGY>i%
// 1111 1111 /\_n5XI1
// :5['V#(o
E]8uj8K3]
// 00 01 02 03 04 05 06 07 ]=%6n@z'
// 00 01 02 03 04 05 06 07 _Rb2jq(&0
// 00 01 02 03 04 05 06 07 q2r$j\L%
// 7p hf
#pragma pack() $}r.fji,c
}zS5o
[OE
int main(int argc, char* argv[])
,v
2^Ui
{ %.D!J",\/K
s2 a; /D1Lh_,2
char *p = (char *)&a; sa&`CEa
for(int i=0;i<24;++i) O_ZYm{T[7
p = (char)(i%8); u}%6=V
printf("%d\n",sizeof(a)); !Vg=l[
printf("c=0x%lx\n",a.c); tHo|8c~[
printf("d.a=0x%x\n",a.d.a);
K,JK9)T
printf("d.b=0x%x\n",a.d.b); \EU^`o+
printf("e=0x%llx\n",a.e); Ssuz%*
return 0; /M::x+/T
} <5mv8'{L
结果: w3"L5;oH
24 `Oi#`lC\
c=0x0 s*_fRf:
d.a=0x504 1og+(m`BL
d.b=0x3020100 G&Dl($
e=0x706050403020100 \'<P~I&p
t$~'$kM)<
/:Gy .
网友 redleaves (ID最吊的网友)的答案和分析: yci} #,nb
m(?{#aaq
如果代码: b1cVAfUP
#pragma pack(8) <ShA_+Nd
struct S1{ i7 21(1
char a; $i6z)]rjg
long b; G'p322Bu
}; T)OR HJ&,
struct S2 { xpO;V}M|
char c; [FrLxU
struct S1 d; czU"
long long e; @M B)B5
}; pqb`g@
#pragma pack() oQ,<Yx%E3
sizeof(S2)结果为24. v*qbzW`
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. -aVC`
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 7n.Oem
.gmS1ju
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; !`RMXUV
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. V" 8 G-dK
a b _<{<b
S1的内存布局:11**,1111, &^DVSVqs^
c S1.a S1.b d qbeUc5`1
S2的内存布局:1***,11**,1111,****11111111 f+hHc8g
[:#K_EI5%
这里有三点很重要: 8{/.1:
1.每个成员分别按自己的方式对齐,并能最小化长度 D>7J[ Yxg-
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 J{prI;]K
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 (YYg-@IO
Jy%?"wn
OR!W3
@
网友xue23(xue23) 的答案和分析: Fz,jnV9=j
+)WU:aKI
有程序查一下各个变量的内存地址得知: JffaT_"\
各个变量在内存中的位置为 ^d{5GK'
c***aa** !rr,(!Ip?O
bbbb**** dd<l;4(
dddddddd z)U7
测试代码为: Dqii60
s2 ss; |u^S}"@3sU
cout << "ss.c = " << &ss << endl ; :o{,F7(P
cout << "ss.d.a = " <<&ss.d.a << endl; ,0,FzxX0!
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; T:Nk9t$W7@
print out 各个变量的内存地址不就可以看出来了吗。 $.,B2} '
>@Ht*h{~
所以答案是24,2. qf\W,SM
?.%dQ0
但是我的想像中应该是这样的分布情况: SU4i'o
c******* ]#^v754X^T
aa**bbbb 6(d6Uwc`
dddddddd <A8>To<
6V]m0{:E
不知为什么会c和a放在一起,组成8位长度。