Intel和微软同时出现的C语言面试题 1nLFtiki
#pragma pack(8) g]}]/\
&zP\K~Nt
struct s1{ e8]mdU{)
short a; H~*[v"
long b; &P8Q|A-u
}; x2f_>tu2
T?5F0WKi
struct s2{ `+r5I5
char c; IZ4jFgpR
s1 d; +n`^W(
long long e; yFP#z5G
}; P|)SXR
,%m$_wA$
#pragma pack() Xg"Mjmr
KQqQ@D&n
问 !lB,2_
1.sizeof(s2) = ? [c6_6q As
2.s2的s1中的a后面空了几个字节接着是b? aR;Q^YJ+a
UuA=qWC
f.r-,%^6{
8%U)EU
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: t,P+~ A
|y=D^NTG
网友rwxybh(行云)的答案: #$fFp
内存布局是 cKy%0oTla
1*** 11** N=L
urXv
1111 **** }mJ)gK5b 6
1111 1111 B "}GAk}V
DFjkp;`1
所以答案就是24和3 tv|=`~Y
)Zm E"
下面是一个测试的程序,试一试就知道了,我用的是VC2005 Bp6Evi
zKWi9
#pragma pack(8) r*3XM{bZ/@
f%auz4CZz
struct s1{ p-/x Md
short a; // 2 BYtes ~d5{Q?T)
long b; // 4 Bytes EGMcU|yL
}; wy&*6>.
struct s2{ O "h+i>|l
char c; // 1 Byte #QDV_ziE5
s1 d; // 8 Bytes XJ NKM~
long long e; // 8 Bytes ,wEM
};
nocH~bAf2
// 1*** 11** !kKKJ~,;
// 1111 **** )DLK<10
// 1111 1111 y! 1NS
// P?uKDON
V+K.'
J
^@
// 00 01 02 03 04 05 06 07 >)
:d38M
// 00 01 02 03 04 05 06 07 NAocmbfNz
// 00 01 02 03 04 05 06 07 nMbV{h ,
// XF$C)id2p
#pragma pack() Zj<T#4?8
) D`_V.,W
int main(int argc, char* argv[]) BZ T%+s;u9
{ &boBu^,94
s2 a; q.X-2jjpx:
char *p = (char *)&a; (6+0U1[Iz
for(int i=0;i<24;++i) Ek.j@79
p = (char)(i%8); RGKJO_*J2
printf("%d\n",sizeof(a)); +[7u>RJ
printf("c=0x%lx\n",a.c); ]-`{kX
printf("d.a=0x%x\n",a.d.a); =f p(hX"
printf("d.b=0x%x\n",a.d.b); 5m3sjcp_
printf("e=0x%llx\n",a.e); Zj0&/S
return 0; }R'oAE}$
} 7I
结果: #WG(V%f]
24 D.GSl
c=0x0 =w5w=qB
d.a=0x504 j)5Vv
K\
d.b=0x3020100 zBR]bk\
e=0x706050403020100 +Snjb0
J{ Vl2P?@
}A;Xd/,'r
网友 redleaves (ID最吊的网友)的答案和分析: 334*nQ
BMW4E 5
如果代码: <.2Z{;z
#pragma pack(8) RinRQd
struct S1{ 3QVng^"B)
char a; kgu+q\?
long b; lb('r"*.
}; _Owz%
struct S2 { nNKL{Hp
char c; 3^a"$VW1
struct S1 d; L$Q+R'
long long e; |g{AD`
}; a`uT'g[*
#pragma pack() td~3N,S
sizeof(S2)结果为24. 8K/lpqw
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 9+']`=a:
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 4SrK]+|
7$;$4.'
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; )wRD
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. {1+H\(v
a b FRW.
S1的内存布局:11**,1111, 8FITcK^
c S1.a S1.b d UTt#ltun ?
S2的内存布局:1***,11**,1111,****11111111 !Z ZA I_N
;a`X|N9
这里有三点很重要: ~83P09\T%
1.每个成员分别按自己的方式对齐,并能最小化长度 1DP)6{x
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 dw|0K+-PH
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 ,L;vN6~
`dZ|}4[1
UK,P?_e
网友xue23(xue23) 的答案和分析: NsHveOK1.
O#\>j
有程序查一下各个变量的内存地址得知: =.c"&,c?L
各个变量在内存中的位置为 ~e<<aTwN
c***aa** v2'JL(=
bbbb**** Ln|${c
dddddddd "q.uiz+1:
测试代码为: di5_5_$`o
s2 ss; %U7B0-
cout << "ss.c = " << &ss << endl ; hz%IxI9
cout << "ss.d.a = " <<&ss.d.a << endl; ap~Iz
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl;
_1'Pb/1
print out 各个变量的内存地址不就可以看出来了吗。 ;GSJnV
Cs{f'I
所以答案是24,2. M\f0
=`g
JPG!cX%
但是我的想像中应该是这样的分布情况:
P+0xi
c******* 'r%oOZk)z
aa**bbbb bB-v ar
dddddddd h'p0V@!N
;>9pJ72r
不知为什么会c和a放在一起,组成8位长度。