Intel和微软同时出现的C语言面试题 Z*d8b
#pragma pack(8) #Zpp*S55
P>=~\v nN#
struct s1{ =R#K`H66j
short a; MN2#
long b; BRP9j
y
}; Q5e ,[1
%t0Fx
struct s2{ R@``MC0
char c; buo_H@@p{s
s1 d; rt%.IQdY
long long e; *b?C%a9
}; :X[(ymWNE
KQ3]'2q
#pragma pack() FxSBxz<N-A
(Q !4\Gy
问 ]GYO`,
1.sizeof(s2) = ? cA"',N8!5
2.s2的s1中的a后面空了几个字节接着是b? lTPo2-j/eK
^RG6h
: j&M&+
"U34D1I)#
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: }N5>^y
;C%40;Q
网友rwxybh(行云)的答案: 59";{"sw
内存布局是 4KE"r F
1*** 11** SU"-%}~O#,
1111 **** CG IcuHp
1111 1111 [7?K9r\#
KyW6[WA9
所以答案就是24和3 3%m2$\
ykSn=0
下面是一个测试的程序,试一试就知道了,我用的是VC2005 !v|j C
/-<S F T`
#pragma pack(8) zpr`
<Mo_GTOC!
struct s1{ ahkSEE{
short a; // 2 BYtes |")}p=
long b; // 4 Bytes [JFmhLP9
}; v$"#9oh
struct s2{ V\@h<%{^%7
char c; // 1 Byte z8M^TV
s1 d; // 8 Bytes g^(wZ$NH
long long e; // 8 Bytes 9i WDEk
}; s;q]:+#7g
// 1*** 11** xA]CtB*o7
// 1111 **** |@={:gRJ{x
// 1111 1111 -UkP{x)S
// 6%NX|4_
>`p`^:
// 00 01 02 03 04 05 06 07 DF'-dh</*
// 00 01 02 03 04 05 06 07 $b\`N2J-_
// 00 01 02 03 04 05 06 07 bL
(g$Yi
// V'~]b~R
#pragma pack() Z{`;Ys:zk
bp2l%A;
int main(int argc, char* argv[]) R-J\c+C>W
{ Nh~ Hh(
s2 a; VO>A+vx3M
char *p = (char *)&a; +Y,>ftN
for(int i=0;i<24;++i) $<2r;'?0D
p = (char)(i%8); h@FDP#H
printf("%d\n",sizeof(a)); QRXsLdf$$
printf("c=0x%lx\n",a.c); ^ng#J\
printf("d.a=0x%x\n",a.d.a); zcD&xoL\H
printf("d.b=0x%x\n",a.d.b); 9H?er_6Yf
printf("e=0x%llx\n",a.e); bT}P":*y
return 0; CQ2{5
} 5+b[-Daz
结果: oC>e'_6_b
24 y5iLFR3z
c=0x0 }kI-UEn$EP
d.a=0x504 on $?c
d.b=0x3020100 |\2zw _o
e=0x706050403020100 Adgh:'h
33|>u+
!7@IWz(,"
网友 redleaves (ID最吊的网友)的答案和分析:
:Ts"f*
(=0W[@k
如果代码: 314PcSc
#pragma pack(8) ^ruS
struct S1{ ~YOwg\w^
char a; ;!&A
long b; 5Fm.] /
}; |r 1\
struct S2 { n[lf==R
char c; !HL7a]PB
struct S1 d; szMh}q"u
long long e; LYNd^}
}; 6#fl1GdH-
#pragma pack() cjsQm6
sizeof(S2)结果为24. ?`Qw=8]`
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. \-N
4G1
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 7}>j [
<~t38|Ff@
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; H1rge<
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. z$oA6qB)
a b z:bxnM2\
S1的内存布局:11**,1111, F"VNz^6laV
c S1.a S1.b d Q+)fI
S2的内存布局:1***,11**,1111,****11111111 UvRa7[<y%%
(Mhj-0xf$
这里有三点很重要: Ev%4}GwO4
1.每个成员分别按自己的方式对齐,并能最小化长度 MFcN.M
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 ge:UliHJ
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 S*Scf~Qp
"0 \U>h
4%~$A`7
网友xue23(xue23) 的答案和分析: &Eg>[gAIlp
n|IdEgD$
有程序查一下各个变量的内存地址得知: ~"!F&
各个变量在内存中的位置为 ChF:N0w?
p
c***aa** 1.!rq,+>1
bbbb**** RK#e7
dddddddd GrjL9+|x
测试代码为: _aL:XKM
s2 ss; ^RrufwUA
cout << "ss.c = " << &ss << endl ; :XcU @m
cout << "ss.d.a = " <<&ss.d.a << endl; 9d^o2Yo
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; #ebT$hf30
print out 各个变量的内存地址不就可以看出来了吗。 #>GUfhou)
Bu">)AnN
所以答案是24,2. :XEr{X
xz[a3In+
但是我的想像中应该是这样的分布情况: "AP''XNi
c******* He^+>XIam
aa**bbbb >/nS<y>
dddddddd VS@o_fUx)
r<c yxR~
不知为什么会c和a放在一起,组成8位长度。