Intel和微软同时出现的C语言面试题 m(IyW734I
#pragma pack(8) ^u> fW["[
^/~C\
(
struct s1{ rDv`E^\
short a; 5A+r^xN
long b; {'yr)(:2M
}; OJD!Ar8Q
t]E@AJOK
struct s2{ /6:qmh2
char c; /xCX. C
s1 d; lr ]C'dD
long long e; \k5
sdHmI[
}; .JV y}^Q\
EkoT U#w5
#pragma pack() pj Md
{xf00/
问 v(zfq'^%`
1.sizeof(s2) = ? WWT1_&0
2.s2的s1中的a后面空了几个字节接着是b? !o\e/HGc!
Ll, U>yo
dUv(Pu(.#
yz=aJ
v;
H
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: \LM.>vJ
}^2'@y!(
网友rwxybh(行云)的答案: f dJ<(i]7W
内存布局是 Z29aRi
1*** 11** O]KQ]zN
1111 **** ]I\9S{?
1111 1111 s7,D}Zz
c$x>6&&L
所以答案就是24和3 73JrK_h
QW_BT^d"
下面是一个测试的程序,试一试就知道了,我用的是VC2005 "[0.a\ d<
#I\" 'n5M
#pragma pack(8) .-)kIFMi
zbj V>5
struct s1{ nPk&/H%5hn
short a; // 2 BYtes u:H:N]
long b; // 4 Bytes AWi+xo|
}; +
]iK^y-.r
struct s2{ }b]eiPWN
char c; // 1 Byte `pF7B6[B
s1 d; // 8 Bytes G&08Qb ,N
long long e; // 8 Bytes L_o/fTz4
}; e'->S g
// 1*** 11** D 9UM8Hxi
// 1111 **** ij1YV2v
// 1111 1111 )iFXa<5h
// =_CH$F!U
+!ZfJZls
// 00 01 02 03 04 05 06 07 '4CD
}
// 00 01 02 03 04 05 06 07 u<4bOJn({
// 00 01 02 03 04 05 06 07 <v=s:^;C0
// MjWxfW/
#pragma pack() /EuH2cy$l
$9@AwS@Uu
int main(int argc, char* argv[]) MGY0^6yK5
{ zO@>)@~
s2 a; hzT)5'_
char *p = (char *)&a; XlnSh<e
for(int i=0;i<24;++i) -hc8IS
p = (char)(i%8); RhC|x,E
printf("%d\n",sizeof(a)); BWNI|pq)v
printf("c=0x%lx\n",a.c); J57; X=M
printf("d.a=0x%x\n",a.d.a); pw`'q(ad
printf("d.b=0x%x\n",a.d.b); UZ#oaD8H6
printf("e=0x%llx\n",a.e); _07$TC1
return 0; *eX/ZCn
} *f_A:`:
结果: V7.g,
24 JW)f'r_f
c=0x0 tG ZMIG_
d.a=0x504 Cy)N hgz
d.b=0x3020100 ]k'^yc{5
e=0x706050403020100 XMdCQ=
qDU4W7|T`
6P:fM Y
网友 redleaves (ID最吊的网友)的答案和分析: #Ge_3^'
w)B?j
如果代码: zWH)\>X59
#pragma pack(8) WA0D#yuJ/
struct S1{ lQBEq"7$
char a; !0vLSF=
long b; /V63yzoY
}; EB*C;ms
struct S2 { boHbiE
char c; E
AZX
struct S1 d; `(
w"{8laB
long long e; ifu!6_b.
}; 3
^K#\*P
#pragma pack() W)J MV
sizeof(S2)结果为24. \P")Eh =d
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. f*xr0l
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. j--byk6PB
CWocb=E
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; -
jCj_@n
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. |xg_z&dX
a b fGqX
dlP
S1的内存布局:11**,1111, "j8)l4}
c S1.a S1.b d gPb.%^p
S2的内存布局:1***,11**,1111,****11111111 n:2._s T
MtaGv#mJ
这里有三点很重要: P/.<sr=2
1.每个成员分别按自己的方式对齐,并能最小化长度 miu?X !
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 <U1T_fiBoc
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 4dcm)Xr
y_w
<3
X^K^az&L
网友xue23(xue23) 的答案和分析: ~J&-~<%P}
goA=U
有程序查一下各个变量的内存地址得知: /I!62?)-*
各个变量在内存中的位置为 yCav;ZS_
c***aa** T!ZjgCY}
bbbb****
{it}\[3
dddddddd /e|Lw4$@S
测试代码为: A[ncwJ
s2 ss; 6lv@4R^u
cout << "ss.c = " << &ss << endl ; kLF`6ZXtd
cout << "ss.d.a = " <<&ss.d.a << endl; 5RFro^S9E
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; Pd\4hy
print out 各个变量的内存地址不就可以看出来了吗。 7C0xKF
ZTV)D
所以答案是24,2. v/9ZTd
4\u`MR
但是我的想像中应该是这样的分布情况: Wc2&3p9 c
c******* ?]$<Ufr
aa**bbbb <%Nf"p{K
dddddddd ^4+NPk
$qz{L~ <
不知为什么会c和a放在一起,组成8位长度。