Intel和微软同时出现的C语言面试题 c[X:vDUX
#pragma pack(8) z`(">J
55Ag<\7
struct s1{ }b=Cv?Zg$m
short a; eH^~r{{R
long b; *m*sg64Zw
}; MeW?z|x`'
=gQ^,x0R9
struct s2{ h@%a+ 6b?
char c; (qdvvu#E
s1 d; LGT?/gup
long long e; xj;V
}; _BHEK
^vha4<'-qG
#pragma pack() e]-%P(}Z
+~f=L- >
问 }0idFotck
1.sizeof(s2) = ? }) Zcw1g
2.s2的s1中的a后面空了几个字节接着是b? zLybf:#
*I9O+/,
/MZ^;XG
6 U_P
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考: Aqo90(jffx
)SyU
网友rwxybh(行云)的答案: W(\^6S)
内存布局是 O#?@'1
1*** 11** "? ON0u9
1111 **** 3{9d5p|\i
1111 1111 t$g@+1p4
3 @%XR8ss
所以答案就是24和3 C@{-$z)
]8CgHT[^7
下面是一个测试的程序,试一试就知道了,我用的是VC2005 {fa3"k_ke
P$5K[Y4f
#pragma pack(8) qB5.of[N!
JasA
w7
struct s1{ ]-cSTtO
short a; // 2 BYtes DIF-%X5
long b; // 4 Bytes +0g L!r
}; l;i/$Yu7
struct s2{ -mw`f)?Ev
char c; // 1 Byte #Fz/}lO
s1 d; // 8 Bytes AL;4-(KH
long long e; // 8 Bytes `T3B
}; #jM-XK
// 1*** 11** odW K\e
// 1111 **** P7\?WN$p
// 1111 1111 Z7p!YTA
// f"SK3hI$p
9PdD =9HH
// 00 01 02 03 04 05 06 07 tn}MKo
// 00 01 02 03 04 05 06 07 .zv BV_I
// 00 01 02 03 04 05 06 07 B}0!b7!
// :*Y2na)qQ
#pragma pack() N5. B"l
(9Q@I8}Iy
int main(int argc, char* argv[]) %"^8$A?>,k
{ ZQ{-6VCjl
s2 a; 1P?|.W_^1
char *p = (char *)&a; '9!J' [W
for(int i=0;i<24;++i) a'(B}B=h
p = (char)(i%8); Vrs?VA`v$
printf("%d\n",sizeof(a)); i!EAs`$o`
printf("c=0x%lx\n",a.c); Oi<yT"7
printf("d.a=0x%x\n",a.d.a); 5i+cjT2
printf("d.b=0x%x\n",a.d.b); XIn,nCY;
printf("e=0x%llx\n",a.e); <.&84c]/&
return 0; 'OvM
} GglGFXOL-
结果: 45rG\$%#
24 **JBZ \'
c=0x0 2P ^x'I
d.a=0x504 Raf(m,o(
d.b=0x3020100 -\n%K
e=0x706050403020100 .FG%QF F~
<QD[hO^/
JJK-+a6cX
网友 redleaves (ID最吊的网友)的答案和分析: Z@}qL1
f+1@mGt
如果代码: QD%!a{I
#pragma pack(8) sE&1ZJ]7
struct S1{ HI7w@V8Ed
char a; ~*x 2IPiH
long b; @qEUp7W.?
}; c(aykIVOo
struct S2 { 6V*,nocL_+
char c; ,Oe:SZJ>
struct S1 d; {
&Vt]9
long long e; F^81?Fi.
}; OrwVRqW-z
#pragma pack() nc6PSj X
sizeof(S2)结果为24. E+lr{~
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐. RFoCM^
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节. ?tA%A
EjMVlZC>
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8; G.`},c;A-
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节. b!bg sd
a b voQJ!h1
S1的内存布局:11**,1111, `aTw!QBfG
c S1.a S1.b d #nw+U+qL
S2的内存布局:1***,11**,1111,****11111111 0TZB}c#qT
<Zvvx
这里有三点很重要: LI].*n/v
1.每个成员分别按自己的方式对齐,并能最小化长度 Q[?R{w6
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 X9ZHYlr+Q
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 tQas_K5
`QtkC>[
+P8CC fPu
网友xue23(xue23) 的答案和分析: )ZI#F]
-K3d u&j
有程序查一下各个变量的内存地址得知: "$pbK:
各个变量在内存中的位置为 u`D _
c***aa** d::9,~
bbbb**** OTl9MwW
dddddddd &>&6OV]P'
测试代码为: [!4xInS
s2 ss; ?5J>]: +ZZ
cout << "ss.c = " << &ss << endl ; Tdm|=xI
cout << "ss.d.a = " <<&ss.d.a << endl; 8i5S
}
cout << "ss.d.b = " <<&(ss.d.b) < cout << "ss.d = " <<&ss.e << endl; {xeJO:M3/
print out 各个变量的内存地址不就可以看出来了吗。 rVP{ ^Jdo
'v9M``
所以答案是24,2. Bal e_s^
3!$+N\ #w
但是我的想像中应该是这样的分布情况: at4JLbk
c******* D, Gv nfY
aa**bbbb )[oP`Z
dddddddd b.v +5=)B
r8?p6E
不知为什么会c和a放在一起,组成8位长度。