Intel和微软同时出现的C语言面试题 MQ w9X
#pragma pack(8) qe?Ggz3p.
aPBX=;(
struct s1{ 3ut_Bt\
short a; WM< \e
long b; G.jQX'%4QG
}; t[O+B6
rc~Y=m
struct s2{
U1\MA6pXW
char c; "Gh#`T0#a
s1 d; K`+vfqX
long long e; zzJ^x8#R
}; BR3mAF
kkfCAM
#pragma pack() NhlJ3/J j
N{pa)
/
问 "Z9^}
1.sizeof(s2) = ? hmzair3X
2.s2的s1中的a后面空了几个字节接着是b? 7+8bL{
HD|sr{Z%
vahf]2jEB
mVrK z
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: |>JmS
KZ\dB;W<|
网友rwxybh(行云)的答案: 7,su f }=
内存布局是 R#fy60
1*** 11** 2mOfsn d@
1111 **** ,lP7 ri
1111 1111 Ltg-w\?]
|0DP}
`~
所以答案就是24和3 }wG|%Y#+r
bXm:]?
下面是一个测试的程序,试一试就知道了,我用的是VC2005 VS%@)sI|Z
hs,5LV)|y
#pragma pack(8) 6m\*]nOy4
<[FS%2,0mb
struct s1{ f-s~Q4
short a; // 2 BYtes -g$OOJB6
long b; // 4 Bytes _X?y,#
}; 7(5]Ry:
struct s2{ yHtGp%j
char c; // 1 Byte QS%,7'EG
s1 d; // 8 Bytes wK ][qZ ]
long long e; // 8 Bytes e18T(g_i
}; @|]iSD&T
#
// 1*** 11** gpsrw>nw
// 1111 **** B~4mk
// 1111 1111
B,:23[v
// -MUQ\pZ
Ol_/uy1r[
// 00 01 02 03 04 05 06 07
Tu'E{Hw
// 00 01 02 03 04 05 06 07 "1CGO@AXS
// 00 01 02 03 04 05 06 07 `^`9{@~
// 2}>go^#O/w
#pragma pack() }o{!}g9
.8%vd
int main(int argc, char* argv[]) ?^ eJ:
{ f5N<3 m=
s2 a; w[M5M2CF
char *p = (char *)&a; q>c+bo
6
for(int i=0;i<24;++i) JH-nvv
p = (char)(i%8); ?Ip$;s
printf("%d\n",sizeof(a)); @!,D%]8"
printf("c=0x%lx\n",a.c); -^y1iN'D
printf("d.a=0x%x\n",a.d.a); pO5v*oONz+
printf("d.b=0x%x\n",a.d.b); :Z]/Q/$
printf("e=0x%llx\n",a.e); 8[f8k3g
return 0; W3aXW,P. V
} 7kOE/>P?
结果: Kl!DKeF
24 US"2O!u
c=0x0 rg"TJ"Q-
d.a=0x504 N.k+AQb
d.b=0x3020100 S54gqc1S]
e=0x706050403020100 nJW_a&'
EF0Pt
`g2&{)3k
网友 redleaves (ID最吊的网友)的答案和分析: 6{lG1\o
WNl&v]
如果代码: t4C<#nfo
#pragma pack(8) (xjqB{U
struct S1{ sf<Q#ieTxY
char a; cYE./1D a
long b; !XkymIX~O.
}; i#Ne'q;T
struct S2 { @G7w(>_T3
char c; ~r{\WZ.
struct S1 d; 4o)(d=q
long long e; C+ZQB)gn
};
#_?426Wfs
#pragma pack() XPGL3[w\V
sizeof(S2)结果为24. 0EcC
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. |Gf1^8:C9
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. tCd{G
c
5@GD} oAn6
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; !5yRWMO9X~
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. bEoB;]
a b />2A<{6\=P
S1的内存布局:11**,1111, Xp<A@2wt?
c S1.a S1.b d ~R"]LbeY
S2的内存布局:1***,11**,1111,****11111111 :|*Gnu
/8 e2dw:
\
这里有三点很重要: f)p>nW?Z
1.每个成员分别按自己的方式对齐,并能最小化长度 Aqx3!
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 C.b,]7i
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 Dlqn~
tjBh$)
Z[DetRc-
网友xue23(xue23) 的答案和分析: rC* sNy2
rTWh(8T
有程序查一下各个变量的内存地址得知: YlZYS'_
各个变量在内存中的位置为 7F>gj
c***aa** >!:$@!6L
bbbb**** 2GHXn:V
dddddddd i*mZi4URN
测试代码为: [q0_7
s2 ss; u|]mcZ,ZW
cout << "ss.c = " << &ss << endl ; ]
P:NnKgK
cout << "ss.d.a = " <<&ss.d.a << endl; [=]+lei
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; 7,) 67G;
print out 各个变量的内存地址不就可以看出来了吗。 + 1E?He:iQ
$gj+v+%N
所以答案是24,2. qcR|E`k-G
]Ct`4pA
但是我的想像中应该是这样的分布情况: =
]dz1~/
c******* Q#yu(
aa**bbbb BK`Q)[
dddddddd 0~PXa(!^K
I?^Q084
不知为什么会c和a放在一起,组成8位长度。