Intel和微软同时出现的C语言面试题 8<.C3m
6h
#pragma pack(8) e&>;*$)
kqce[hgs<
struct s1{ C0S^h<iSe*
short a; R
zf
long b; PQK(0iCo4
}; wD68tG$
h~(G$':^
struct s2{ L]d-hs
char c; NZ/yBOD(
s1 d; S,<EEtXQ
long long e; TjQvAkT
}; )RO<o O
{"&SJt[%X
#pragma pack() UW9?p}F
s<9RKfm
问 -1ce<nN
1.sizeof(s2) = ? b&=5m
2.s2的s1中的a后面空了几个字节接着是b? :>TEDy~O%
U Z|HJ8_
W
D
T]!
q EP
4
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: abJ"
[
3&6#F"7
网友rwxybh(行云)的答案: 6ezS {Q
内存布局是 34wkzu
1*** 11** MXzVgy
1111 **** ;Ra+=z}>
1111 1111 (y?ITz9
"TUe%o
所以答案就是24和3 {}QB|IH`
8me ]JRw
下面是一个测试的程序,试一试就知道了,我用的是VC2005 Ux#x#N
`ORECg)
#pragma pack(8) _UT$,0u_i
&Ch#-CUE/
struct s1{ FL8g5I
short a; // 2 BYtes esHQoIhd
long b; // 4 Bytes %e`$p=m
}; K
=wBpLB
struct s2{ j:,NE(DF
char c; // 1 Byte hSK;V<$[Z
s1 d; // 8 Bytes ZVbl88,(l
long long e; // 8 Bytes ,SQZD,3v4
}; k6Uc3O
// 1*** 11** ]D@0|
// 1111 **** {@<J_A
// 1111 1111 Fe.t/amS/
// _[Vf547vS
H)aQ3T4N5
// 00 01 02 03 04 05 06 07 xB@|LtdO9;
// 00 01 02 03 04 05 06 07 Up:<=Kgci
// 00 01 02 03 04 05 06 07 E;d7ch
// q~@]W=
#pragma pack() fZxIY,
v^ /Q 8Q
int main(int argc, char* argv[]) `Pw*_2
{ #-8\JEn
s2 a; y$3;$ R^
char *p = (char *)&a; K9vIm4::d$
for(int i=0;i<24;++i) =l.+,|ZH!
p = (char)(i%8); *26334B.R
printf("%d\n",sizeof(a)); "+zCS|
printf("c=0x%lx\n",a.c); RJy=pNztm
printf("d.a=0x%x\n",a.d.a); *=fr8
printf("d.b=0x%x\n",a.d.b); `+t.!tv!
printf("e=0x%llx\n",a.e); gr-fXZO
return 0; /B5-Fx7j3
} Hg9CZMko
结果: oG7q_4+&
24 *xE,sj+(
c=0x0 fK&e7j`qO
d.a=0x504 S!PzLTc
d.b=0x3020100
|7B!^
K
e=0x706050403020100 DI`%zLDcY
a=XW[TY1
Sa"9^_.2#
网友 redleaves (ID最吊的网友)的答案和分析: ~2d:Q6
(~$/$%b
如果代码: :L_BG)dM
#pragma pack(8) kD) $2I?
struct S1{ v`V7OD#:j]
char a; J(#mtj>v_
long b; *_ +7ni
}; (_r EAEo
struct S2 { +3i7D
char c; KluA
struct S1 d; BZb]SoAL
long long e; f'q 28lVf
}; r-kMLw/)
#pragma pack() \<vNVz7.D
sizeof(S2)结果为24. ^v9|%^ug
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. F?m?UQS'u
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. ?EU\}N J
O:#+%
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; OzT#1T1'c
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. Pv<FLo%u<
a b q{die[J
S1的内存布局:11**,1111, CK_(b"
c S1.a S1.b d _ nP;Fx
S2的内存布局:1***,11**,1111,****11111111 ;nmM7TZ;
\Hqc9&0
这里有三点很重要: uhV0J97
1.每个成员分别按自己的方式对齐,并能最小化长度 p.fF}B
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 )4xu^=N&as
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 TP1S[`nR
D\^WXY5e%y
IMQ]1uq0$
网友xue23(xue23) 的答案和分析: z"DkFvA
NHw x:-RH
有程序查一下各个变量的内存地址得知: 9umGIQHnil
各个变量在内存中的位置为 f>$h@/-*
c***aa** Ni*Wz*o
bbbb**** ^IgY d*5
dddddddd Bn]K+h\E
测试代码为: IGFGa@C
s2 ss; I~'*$l
cout << "ss.c = " << &ss << endl ; ,pq{& A
cout << "ss.d.a = " <<&ss.d.a << endl; &"uV~AM
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; /T0nLp`gi
print out 各个变量的内存地址不就可以看出来了吗。 LF*Q!
~9D~7UR
所以答案是24,2. BzpP7 ZWV
%u p}p/?
但是我的想像中应该是这样的分布情况: b'x$2K;E
c******* 2aNT#J"_
aa**bbbb tn/T6C^)
dddddddd TTI81:fku
tUE'K.-
不知为什么会c和a放在一起,组成8位长度。