Intel和微软同时出现的C语言面试题 UpITx]y?"m
#pragma pack(8) 3O.-'U1K
B@4#y9`5
struct s1{ E_OLf%um
short a; "~ /3
long b; xfzR>NU
}; u0,~pJvX
`'>>[*06:a
struct s2{ WXM_H0K
char c; #df43_u
s1 d; \=@}(<4
long long e; QqDF_
};
Wi[Y@
ru&RL
HFV
#pragma pack() !"kvXxp^
-nW{$&5AF
问 lbPxZ'YO#
1.sizeof(s2) = ? TcC=_je460
2.s2的s1中的a后面空了几个字节接着是b? 9#p^Z)[)-
@ZVc!5J_,
%/s1ma6q
H\^^p!^)
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: 1Nz\3]-
..!yf e"5
网友rwxybh(行云)的答案: LV[4z o]=
内存布局是 ]8^2(^3ct
1*** 11** XEuv
aM
1111 **** OV[-m;h|
1111 1111 Zwcb5\Q
ovl@[>OB
所以答案就是24和3 yP-Dj
,
23>?3-q
下面是一个测试的程序,试一试就知道了,我用的是VC2005 9.R_=
g
(~&
#pragma pack(8) D"hiEz
ck}y-,>,[O
struct s1{ b9U2afd
short a; // 2 BYtes ql4T@r3l}3
long b; // 4 Bytes c*h5lM'n6
}; ,kP{3.#Q
struct s2{ ^\!^#rO
char c; // 1 Byte RHxd6Gs"
s1 d; // 8 Bytes 1~*_H_Q't
long long e; // 8 Bytes r}991O<
}; sqy5rug
// 1*** 11** RPrk]<<1
// 1111 **** o
2DnkzpJ
// 1111 1111 1ID!rxE
// `8Om*{xg
~$cw]R58,9
// 00 01 02 03 04 05 06 07 =}L[/ RL
// 00 01 02 03 04 05 06 07 !>+
0/
// 00 01 02 03 04 05 06 07 e0qa~5
// :sn}D~
#pragma pack() hk=+t&Y<H
D&'".N,}
int main(int argc, char* argv[]) [:o#d`^
{ ~5|a9HV:
s2 a; ^mGT ZxO
char *p = (char *)&a; =m40{
for(int i=0;i<24;++i) Pg:Nz@CQ
p = (char)(i%8); eY-$hnUe
printf("%d\n",sizeof(a)); D Lu]d$G
printf("c=0x%lx\n",a.c); b"gYNGgX
printf("d.a=0x%x\n",a.d.a); +vQyHo
printf("d.b=0x%x\n",a.d.b); <
;g0?M\
printf("e=0x%llx\n",a.e); { sZrI5
return 0; \CL`j
} r8xH A
结果: !b7H
24 ]*@7o^4i
c=0x0 Kq1sGk
d.a=0x504 c" l~=1Dr
d.b=0x3020100 rUyT5Vf
e=0x706050403020100 )yK!EK\
^cY5!W.q8
DJ\lvT#j
网友 redleaves (ID最吊的网友)的答案和分析: ~(^[TuJC
HiWZ?G
如果代码: :\>UZ9h #
#pragma pack(8) o;O_N^_W
struct S1{ 9uq|
VU5
char a; Ywni2-)<
long b; 3w-0v"j U
}; =?}'\
>G "
struct S2 { )FB)ZK ;
char c; 4Qw!YI#40$
struct S1 d; T^79p$
long long e; aw,8'N)
}; B1GSZUd^?0
#pragma pack() $Fo ,$
sizeof(S2)结果为24. iX,Qh2(ig
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 8-m"] o3
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. eBP
N[V
isaT0__8
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; :ortyCB:H
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. I5e!vCG)
a b ^c2 8Q.<w(
S1的内存布局:11**,1111, :c6%;2
c S1.a S1.b d fN&O `T>
S2的内存布局:1***,11**,1111,****11111111 ?GFVV ->i
-wO`o<
这里有三点很重要: !is8`8F8
1.每个成员分别按自己的方式对齐,并能最小化长度 WgY3g1C
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 n"Ev25%
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 H<qR^a
RpreW7B_Q*
zgO?%O
网友xue23(xue23) 的答案和分析: ^{bP#f
{d3r>Ub)7d
有程序查一下各个变量的内存地址得知: :gR`rc!
各个变量在内存中的位置为 <}e<Zf!
c***aa** zRKg>GG`
bbbb**** OtC/)sX
dddddddd F|"NJ*o}
测试代码为: m1frN#3
s2 ss; X`22Hf4ct
cout << "ss.c = " << &ss << endl ; k<St:X%.O
cout << "ss.d.a = " <<&ss.d.a << endl; #)\KV7f!;
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; vg)zk2O
print out 各个变量的内存地址不就可以看出来了吗。 x|Q6[Y
Y!SD^Ie7!
所以答案是24,2. Obw uyhjQ
=]D##R
但是我的想像中应该是这样的分布情况: ';
qT
c******* Hv%a\WNS1
aa**bbbb f",B;C
dddddddd u2DsjaL
MF& +4$q
不知为什么会c和a放在一起,组成8位长度。