Intel和微软同时出现的C语言面试题 SQ.4IWT(hR
#pragma pack(8) 2f:'~ P56
wR;l"*j
struct s1{ }K*ri
short a; PH7L#H^
long b; {xH
\!!"T
}; /ZzlC#`
%kc g#p+tE
struct s2{ RU{}qPs?
char c; 1B1d>V$*
s1 d; RF;N]A?*
long long e; yjSN;3t71
}; `2@-'/$\I|
xS(sR x+A
#pragma pack() TWs|lhC7!
yq<YGNy!
问 QqwXFk
1.sizeof(s2) = ? !3b%Q</M H
2.s2的s1中的a后面空了几个字节接着是b? Wt`D
3%P?1s
"(xS[i
.H>Rqikj
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: S 5d{dTPq
q6ikJ8E8b
网友rwxybh(行云)的答案: kl={L{r
内存布局是 5sE^MS1
1*** 11** {c J6Lq&
1111 **** h)<R#xw
1111 1111 )ld7^G
%/^d]#
所以答案就是24和3 #>,cc?H-
1z`,*eD7
下面是一个测试的程序,试一试就知道了,我用的是VC2005 }UO,R~q~
D~y]d
#pragma pack(8) <N*>9S,}
Q0--.Q=:Y
struct s1{ ]u,~/Gy
short a; // 2 BYtes /Mk)H
d
long b; // 4 Bytes B.WJ6.DkS
}; y H'\<bT
struct s2{ ~"wD4Ue
char c; // 1 Byte nY8UJy}<oL
s1 d; // 8 Bytes q-RGplx
long long e; // 8 Bytes |4c==7.
}; OP&[5X+Y
// 1*** 11** D!P?sq _5r
// 1111 **** XMdc n,
// 1111 1111 o2|(0uN'
// MvW>ktkU
+sI.GWQ_:
// 00 01 02 03 04 05 06 07 a(7ryl~c=
// 00 01 02 03 04 05 06 07 xC{NIOYn'
// 00 01 02 03 04 05 06 07 x3P@AC$\
// _kd |:,
#pragma pack() Z\L@5.*ydE
H|Nw)*.
int main(int argc, char* argv[]) "5YdmBy
{ LBE".+
s2 a; j"V$J8)[
char *p = (char *)&a; 35>}$1?-6
for(int i=0;i<24;++i) Ocb2XEF
p = (char)(i%8); "h2Ny#
printf("%d\n",sizeof(a)); |]q=D1/A
printf("c=0x%lx\n",a.c); s6D-?G*u%8
printf("d.a=0x%x\n",a.d.a); H94.E|Q\+
printf("d.b=0x%x\n",a.d.b); s/^k;qw
printf("e=0x%llx\n",a.e); kmoJ`W} N
return 0; Z])_E6.
} n,F00YR
结果: v<SEGv-
24 !lF^~x
c=0x0 f+920/>!Z
d.a=0x504 -b$OHFL
d.b=0x3020100 Q#N+5<]J)#
e=0x706050403020100 6ZR0_v;TD
@5wg' mM
W~tOH=9>
网友 redleaves (ID最吊的网友)的答案和分析: OeYLL4H
@NIypi$T
如果代码: T]W -g
#pragma pack(8) 8x"d/D
struct S1{ f*],j
char a; (HI%C@e9
long b; _Pkh`}W:
}; !_) ^bRd
struct S2 { RV`j>1
char c; =dBrmMh
struct S1 d; /6zpVkV
long long e; 0I((UA/7Zs
}; CiI:
uU
#pragma pack() ]e.+u
sizeof(S2)结果为24. QZr<=}
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. 8~E)gV+v
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. MPbPq3an
<&:&qngg
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; ef&@aB
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. "6yiQ\`J
a b Td*Oljj._U
S1的内存布局:11**,1111, bFezTl{M
c S1.a S1.b d 5V~p@vCx
S2的内存布局:1***,11**,1111,****11111111 <y!r~?
UwkX[u
这里有三点很重要: ^4pKsO3ul
1.每个成员分别按自己的方式对齐,并能最小化长度 o2 d~
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 Ki/5xK=s
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 ^~qs-.?
k_<{j0z.
X3{1DY3@u
网友xue23(xue23) 的答案和分析: i8_x1=A
U!:!]DX(
有程序查一下各个变量的内存地址得知: oxQID
各个变量在内存中的位置为 %:KV2GP
c***aa** vQmackY
bbbb**** !`[I>:Ex
dddddddd 8 QF?W{NK
测试代码为: $sF#Na4^
s2 ss; 5jV97x)BGx
cout << "ss.c = " << &ss << endl ; F9P0cGDs
cout << "ss.d.a = " <<&ss.d.a << endl; ^:DhHqvK
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; Pmlgh&Z
print out 各个变量的内存地址不就可以看出来了吗。 VhFRh,J(T
=veOVv[Q&/
所以答案是24,2. noNF;zT
AH'4H."o/9
但是我的想像中应该是这样的分布情况: A}bHfn|
c******* eD{ @0&
aa**bbbb 8='21@wrN
dddddddd <nTmZ-;
ef}E.Bl
不知为什么会c和a放在一起,组成8位长度。