Intel和微软同时出现的C语言面试题 \Q|1I
#pragma pack(8) F"#bCnS
@>_`g=
struct s1{ h )"PPI
short a; @H"~/ m_o
long b; j08}5Eo
}; 0"(5\T
En&ESWN
struct s2{ Pq>r|/~_
char c; {v}f/cu
s1 d; AKC';J
long long e; r;t0+aLc*
}; 0PIC|
E9;cd$}K
#pragma pack() p[VBeO^%
R)"Ds}1G
问 v9(->X'
1.sizeof(s2) = ? @Nn9-#iW
2.s2的s1中的a后面空了几个字节接着是b? Pdmfn8I]%
:[m;#b
(n05MwKu\
D+]#qS1q
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: CDQ}C=4
M2(+}gv;7p
网友rwxybh(行云)的答案: \]e"#"v}}_
内存布局是 }+h/2D
1*** 11** ^I@1y}xi
1111 **** ZWQrG'$?o8
1111 1111 <LIL{g0eX
UJ1iXV[h"
所以答案就是24和3 hW$B;
n$g g$<
下面是一个测试的程序,试一试就知道了,我用的是VC2005 DnS#
cs~
zdrCr0Rx,
#pragma pack(8) &*B=5W;6^u
_(&^M[O
struct s1{ QU_O9 BN
short a; // 2 BYtes N W :_)1
long b; // 4 Bytes v=E V5#A
};
XZLo*C!MG
struct s2{ @tWyc%t
char c; // 1 Byte cJd~UQ<k
s1 d; // 8 Bytes bYGK}:T8U
long long e; // 8 Bytes rn #FmM
}; :3M2zV
cf
// 1*** 11** 9}Ud'#E
// 1111 **** uV!Ax*'
// 1111 1111 CvKXVhf0$J
// NK2Kw{c"iI
y8'WR-;
// 00 01 02 03 04 05 06 07 i[/g&fx
// 00 01 02 03 04 05 06 07 yT%"<m6Y*\
// 00 01 02 03 04 05 06 07 >!MOgLO3
// ^E*W
B~
#pragma pack() oMawINDa
%Sr/'7 K
int main(int argc, char* argv[]) I
*YO
{ ZdJwy%
s2 a; zV_U/]y
char *p = (char *)&a; 'VcZ_m:
for(int i=0;i<24;++i) ^I=c]D]);
p = (char)(i%8); !qsk;Vk7Z
printf("%d\n",sizeof(a)); ?Y7'OlO
printf("c=0x%lx\n",a.c); q(4W/y
printf("d.a=0x%x\n",a.d.a); Z{s&myd
printf("d.b=0x%x\n",a.d.b); \Y&* sfQ
printf("e=0x%llx\n",a.e); `,gGmh
return 0; CB{%~
} ="<5+G
结果: ^m.QW*
24 WeNx9+2=Z
c=0x0 j/`-x
d.a=0x504 :Fz;nG-G
d.b=0x3020100 D's'LspQ
e=0x706050403020100 {</MC`
4bLk+EY4A
,_@C(O
网友 redleaves (ID最吊的网友)的答案和分析: /4J2F9:f
3^AycwNBA
如果代码: eL3HX _2(
#pragma pack(8) 7cV9xIe^
struct S1{ 2?9 FFlX
char a; wNMg Y
long b; AuuZWd
}; np,L39:sf
struct S2 { M3c!SXx\
char c; KKP}fN
struct S1 d; H=Rqr
long long e; xP%`QTl\
}; 9v>BP`Mg
#pragma pack() g^ZsV:D
sizeof(S2)结果为24.
@ c,KK~{
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. B f33%I~
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. [,[;'::=o4
}6ObQa43
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; 0`.3`Mk
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. F4'g}yOLd
a b qI;"yG-x-
S1的内存布局:11**,1111, ]H<5]({F
c S1.a S1.b d &$F4/2|b%
S2的内存布局:1***,11**,1111,****11111111 `##qf@M
iU3)4(R
这里有三点很重要: T&Z%=L_Q
1.每个成员分别按自己的方式对齐,并能最小化长度 - 6a4H?L
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 b*Ny
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐
$0>>Z
eQ_dO]Q
sf )ojq6s
网友xue23(xue23) 的答案和分析: 2<HG=iSf
Z0*Lm+d9z
有程序查一下各个变量的内存地址得知: d#P3
<
各个变量在内存中的位置为 CBw/a0Uck
c***aa** EV{kd.=f
bbbb**** c&r