Intel和微软同时出现的C语言面试题 Wt5pK[JV
#pragma pack(8) '4GN%xi
'o=DGm2H
struct s1{ 3 q8S
short a; ^Et^,I:`
long b; L09r|g4Z
}; N:KM8PZ&~
hw`pi6
struct s2{ w$]wd`N}
char c; A]%*ye"NT
s1 d; PXl%"O%d
long long e; 8YPX8d8u
}; mxH63$R
LGtw4'yr
#pragma pack() ijcF[bmE
K{Nj-Rqd
问 @G>eCj
1.sizeof(s2) = ?
!Qsjn
2.s2的s1中的a后面空了几个字节接着是b? 3:w_49~:~
|A|K);
)yz)Fw|&
Bs '=YK$
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: tJ7tZ~Ak
Z" l].\=
F
网友rwxybh(行云)的答案: 4j,6t|T
内存布局是 :v45Ls4J
1*** 11** $WRRCB/A6
1111 **** Vv`94aQTD
1111 1111 S]}}r)
O#!|2qN
所以答案就是24和3 3*?W2;Zw$
~USyN'5lU7
下面是一个测试的程序,试一试就知道了,我用的是VC2005 0e:j=kd)NH
pL*aU=FjQ
#pragma pack(8) Wj)v,v2&
RP 6<#tq,
struct s1{ )2^r
0(x
short a; // 2 BYtes JS?%zj&@
long b; // 4 Bytes C!1)3w|
}; 5|}u25J
struct s2{ WK0IagYw
char c; // 1 Byte F *U.cJ%
s1 d; // 8 Bytes =pj3G?F#
long long e; // 8 Bytes zII^Ny8D
}; z t
// 1*** 11** ;S&anC#E
// 1111 **** 2H] 7 =j
// 1111 1111 I!lR 7%
// M`9|8f,!a
oBnes*
// 00 01 02 03 04 05 06 07 YJDJj
x
// 00 01 02 03 04 05 06 07 qx0F*EH|
// 00 01 02 03 04 05 06 07 A[F@rUZp
// -) +B!"1
#pragma pack() }t|i1{%_
BNO+-ob-
int main(int argc, char* argv[]) J_<6;#
{ X_3hh} =
s2 a; oZL# *Z(h
char *p = (char *)&a; "ChJR[4@
for(int i=0;i<24;++i) lQRtsmZ0
p = (char)(i%8); 6@:<62!;
printf("%d\n",sizeof(a)); D)[(
printf("c=0x%lx\n",a.c); pOB<Bx5t
printf("d.a=0x%x\n",a.d.a); K|D1
printf("d.b=0x%x\n",a.d.b); ^@Qc!(P
printf("e=0x%llx\n",a.e); XQOM6$~,
return 0; }:s.m8LC5n
} Xe\v6gbD
结果: $&jVEMia
24 <|E*aR|M
c=0x0 VTX6_&Hc1g
d.a=0x504 bq8h?Q
d.b=0x3020100 QM~~b=P,\
e=0x706050403020100 NE &{_i!
#7YJ87<E
gTLBR
网友 redleaves (ID最吊的网友)的答案和分析: F{
C2%
s#
G~4G$YL*
如果代码: M D&7k,!
#pragma pack(8) `O%O[
struct S1{ L@?3E`4/v
char a; V1Gnr~GM
long b; T}"[f/:N/
}; }P\6}cK
struct S2 { 3".#nN
char c; d\c)cgh%
struct S1 d; q}z`Z/`/
long long e; rzvKvGd#N
}; ,nV4%Aa
#pragma pack() <<Z, 1{3F
sizeof(S2)结果为24. nYBa+>3BDf
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. I;UT;/E2
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. Q^xk]~G$(
}Q6o#oZ
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; "kVzN22
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. [e{W:7uFV
a b ZhC,nbM
S1的内存布局:11**,1111, oDt{;S8|]
c S1.a S1.b d rz%^l1@-
S2的内存布局:1***,11**,1111,****11111111 lPtML<a
Jm 0.\[J
这里有三点很重要: &xt
GabNk
1.每个成员分别按自己的方式对齐,并能最小化长度 )4,U
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 -I;\9r+
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 f)r6F JLU
50T^V`6
##alzC
网友xue23(xue23) 的答案和分析: v}IhO~`uEq
Otf{)f
有程序查一下各个变量的内存地址得知: s5*HS3D
各个变量在内存中的位置为 }iUpBn
c***aa** fILvEf4b
bbbb**** B;piO-hH
dddddddd =NNxe"Kd;U
测试代码为: %E [HMq<H
s2 ss; U: )Gc
cout << "ss.c = " << &ss << endl ; k7cY^&o
cout << "ss.d.a = " <<&ss.d.a << endl; ^oW{N
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; zW)Wt.svP
print out 各个变量的内存地址不就可以看出来了吗。 RU>qj
*e
@Q;s[Kg{!
所以答案是24,2. !*?9n^PaF
@tJic|)x
但是我的想像中应该是这样的分布情况: O,NVhU7,
c******* >Ml5QO$*.q
aa**bbbb OF-VVIS
dddddddd {:Kr't<XzF
?|\wJrM ]
不知为什么会c和a放在一起,组成8位长度。