Intel和微软同时出现的C语言面试题 l.NEkAYPmH
#pragma pack(8) bKN@j'M
/Id%_,}Kb
struct s1{ [.uG5%fa
short a; K8UP,f2
long b; %*0^0wz
}; 8Y7Q+p|O
/q`xCS
struct s2{ 0p}D(m2B
char c; 2
Cv4=S
s1 d; YLzx<~E4a
long long e; 2-Ej4I~
}; VYk!k3qS
jGpN,/VQa
#pragma pack() Tw;3_Lj
([m
mPyp>L
问 9E>|=d|(d
1.sizeof(s2) = ? xY^%&n
2.s2的s1中的a后面空了几个字节接着是b? 75/(??2
2bkX}FWd;
E{Ov>osq
"q.\>MCv
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: J2xw) +
G'ei/Me6{
网友rwxybh(行云)的答案: [Q/TlO t5
内存布局是 ov_j4j>6P
1*** 11** [8=vv7wS
1111 **** )E-inHD /
1111 1111 AN/;)wc
:lPb.UCY
所以答案就是24和3 n
T{3o;A
U$WxHYo
下面是一个测试的程序,试一试就知道了,我用的是VC2005 K|hjEQRv
F|e1"PkeoA
#pragma pack(8) EkjN{$*
O\"3J(y,
struct s1{ xQ^E"Q,1
short a; // 2 BYtes YW( Qmo7
long b; // 4 Bytes pH"#8O&
}; \b?" b
struct s2{ vnM@QfN
char c; // 1 Byte P;qN(2L/=<
s1 d; // 8 Bytes q#,f 4P
long long e; // 8 Bytes 7G}2,ueI
}; Y6zbo
// 1*** 11** I J(
// 1111 **** 8{^WY7.'
// 1111 1111 %)/P^9I6
// ;kS&A(
~&7MkkftM
// 00 01 02 03 04 05 06 07 06c>$1-?
// 00 01 02 03 04 05 06 07 OHb[qX\
// 00 01 02 03 04 05 06 07 +RYls|f
// '":lB]hS
#pragma pack() ]pNvxXbeW
o4K ~
int main(int argc, char* argv[]) ]<cK";
{ -y8`yHb_
s2 a; 5ft`zf
char *p = (char *)&a; 117EZg]O
for(int i=0;i<24;++i) m
g4nrr\
p = (char)(i%8); V9{]OV%
printf("%d\n",sizeof(a)); Z\ja
printf("c=0x%lx\n",a.c); ebUBrxZX
printf("d.a=0x%x\n",a.d.a); 1p/3!1
printf("d.b=0x%x\n",a.d.b); Z7hgA-t
printf("e=0x%llx\n",a.e); 7b;I+q
return 0; $m].8?
} HUv/ ~^<
结果: C9n?@D;S
24 }%'?p<^M
c=0x0 hRrn$BdLX
d.a=0x504 XINu=N(g
d.b=0x3020100 ZjQ
|Wx
e=0x706050403020100 s'E2P[:
ND>r#(_\
LYz.Ci}
网友 redleaves (ID最吊的网友)的答案和分析: vdx0i&RiL
g!?:Ye`5
如果代码: ?fUlgQ}N
#pragma pack(8) zMm#Rhn
struct S1{ d%RC
char a; |
r&k48@
long b; T`\x,`
^
}; t>urc
struct S2 { BGD8w2
char c; ]
2eK
struct S1 d; |"/8XA
long long e; %_RQx2
}; D#il*
#pragma pack() /H(?
2IHC
sizeof(S2)结果为24. a!<8\vzg
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. si`A:14R
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. ES.fOdx
ZniB]k1
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
-QM:
q
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. JORGj0v
a b aB{vFTD5
S1的内存布局:11**,1111, )z73-M V"
c S1.a S1.b d j53*E
)d
S2的内存布局:1***,11**,1111,****11111111
gX]-\
vq^f}id
这里有三点很重要: +e yc`J
1.每个成员分别按自己的方式对齐,并能最小化长度 s:/8[(A
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 4'`{H@]tb
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 \N!AXD
U(Nu%
% NA9{<I
网友xue23(xue23) 的答案和分析: fPn>v)lN{
#sPHdz'3M
有程序查一下各个变量的内存地址得知: %r%M lj:#
各个变量在内存中的位置为 KxYwJ
c***aa** w+#C-&z
bbbb**** a(kg/s
dddddddd 6:Ch^c+IZ
测试代码为: XQ9O$
~q
s2 ss; )}D'<^=#T
cout << "ss.c = " << &ss << endl ; _aFl_\3>
cout << "ss.d.a = " <<&ss.d.a << endl; :km61
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; DcoX+8 7
print out 各个变量的内存地址不就可以看出来了吗。 hxVKV?Fl
}=gx#
所以答案是24,2. \O*-#} ~\
TcjEcMw,
但是我的想像中应该是这样的分布情况: /'].lp
c******* ^)(bM$(`
aa**bbbb ~P8tUhffK
dddddddd bJRN;g
66/3|83Z
不知为什么会c和a放在一起,组成8位长度。