Intel和微软同时出现的C语言面试题 %zelpBu+
#pragma pack(8) ~o%-\^oc
)R +o8C
struct s1{ V?O%k d
short a; EIYM0vls(
long b; hv"toszj\
}; z\E"={P&
TcP1"wc
struct s2{ jF3!}*7,
char c; 1 IlR
s1 d; 0%qUTGj
long long e; 3'"M31iA
}; "~(&5M\8`
vW{cBy
#pragma pack() @*uX[)
9kF#*
问 Me}TW!GC
1.sizeof(s2) = ? YMi(Cyja&
2.s2的s1中的a后面空了几个字节接着是b? YDNqWP7s
v2n0[b0
VBX#
!K1Q
r9M={jC
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: 87K)qsv8
Z8&C-yCC
网友rwxybh(行云)的答案: 2&Byq
内存布局是 VRX"
@uCD
1*** 11** Wv0'?NL.
1111 **** BY0|exW
1111 1111 rEhf_[Dv
_onp%*
所以答案就是24和3 >jX
UO
KCk?)Qv
下面是一个测试的程序,试一试就知道了,我用的是VC2005 _=L;`~=C9e
7rSUSra
#pragma pack(8) U R@BSK'
"k-ov9yK
struct s1{ N}Ks[2
short a; // 2 BYtes ?*'$(}r3
long b; // 4 Bytes ]|N4 #4
}; {F:v$ K
struct s2{ p{a]pG+3
char c; // 1 Byte e_=pspnZ
s1 d; // 8 Bytes ^Q=y^fx1
long long e; // 8 Bytes Q==v!"Gi|
}; RW7oL:$dt
// 1*** 11** e(#IewKp
// 1111 **** &ZE\@Vc
// 1111 1111 cIr1"5POXK
// zw:C*sY
;a#*|vx
// 00 01 02 03 04 05 06 07 hRr1#'&
// 00 01 02 03 04 05 06 07 DvX3/z#T
// 00 01 02 03 04 05 06 07 s$Zq/l$1x
// v'Vt
.m&9&
#pragma pack() D4q>R;
"Py Wo
int main(int argc, char* argv[]) 'yd@GQM&
{ #jZ@l3
s2 a; `<J#l;y
char *p = (char *)&a; cVay=5].
for(int i=0;i<24;++i) Hl3)R*&'J
p = (char)(i%8); NGD*ce"w
printf("%d\n",sizeof(a)); (
f,J_
printf("c=0x%lx\n",a.c); =#(0)p$EC
printf("d.a=0x%x\n",a.d.a); rQEi/
printf("d.b=0x%x\n",a.d.b);
s8_aL)@f
printf("e=0x%llx\n",a.e); rer|k<k;]G
return 0; ,?k%jcR
} i<m$#6<Z
结果: Taf
n:Nw}
24 /zG+]
c=0x0 PXosFz~
d.a=0x504 's[BK/
d.b=0x3020100 #SQvXMT
e=0x706050403020100 1OJ*wI*
efjO8J[uk-
K 3Yw8t2J
网友 redleaves (ID最吊的网友)的答案和分析:
)C
{h1
`
7qg<[
如果代码: l(%k6
#pragma pack(8) yI8m%g%
struct S1{ PK6*}y
char a; gg-};0P-
long b; Wp5]Uk
}; c^=R8y-N
struct S2 { 4\N_ G
@
char c; {l2N&
struct S1 d; d/{Q
t
long long e; 84=-Lw
}; dEASvD'
#pragma pack() Q.,DZp
sizeof(S2)结果为24. z)lM2x>|*
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. W+gpr|R2
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 3;*z3;#}
[p ii
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; AnNPTi
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. __!m*!sd
a b =fl%8"%N&
S1的内存布局:11**,1111, eZg$AOpU
c S1.a S1.b d [O2h-`
S2的内存布局:1***,11**,1111,****11111111 {6'*Phw
Xv0F:1
这里有三点很重要: McjS)4j&.
1.每个成员分别按自己的方式对齐,并能最小化长度 :pwa{P
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 2 H[ ; v +
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 Dl%?OG<
n)#Lh
7X"
F>N+<Z
网友xue23(xue23) 的答案和分析: 3gpo
%
HsnG4OE
有程序查一下各个变量的内存地址得知: Ikj=`,a2B
各个变量在内存中的位置为 Fn!SGX~kx$
c***aa** w
NH9WG
bbbb**** ivfXat-
dddddddd zmI5"K"'F
测试代码为: I}+;ME|<2
s2 ss; &]< 3~6n
cout << "ss.c = " << &ss << endl ; 1Bg_FPu
cout << "ss.d.a = " <<&ss.d.a << endl; EKuSnlTXba
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; )lh8
k{
print out 各个变量的内存地址不就可以看出来了吗。 Seda }
?*H9-2W@
所以答案是24,2. /b#q*x-b
+I52EXo
但是我的想像中应该是这样的分布情况: "Sjr_!u
c******* p0M=t-
aa**bbbb +8AvTSgX%
dddddddd QHzgy?
%/T7Z;d
不知为什么会c和a放在一起,组成8位长度。