Intel和微软同时出现的C语言面试题 n5C,Z!)z
#pragma pack(8) ;-`NT`
#2
i@+m<YS:2>
struct s1{ )tBz=hy#
short a; _p8u
&TZ
long b; 0s-K oz
}; nnn\
zd%f5L('
struct s2{ iYB c4'X
char c; c/+6M
s1 d; QD0x^v8
long long e; KWo Ps%G
}; JE}VRMNr
5,,'hAq_
#pragma pack() !@lx|=#
bK6^<,~
问 6MM\nIU)/
1.sizeof(s2) = ? BR|0uJ.M
2.s2的s1中的a后面空了几个字节接着是b? ].rKfv:
j-BNHX
JL
G!;sov
y ]t19G+
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: JRC2+BU
/
w=fWW^>bP
网友rwxybh(行云)的答案: <B>qEa_I
内存布局是 >bWpj8Kv
1*** 11** FNUs
.d"
1111 **** %P ~;>4i,
1111 1111 Jd/d\P
d,?D '/
所以答案就是24和3 Ee MKo
c<Cf|W
下面是一个测试的程序,试一试就知道了,我用的是VC2005 9]+zZP_#
lwfS$7^P
#pragma pack(8) T(u;<}e@[
+JYb)rn$^
struct s1{ F)~>4>hPr
short a; // 2 BYtes /TsXm-g#
long b; // 4 Bytes l F64g
}; sDBSc:5+e
struct s2{ ~8&->?{
char c; // 1 Byte MH)V=xU|)
s1 d; // 8 Bytes .'o=J`|
long long e; // 8 Bytes Eb~vNdPo
}; xGyl7$J
// 1*** 11** *bo| F%NAz
// 1111 **** +pgHCzwJE
// 1111 1111 ^[SW07o~
// I)yaR+l
}O+xs3Uv
// 00 01 02 03 04 05 06 07 iPl,KjGk
// 00 01 02 03 04 05 06 07 ftMlm_u
// 00 01 02 03 04 05 06 07 Ws5N|g
// aHC%:)ww:
#pragma pack() ~ zfF*A
%J-:%i
int main(int argc, char* argv[]) ;76+J)
{ 64mh. j
s2 a; 4G:~|N.{p
char *p = (char *)&a; >{{ds--
for(int i=0;i<24;++i) t0fgG/f'
p = (char)(i%8); @D-I@Cyl
printf("%d\n",sizeof(a)); @_"cMU!
printf("c=0x%lx\n",a.c); nGWy4rY2S
printf("d.a=0x%x\n",a.d.a); gdD|'h
printf("d.b=0x%x\n",a.d.b); oUsfO-dET^
printf("e=0x%llx\n",a.e); 7:F0?l*
return 0; EGI$=Y
} HqsqUS3[
结果: [2xu`HT02
24 Y [)mHs2
c=0x0
;UXV!8SM
d.a=0x504 h8O\sKn
d.b=0x3020100 u(3 uZ:
e=0x706050403020100 {,uSDIOj$
rb@[Edj
+a*Ic8*
网友 redleaves (ID最吊的网友)的答案和分析: -q9m@!L
Uu8ayN j
如果代码: h0m5oV
#pragma pack(8) 6 8n ;#-X
struct S1{ T^]]z}k
char a; xGr{ad.N
long b; G*EF_N.G0
}; jNx{*2._r
struct S2 { $k)K}U
char c; VF11eZ"
struct S1 d; :0(^^6Q\
long long e; 7L/LlO/
}; }l+_KA
#pragma pack() |LJv*
sizeof(S2)结果为24. Z1
)1s
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. BZhf/{h[@
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. clyp0`,7
,7cw%mQA
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; lIEZ=CEmY
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. ms Cz\8Xd
a b *
G*VY#L
S1的内存布局:11**,1111, ^!exH(g
c S1.a S1.b d =9QyOh
S2的内存布局:1***,11**,1111,****11111111 \i[N";K
-[vw 8
这里有三点很重要: &+02Sn3A
1.每个成员分别按自己的方式对齐,并能最小化长度 a0]GQyIG
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 wQ+il6
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 837:;<T
@i'D)6sC
cXt&k
网友xue23(xue23) 的答案和分析: |1
qrU(
!XjZt
有程序查一下各个变量的内存地址得知: 8IL5:7H8
各个变量在内存中的位置为 v
-)<nox
c***aa** <(TAA15Xol
bbbb**** #t1? *4.p
dddddddd jTqJ(M}L
测试代码为: indbg
d
s2 ss; c{to9Lk.#
cout << "ss.c = " << &ss << endl ; Cp!9 "J:
cout << "ss.d.a = " <<&ss.d.a << endl; :(OV{ u
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; w(_:+-rqQ<
print out 各个变量的内存地址不就可以看出来了吗。 L-U4
8 i
p`&{NR3+
所以答案是24,2. s\3]0n9
c8]%,26.
但是我的想像中应该是这样的分布情况: h*KDZ+{)
c******* A #SO}c
aa**bbbb ^y ', l
dddddddd Ow1+zltgj-
"i&n;8?Y
不知为什么会c和a放在一起,组成8位长度。