Intel和微软同时出现的C语言面试题 mk~Lkwl
#pragma pack(8) SY2B\TV
8:A6Ew&\]O
struct s1{ mY1$N}8fm
short a; 2?7a\s
long b; C44Dz.rs
}; l>9ZAI\^
`Uw^,r
struct s2{ P3YG:*
char c; FCmS3KIa,
s1 d; 5k}UXRB?
long long e; Xl%&hM
}; VuW&CnZ
@le23+q
#pragma pack() R=M${u<t
yz2NB?)
问 Wc_Ph40C<_
1.sizeof(s2) = ? 8YBsYKC
2.s2的s1中的a后面空了几个字节接着是b? {/ _.]Vh
$NWI_F4
uEuK1f`
'm"H*f
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: ^\\cGJ&8c
T3{qn$t8
网友rwxybh(行云)的答案: [XQoag;!
内存布局是 _hLM\L
1*** 11** 'u.`!w '|L
1111 **** ~c3CyOab
1111 1111 ZA ii"F
o*QhoDjc
所以答案就是24和3 ziy~~J
zn3i2MWS
下面是一个测试的程序,试一试就知道了,我用的是VC2005 )5X7|*LP
?z60b=f8
#pragma pack(8) ^IM;D)X&:
_" F(w"|
struct s1{ rC<m6
short a; // 2 BYtes NzRL(A6V
long b; // 4 Bytes rReZ$U
}; A\.M/)Qo
struct s2{ v1zJr6ra9
char c; // 1 Byte (F7!&] 8%
s1 d; // 8 Bytes J74nAC%J^
long long e; // 8 Bytes rYq8OZLi
}; 4Kt?; y
;
// 1*** 11** QkzPzbF"
// 1111 **** `&>!a
// 1111 1111 YrgwR
// O`mW,
KFC zf_P!
// 00 01 02 03 04 05 06 07 Ty]CdyL$
// 00 01 02 03 04 05 06 07 G#CWl),=
// 00 01 02 03 04 05 06 07 t L;;Yt
// +]|J
#pragma pack() 8F4#E
U
nS'0i&<{1
int main(int argc, char* argv[]) w];t ]q|
{ OY`G _=6!N
s2 a; /sdkQ{J!.
char *p = (char *)&a; 88)0Xi|]KP
for(int i=0;i<24;++i) JUU0Tx:`9)
p = (char)(i%8); )CXJRo`j0
printf("%d\n",sizeof(a)); |g4!Yd
printf("c=0x%lx\n",a.c);
OH*[
printf("d.a=0x%x\n",a.d.a); m.EWYO0XQ
printf("d.b=0x%x\n",a.d.b); ^#%$?w>wI
printf("e=0x%llx\n",a.e); +V7*vlx-
return 0; T0RgCU
IV
} +|(
eP_
结果: K22W=B)Ln
24 )kgy L,9
c=0x0 *Xl&N- 04
d.a=0x504 F=^vu7rf
d.b=0x3020100 NP^kbF
e=0x706050403020100 ;][1_
WFN5&7$ W
FQ(=Fnqn
网友 redleaves (ID最吊的网友)的答案和分析: }(TZ}* d
o&LNtl;
如果代码: qdj,Qz9ly
#pragma pack(8) 9[6*FAFJPP
struct S1{ FJ>| l#nO
char a; m=NX;t
long b; m2<sVTN`^
}; )X| uOg&|
struct S2 { w>VM--
char c; -oe&1RrdVg
struct S1 d;
D[]vJ
long long e; oOe5IczS(
}; /k}vm3
#pragma pack() |n~,$
sizeof(S2)结果为24. O2Rv^la
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. S <|e/![@
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. 0-4WLMx
]rHdG^0uss
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; lgA9p
4-
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. "vjz $.
a b }e9:2
S1的内存布局:11**,1111, R[Kyq|UyVr
c S1.a S1.b d KH2a 2
S2的内存布局:1***,11**,1111,****11111111 ^i#q{@g
cD2}EqZ 9
这里有三点很重要: ~c3!,C
1.每个成员分别按自己的方式对齐,并能最小化长度 P7"g/j" "
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 k9WihejS
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 T6-e
&HZ"<y{j
7PP76$
网友xue23(xue23) 的答案和分析: .wS' Xn&
+<AX
0(
有程序查一下各个变量的内存地址得知: `;4zIBJ
各个变量在内存中的位置为 jcOxtDTSW
c***aa** C8@SuJ
bbbb**** ;9 XM
s)
dddddddd i~.L{K
测试代码为: sRb)*p'
s2 ss; (K>5DU
cout << "ss.c = " << &ss << endl ; MBDu0
[c
cout << "ss.d.a = " <<&ss.d.a << endl; RNp3lXf O
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; #th^\pV
print out 各个变量的内存地址不就可以看出来了吗。 $0sUh]7y
8TC%]SvYim
所以答案是24,2. Q6kkMLh
nP4jOq*H
但是我的想像中应该是这样的分布情况: O^4:4tRpt
c******* Z]":xl\7
aa**bbbb y$#mk3(e~t
dddddddd )5)S8~Oc
B]InOlc47
不知为什么会c和a放在一起,组成8位长度。