Intel和微软同时出现的C语言面试题 twv|,kM
#pragma pack(8) 9UsA>m.
/{>$E>N;
struct s1{ cKJf0S:cx-
short a; cXU8}>qY7
long b; w#vSZbh
}; Uy2NZ%rnt
"(zvI>A
struct s2{ #tg,%*.s
char c; g HdNqOy
c
s1 d; c7UmR?m
long long e; Ydm0
}; xP#vAR
)9I>y2WU~
#pragma pack() Aslh}'$}-
_1Iy /T@1
问 KJn@2x6LP
1.sizeof(s2) = ? \UA\0p
2.s2的s1中的a后面空了几个字节接着是b? }(k#,&Fv`
$0$'co"
hsG~xRA\
O#LG$Y
n*
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: pRWEBd1U
&|yQwNA*a"
网友rwxybh(行云)的答案: *j5>2-C &
内存布局是 TRP#b 7nC
1*** 11** q.0Evr:
1111 **** !~Vo'ykwx'
1111 1111 i[_(0P+Da
yMaU`z
所以答案就是24和3 5.m&93P
p)6!GdT
下面是一个测试的程序,试一试就知道了,我用的是VC2005 1P4cBw%
JjA3G`m=
#pragma pack(8) Geyy!sr``
g_X-.3=2K
struct s1{ \|e>(h!l;
short a; // 2 BYtes `_%UK=m
long b; // 4 Bytes _gU:!:}
}; t/55tL
struct s2{ !%MI9Ok
char c; // 1 Byte V`P8oIOh]
s1 d; // 8 Bytes KaVNRS
long long e; // 8 Bytes DJ_[{WAV
}; wcr3ugvT
// 1*** 11** b-?wJSf|
// 1111 **** eS#kDa/ %
// 1111 1111 $HgBzZ7A2
// x}\x3U
I(^pIe-
// 00 01 02 03 04 05 06 07 {1?94rz
// 00 01 02 03 04 05 06 07 e&~vO| 3w%
// 00 01 02 03 04 05 06 07 LGnb"ZN
// )/HbmtX qI
#pragma pack() n/W@H Im#
[|iWLPO1&k
int main(int argc, char* argv[]) 5k:SD7^b
{ CFE ubEb
s2 a; &T.d"i
char *p = (char *)&a; A]0A,A0
for(int i=0;i<24;++i) &10l80vj
p = (char)(i%8); M3XG s|gw
printf("%d\n",sizeof(a)); ?^Gi;d5
printf("c=0x%lx\n",a.c); ,+w9_Gy2H
printf("d.a=0x%x\n",a.d.a); -e_91WI
printf("d.b=0x%x\n",a.d.b); Vn&{yCm3
printf("e=0x%llx\n",a.e); cp1-eR_&
return 0; /80H.|8O
} 5(wmy-x\
结果: @!p bR(8
24 Ibf~gr(j
c=0x0 8y:/!rRN
d.a=0x504 ;x<5F+b
d.b=0x3020100 mJxr"cwHl
e=0x706050403020100 {F!/\2a
S?b^g'5m
M)x6m|.=
网友 redleaves (ID最吊的网友)的答案和分析: 1`hmD1d
oX=dJJE
如果代码: tIK`/)w,
#pragma pack(8) _+!@c6k)ra
struct S1{ }K.Rv(m
char a; |>^5G@e
long b; H1GmC`\<[:
}; 1JQ5bB"
struct S2 { kM6i{{Q
char c; J#.f%VJ
struct S1 d; *wk?{ U
long long e; D\:dn
}; P"(VRc6x
#pragma pack() 45.<eWH$*(
sizeof(S2)结果为24. !S.O~Kq
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. ,(u-q]8
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. ]?<
wUd
U
g:
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; *S xDwN
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. awXK9}.
a b +3yG8
S1的内存布局:11**,1111,
HNJR&U t
c S1.a S1.b d gmUXh;aHc
S2的内存布局:1***,11**,1111,****11111111 A%[e<vj9
reQr=OAez
这里有三点很重要: sYEh>%mo^C
1.每个成员分别按自己的方式对齐,并能最小化长度 8Y]% S9.
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 vAh'6Ob7r
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 Iuyq!R4:7
[psZc'q
dhX$b!DA
网友xue23(xue23) 的答案和分析: Sj ly]
/!#A'#Z
有程序查一下各个变量的内存地址得知:
O~Jm<