Intel和微软同时出现的C语言面试题 fILINW{Yk)
#pragma pack(8) 2G=Bav\n+
NIY0f@1z-
struct s1{ >2_BL5<S
short a; MS)# S&
long b; J}Bg<[n
}; ka0T|$ u(s
5? &k? v@
struct s2{ rbHrG<+7zO
char c; Xai ,
s1 d; CS)&A4`8
long long e; /JaH
}; J^R))R=
x$Ko|:-
#pragma pack() Z,M?!vK
;cH|9m:Y
问 +y! dU{L^
1.sizeof(s2) = ? iW(HOsA
2.s2的s1中的a后面空了几个字节接着是b? gYn1-/Z>I
Ol`/r@s
Ek~Qp9B
2asA]sY
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: >pW8K[
Am'5|
网友rwxybh(行云)的答案: 5)+(McJC
内存布局是 AyB-+oTf(
1*** 11** /pan{.< k
1111 **** E3<jH
1111 1111 ,B(UkPGT
QXY-?0RO#
所以答案就是24和3 };o6|e:2E
1mm/Ssw:C
下面是一个测试的程序,试一试就知道了,我用的是VC2005 OmQSNU.our
PspH[db
#pragma pack(8) zmQ V6o=k
\K.i8f,
struct s1{ 2f9~:.NgF
short a; // 2 BYtes p+SFeUp
long b; // 4 Bytes }{[H@uhjH
}; IsxPm9P2<
struct s2{ (cAv :EKpo
char c; // 1 Byte +Pd&YfU9
s1 d; // 8 Bytes j#S>8:
G
long long e; // 8 Bytes ,UopGlA
,
}; a,b;H(em
// 1*** 11** i[`nu#n/
// 1111 **** Q^$IlzG7i
// 1111 1111 y44FejH(v
// "IA[;+_"
T8h.!Vef
// 00 01 02 03 04 05 06 07 oUIa/}}w5
// 00 01 02 03 04 05 06 07 H0Qpc<Z4/
// 00 01 02 03 04 05 06 07 R/R[r> 1)6
// \[Op:^S
#pragma pack() Vy.A`Hz
gV1&b
(h
int main(int argc, char* argv[]) ol^V@3[<
{
.'mmn5E
s2 a; ;n$j?n+|
char *p = (char *)&a; X+)68
for(int i=0;i<24;++i) jhjGDF
p = (char)(i%8); s\_-` [B0
printf("%d\n",sizeof(a)); \Si@t{`O
printf("c=0x%lx\n",a.c); 58,_
printf("d.a=0x%x\n",a.d.a); {:xINQ=}D
printf("d.b=0x%x\n",a.d.b); IzF7W?k
printf("e=0x%llx\n",a.e); m8,P-m
return 0; H_sLviYLu
} oe_l:Y%
结果: qUA&XUJ
24 GzWmXm
c=0x0 q{@j$fMt0
d.a=0x504 +8Yt91
d.b=0x3020100 V|zzj[c
e=0x706050403020100 $'btfo4H
LbOjKM^-
&>\E
>mJ
网友 redleaves (ID最吊的网友)的答案和分析: A(X~pP&oF
.",E}3zn
如果代码: uNZJNrV%
#pragma pack(8) wvvMesX<L
struct S1{ }WS%nQA
char a; fqZqPcT0
long b; hAi50q;z
}; )[yM4QFl
struct S2 { h.>6>5$n
char c; /1:`?% ,2
struct S1 d; A<2_V1
long long e; `An|a~G1
}; !yU!ta Q
#pragma pack() <use+C2
sizeof(S2)结果为24. ke_Dd?
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 8.HqQ:?&2t
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. ^$f}s,09
fT [JU1
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; 2c@4<kyfP
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. /f~V(DK
a b oRFHq>-.g
S1的内存布局:11**,1111, >i7zV`eK
c S1.a S1.b d rD<G_%hP
S2的内存布局:1***,11**,1111,****11111111 kKAK;JQ
9:"%j
这里有三点很重要: He}qgE>Us
1.每个成员分别按自己的方式对齐,并能最小化长度 zm4Okg)w@
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 li;Np5P
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 +RQlMAB
~F~g$E2 }
"gjy+eosY
网友xue23(xue23) 的答案和分析: Qc#<RbLL
ba& \~_4
有程序查一下各个变量的内存地址得知: pE@Q
(9`b{
各个变量在内存中的位置为 F?&n5