Intel和微软同时出现的C语言面试题 ErgWs Aw-
#pragma pack(8) r7^v@
%j2$ ezud
struct s1{ W0}FOfL9
short a; c|K:oi,z
long b; "y5bODq3t
}; X3~`~J
B*9?mcP\
struct s2{ <AK9HPxP
char c; Dy:r)\KX
s1 d; 4aW[`
long long e; +N'&6z0Wf
}; )1YX+',"
4P"XT
#pragma pack() y.s\MWvv>u
9m\Yi
问 qz.l
1.sizeof(s2) = ? abCxB^5VL
2.s2的s1中的a后面空了几个字节接着是b? jfVw{\l
4?bvJJuf)
c]i;0j? Dl
2dK:VC4U
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: Wc,`L$Jx
ru~!;xT
网友rwxybh(行云)的答案: <;uM/vSi
内存布局是 nyxoa/
1*** 11** awjAv8tPO!
1111 **** L}'^FqO[IW
1111 1111 hc|#JS2H@y
9M;Y$Z
所以答案就是24和3 $~VIx% h
sZ7~AJ
下面是一个测试的程序,试一试就知道了,我用的是VC2005 H/.UDz
S<-5<Pg
#pragma pack(8) E25w^x2
I*$-[3/
struct s1{ 1=C<aRZ b^
short a; // 2 BYtes #k[Y(_
long b; // 4 Bytes ~Nf|,{[(5
}; 2+b}FVOe\
struct s2{ rq Uk_|Xa
char c; // 1 Byte 0Wc_m;
s1 d; // 8 Bytes bUds E1f
long long e; // 8 Bytes u } +?'B)
}; U0iV
E+)Bt
// 1*** 11** W BA7G
// 1111 **** d0&
// 1111 1111 d @ l
// qJ<l$Ig
MJCz %zK
// 00 01 02 03 04 05 06 07 z@V9%xF-3
// 00 01 02 03 04 05 06 07 k@h0 }%
// 00 01 02 03 04 05 06 07 UX<)hvKj
// 0\s&;@xKk
#pragma pack() r .
(}
@; I9e
int main(int argc, char* argv[]) @A<~bod
{ euW
s2 a; 6j+X@|2^
char *p = (char *)&a; "WO0rh`
for(int i=0;i<24;++i) ]0MuXiR
p = (char)(i%8); 7,8TMd1`M
printf("%d\n",sizeof(a)); F%af05L[
printf("c=0x%lx\n",a.c); /L5:/Z
printf("d.a=0x%x\n",a.d.a); E H%hL5(
printf("d.b=0x%x\n",a.d.b); 3 `mtc@*
printf("e=0x%llx\n",a.e); m{~L Fhhd1
return 0; JNJ6HyCU
} &%8IBT
结果: &-X51O C
24 UI%4d3
c=0x0 kHhku!CH
d.a=0x504 m|t\w|B2
d.b=0x3020100 c&{= aIe w
e=0x706050403020100 b!`Ze~V
rKd|s7l
V<;_wO^
网友 redleaves (ID最吊的网友)的答案和分析: IN;9p w
bZK^q B
如果代码: K[
S>EITr
#pragma pack(8) H*P+>j&
struct S1{ (TO<SY3AB
char a; Q9B!0G.-bs
long b; moh,a B#
}; dK,=9DQy5
struct S2 { C3~~h|:
char c; 7,V_5M;t
struct S1 d; C8)Paop$
long long e; .tyV=B:h
}; x K\i&A
#pragma pack() _x#y
sizeof(S2)结果为24. d6-q"
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. qt/6o|V
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. pGy k61
%g3QE:(2@q
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; p=Leoc1
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. ,j\uvi(Y
a b }J92TV
S1的内存布局:11**,1111, ?i\V^3S n$
c S1.a S1.b d l @@pXg3
S2的内存布局:1***,11**,1111,****11111111 jsr)
GC3d7
这里有三点很重要: AN[pjC<
1.每个成员分别按自己的方式对齐,并能最小化长度 JP
{`^c
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 ImH9 F\
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 4gdXO
l[m*csDk"
H1KXAy`&
网友xue23(xue23) 的答案和分析: R[fQ$` M
c'Z)uquvP
有程序查一下各个变量的内存地址得知: TL7qOA7^X
各个变量在内存中的位置为 h^`@%g9 S
c***aa** MBKF8b'k
bbbb**** kApD D[ N
dddddddd 8oRq3 "
测试代码为: Pc5C*{C
s2 ss; ) .' + {
cout << "ss.c = " << &ss << endl ; Nlwt}7
cout << "ss.d.a = " <<&ss.d.a << endl; Z("N
*`VP;
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; \_(0V"
print out 各个变量的内存地址不就可以看出来了吗。 qNrLM!Rj
Fl{~#]
所以答案是24,2. xy$aFPH!-
a\Gd;C ^`
但是我的想像中应该是这样的分布情况: Nl%5OBm
c******* Ukf:m&G
aa**bbbb 0JR)-*
dddddddd )"M;7W?R0
?A r}QN
不知为什么会c和a放在一起,组成8位长度。