Intel和微软同时出现的C语言面试题 <S68UN(Ke
#pragma pack(8) =a^}]k}
:.aMhyh#*
struct s1{ \2!1fN
short a; ;Bwg'ThT
long b; 6tF_u D
}; m< Y I}
M2lvD&
struct s2{ FE,BvNBZ
char c; kmT5g gy
s1 d; ]-"G:r
long long e; f O ,5
u;
}; 2rPmu
P+bA>lJd
#pragma pack() !!?TkVyEyM
~EtwX YkRZ
问 a|eHo%Qt
1.sizeof(s2) = ? VMIX=gTZ
2.s2的s1中的a后面空了几个字节接着是b? 7-#
+FJ+,|i
y7~y@ 2
9wbj}tN\z
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: TQ5*z,CkS
,8G6q_ud
网友rwxybh(行云)的答案: a]nK!;>$
内存布局是 ?/|KM8
1*** 11** '8w>=9Xl
1111 **** "Tz'j}< 9C
1111 1111 Fj4>)!^kM
WT63ve
所以答案就是24和3 ?"$Rw32
V@rqC[on
下面是一个测试的程序,试一试就知道了,我用的是VC2005 ^:~!@$*;6
A~}5T%qb
#pragma pack(8) ]p!)8[<
QTC!vKM
struct s1{ a'Yi^;2+\
short a; // 2 BYtes %z~=Jz^
long b; // 4 Bytes ,0a\Ka{^
}; ( 4(,"
struct s2{ "fu:hHq
char c; // 1 Byte Z0%:j\W4c
s1 d; // 8 Bytes 4i7+'F
long long e; // 8 Bytes qWM+!f
}; 5Mz:$5Tm
// 1*** 11** N@0cn
q:"
// 1111 **** ny1;]_X_
// 1111 1111 rXP~k]tC
// _;M3=MTM9
,pIh.sk7s*
// 00 01 02 03 04 05 06 07 vb6kr?-i*
// 00 01 02 03 04 05 06 07 i&YWutG
// 00 01 02 03 04 05 06 07 l"-Z#[
// o$Ju\(Y$<+
#pragma pack() m~0Kos%^*b
Z C<+BKS
int main(int argc, char* argv[]) G>Hg0u0!,
{ $b(CN+#
s2 a; Z@(KZ|
char *p = (char *)&a; g%<n9AUl
for(int i=0;i<24;++i) LUdXAi"f
p = (char)(i%8); !_P&SmK3
printf("%d\n",sizeof(a)); ;SIWWuk
printf("c=0x%lx\n",a.c); _iL?kf
printf("d.a=0x%x\n",a.d.a); -Xx4:S
printf("d.b=0x%x\n",a.d.b); pX+4B=*
printf("e=0x%llx\n",a.e); S$ffTdRz
return 0; :V1j*)
} T+e*' <!O
结果: _n1[(I
24 'o~gT ;T#
c=0x0 Al=ByX @
d.a=0x504 B"8jEYT5
d.b=0x3020100 T'{9!By,P
e=0x706050403020100 k/(]1QnW
NfUt\ p*
j#0JD!Vr
网友 redleaves (ID最吊的网友)的答案和分析: ||?@pn\
!Au#j^5K-o
如果代码: Q(36RX%@
#pragma pack(8) V';l H2
struct S1{ d6W\
\6V
char a; P ^ 4 @
long b; C;j&Vbf
}; stUUez>
struct S2 { |{v#'";O:
char c; $,yAOaa
struct S1 d; v&bG`\ !
long long e; oKb"Ky@s
}; T+^c=[W
#pragma pack() c]zFZJ6M
sizeof(S2)结果为24. 3{fg3?
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. W.NZ%~|+e/
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. <{GVA0nr
uFhaN\S
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; [dAQrou6P
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. QFMAy>Gdn
a b =3 Vug2*wd
S1的内存布局:11**,1111, YZ`SF"Bd(
c S1.a S1.b d tj$[szo
S2的内存布局:1***,11**,1111,****11111111 2,wwI<=E'
N<1+aL\
这里有三点很重要: <Se9aD
1.每个成员分别按自己的方式对齐,并能最小化长度 \5 rJ
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 M~N/er
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 SnR2o3r-Of
U(#JC(E-#
iGkysU<wcp
网友xue23(xue23) 的答案和分析: le]~Cy0
x x4GP2
有程序查一下各个变量的内存地址得知: N#2ldY *
各个变量在内存中的位置为 =YTcWB
c***aa** - Z`RKR8C
bbbb**** 3H`{
A/r
dddddddd vENf3;o0
测试代码为: mf)+ 5On
s2 ss; QW$p{ zo
cout << "ss.c = " << &ss << endl ; %4f.<gz~r|
cout << "ss.d.a = " <<&ss.d.a << endl; ~`C_B]3|
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; O`Gq7=X
print out 各个变量的内存地址不就可以看出来了吗。 vaGF(hfTA
@0 /qP<E
所以答案是24,2. -sfv"?
;}j(x;l>t
但是我的想像中应该是这样的分布情况: &iVdqr1,
c******* 2 U]d1
aa**bbbb r34MDUZdI
dddddddd RFyMRE!?
y;uR@{
不知为什么会c和a放在一起,组成8位长度。