Intel和微软同时出现的C语言面试题 iwz
#pragma pack(8) `l2O?U -@
?
J}r
struct s1{ !US d9
short a; 8}H1_y-g[
long b; ~\x:<)
}; &l$Q^g
1O].v&{
struct s2{ kGpa\c
g1
char c; +_XmlX A3Z
s1 d; 43?^7_l-
long long e; _&K
}; #HS]NA|e@
y4h=Lki@
#pragma pack() izh<I0
[E#UGJ@
问 XwV'Ha
1.sizeof(s2) = ? G}5 #l
2.s2的s1中的a后面空了几个字节接着是b? M"%Q&o/I
%Qg+R26U
z
<mK>$
eh1Q7~
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: Rqwzh@}
,q(&)L$S
网友rwxybh(行云)的答案: bjAnaya
内存布局是 ThPE
0V
1*** 11** >!_Xgw
1111 **** < >UPD02
1111 1111
h:lt<y
]Jh+'RK\#
所以答案就是24和3 1ygpp0IGJ
1c JF/"v
下面是一个测试的程序,试一试就知道了,我用的是VC2005 PoEqurH0
r=yK,d/1
#pragma pack(8) AiD[SR
Fnk_\d6Ma
struct s1{ v]__%_
short a; // 2 BYtes ?+T^O?r|O
long b; // 4 Bytes >]o}}KF?
}; S+TOSjfis
struct s2{ \om%Q[F7a
char c; // 1 Byte {3N'D2N
s1 d; // 8 Bytes L4uFNM]
long long e; // 8 Bytes OL_{_K(w
}; 8M@BG8
// 1*** 11** iC
iZJ"
// 1111 **** RwS@I/
// 1111 1111 Y>jiXl?&
// AeAp0cbet
.z13 =yv
// 00 01 02 03 04 05 06 07 :eo
// 00 01 02 03 04 05 06 07 ''\;z<v
// 00 01 02 03 04 05 06 07 &3J@BMYp
// drsB/
#pragma pack() rJ KZ)N{
5NJ4
int main(int argc, char* argv[]) *T0q|P~o%
{ k6=nO?$
s2 a; 'zh7_%
char *p = (char *)&a; NBb6T
V}j
for(int i=0;i<24;++i) s,a}?W
p = (char)(i%8); ^5r9 5
printf("%d\n",sizeof(a)); sgE-`#
printf("c=0x%lx\n",a.c); ?5kHa_^
printf("d.a=0x%x\n",a.d.a); =2w4C_
printf("d.b=0x%x\n",a.d.b); 1Bxmm#
printf("e=0x%llx\n",a.e); (H+'X}1
return 0; Zo>]rKeV
} A.UUW
结果: :$MG*/Q
24 *,Bzc Z
c=0x0 Vf(6!iRP@
d.a=0x504 Wu)>U
d.b=0x3020100 vM_:&j_?``
e=0x706050403020100 0a"igq9t
xC
C:BO`pw
u4Em%:Xj
网友 redleaves (ID最吊的网友)的答案和分析: <3,<\ub
b,8{ X<
如果代码: qC'{;ko
#pragma pack(8) VY)s+Bx
struct S1{ 2Pc%fuC
char a; vFEQ7qI
long b; / g 2b
}; .jMq
struct S2 { A<;SnXm
char c; gk`zA
struct S1 d; +**!@uY
long long e; '=P7""mN5
}; %,ngRYxT#
#pragma pack() JmEj{K<3I
sizeof(S2)结果为24. G9JAcO1
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 7t.!lh5G%
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. ,]b~t0|B
ZoArQ(YFy
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; h;3cd0
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. "fq{Y~F%`
a b C!7>1I~5
S1的内存布局:11**,1111, r1fGJv1!o
c S1.a S1.b d B7]MGXC
S2的内存布局:1***,11**,1111,****11111111 Ie%EH
/r_~:3F
这里有三点很重要: s=42uKz
1.每个成员分别按自己的方式对齐,并能最小化长度 n("0%@ov
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 " LJq%E
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 z5TuGYb<
%6_AM
qTQBt}
网友xue23(xue23) 的答案和分析: c&L"N!4z
`=7j$#6U
有程序查一下各个变量的内存地址得知: ;j2vHU#q-
各个变量在内存中的位置为 NzNA>[$[
c***aa** aN(|'uO@
bbbb**** LiKxq=K
dddddddd `mN4_\]
测试代码为: \rPbK+G.
s2 ss; rb{P :MX
cout << "ss.c = " << &ss << endl ; |hr]>P1
cout << "ss.d.a = " <<&ss.d.a << endl; (e"iO`H
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; ^n+ !4(@=
print out 各个变量的内存地址不就可以看出来了吗。 [k-+AA>:
>$ 2V%};
所以答案是24,2. V%Sy"IG
VU@9@%TN
但是我的想像中应该是这样的分布情况:
P\_`
c******* V <bd;m
aa**bbbb ;V<fB/S.=+
dddddddd ]KJj6xn
R i^[i}
不知为什么会c和a放在一起,组成8位长度。