Intel和微软和本公司同时出现的面试题
#pragma pack(8)
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long long e;
};
#pragma pack()
问
1.sizeof(s2) = ?
2.s2的s1中的a后面空了几个字节接着是b?
问题点数:200、回复次数:122Top
1 楼Varg(Varg)回复于 2005-02-24 17:15:44 得分 1
When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each structure member after the first is stored on the smaller member type or n-byte boundaries.Top
2 楼Oversense(步步文)回复于 2005-02-24 17:24:05 得分 0
第二个问题写错了,是
2.s2的c后面空了几个字节接着是d?Top
3 楼Varg(Varg)回复于 2005-02-24 17:26:33 得分 1
sizeof(s2)==16Top
4 楼wwwllg(野蛮人)回复于 2005-02-24 17:29:51 得分 1
1.16
2.4
猜的。
Top
5 楼fisker0303(天塌了,地陷了,小花狗不见了.)回复于 2005-02-24 17:30:08 得分 1
以前看过篇文章介绍的很清楚,现在忘了,5555Top
6 楼wwwllg(野蛮人)回复于 2005-02-24 17:32:43 得分 1
晕,是24,Top
7 楼laowang456(wangyulei)回复于 2005-02-24 17:37:43 得分 1
很变态的题阿,我是写程序写了二年多才了解PACK的猫腻的Top
8 楼wenddy112(敬)回复于 2005-02-24 17:53:29 得分 1
http://blog.csdn.net/wenddy112/articles/300583.aspxTop
9 楼alec626(月吻长河Blog:spaces.msn.com/filebase)回复于 2005-02-24 19:02:15 得分 1
好题!Top
10 楼kobefly(科比--网络学习中)回复于 2005-02-25 19:11:47 得分 1
这个题目真的不错啊
字节对齐的问题
里边还加了结构嵌套
不错啊Top
11 楼goodluckyxl(被人遗忘的狗)回复于 2005-02-25 19:19:05 得分 1
16 没空Top
12 楼kobefly(科比--网络学习中)回复于 2005-02-25 19:23:42 得分 1
他这里的long long 估计是8字节的那种类型
就不是16拉
可以用double代替
因为我这里没这种类型
哈哈Top
13 楼eric_shenzhen(衣带渐宽终不悔,为伊消的人憔悴)回复于 2005-02-25 19:34:30 得分 1
这样的题真是不错,用了3年多c了,平时感觉真是“精通”了,其实还是在大海中寻找方向!Top
14 楼yrhkxg(小鹤)回复于 2005-02-25 20:36:08 得分 1
1.24
2.3Top
15 楼ybt631(默默耕耘!)回复于 2005-02-25 20:40:32 得分 1
32 和6Top
16 楼melonliu(I believe I can FLY!!)回复于 2005-02-25 20:40:33 得分 0
alignTop
17 楼w7x(舍我其谁)回复于 2005-02-25 20:41:48 得分 1
1,24 vc++ 2005 express long long's size is 8 byte
2,我想应该不在中间空吧,在e后面空9个Top
18 楼tongdegang2005(boy)回复于 2005-02-25 21:22:31 得分 1
1.sizeof(s2) = ?
sizeof(s2) =16=4+8+4
2.s2的s1中的a后面空了几个字节接着是b?
空了2个字节接着是b。Top
19 楼FePwaw(A呜)回复于 2005-02-25 21:41:01 得分 1
1 4 + 8 + 8 = 20
2 4 -1 = 3Top
20 楼waterinsunny(aj)回复于 2005-02-25 22:07:52 得分 1
这是错误的Top
21 楼careprad(深蓝芝心)回复于 2005-02-25 22:48:17 得分 0
mark!Top
22 楼Augustus(左右张望)回复于 2005-02-25 23:15:14 得分 1
struct s2 {
c, , , ,
struct s1 {
a a, , ,
b b b b, }
, , , ,
d d d d,
d d d d
画过内存分布示意图出来。答案自己看了Top
23 楼redchina(风清云淡)回复于 2005-02-26 01:52:40 得分 1
结构1的内存布局:11**,1111,
结构2的内存布局:1***,11**,1111,11111111****
所以sizeof(s2) =24;s2的c后面空了3个字节接着是d
Top
24 楼idau7((小i不怕)我爱Eva)回复于 2005-02-26 01:53:35 得分 0
唉...一声叹息.Top
25 楼redchina(风清云淡)回复于 2005-02-26 01:58:52 得分 1
嗯,结构2的内存布局是1***,11**,1111,****11111111
Augustus(登高望远)说的对。
Top
26 楼zhengwei1984222(阿什坎迪.兄弟会之剑)回复于 2005-02-26 02:12:08 得分 1
1.sizeof(s2) = 16
2.s2的s1中的a后面空了几个字节接着是b?0个
布局:c-aa bbbb eeeeTop
27 楼zhengwei1984222(阿什坎迪.兄弟会之剑)回复于 2005-02-26 02:13:15 得分 1
布局:c-aa bbbb eeee eeee
Top
28 楼shishulv(小记者)回复于 2005-02-26 12:25:35 得分 1
就是Augustus(登高望远)说的。Top
29 楼Jackallen(逸海蛟龙)回复于 2005-02-26 14:01:35 得分 1
24
2Top
30 楼busade1()回复于 2005-02-26 14:20:49 得分 0
长知识Top
31 楼rwxybh(行云)回复于 2005-02-26 15:36:26 得分 5
内存布局确实如Augustus(登高望远)说的。是
1*** 11**
1111 ****
1111 1111
所以答案就是24和3
下面是一个测试的程序,试一试就知道了,我用的是VC2005
#pragma pack(8)
struct s1{
short a; // 2 BYtes
long b; // 4 Bytes
};
struct s2{
char c; // 1 Byte
s1 d; // 8 Bytes
long long e; // 8 Bytes
};
// 1*** 11**
// 1111 ****
// 1111 1111
//
// 00 01 02 03 04 05 06 07
// 00 01 02 03 04 05 06 07
// 00 01 02 03 04 05 06 07
//
#pragma pack()
int main(int argc, char* argv[])
{
s2 a;
char *p = (char *)&a;
for(int i=0;i<24;++i)
p[i] = (char)(i%8);
printf("%d\n",sizeof(a));
printf("c=0x%lx\n",a.c);
printf("d.a=0x%x\n",a.d.a);
printf("d.b=0x%x\n",a.d.b);
printf("e=0x%llx\n",a.e);
return 0;
}
结果:
24
c=0x0
d.a=0x504
d.b=0x3020100
e=0x706050403020100
Top
32 楼cat_dog(东方软件)回复于 2005-02-26 15:51:48 得分 1
应该是24,7
内存结构不是上面说的那样,应如下所示:
1*** **** c
11** 1111 s1
1111 1111 d
sizeof(s1) = 8; 所以的起始地址必须是8字节对齐。
Top
33 楼yitiaoming2003(小钱)回复于 2005-02-26 15:55:35 得分 0
同意楼上的Top
34 楼stevens2009(风)回复于 2005-02-26 16:04:29 得分 0
mTop
35 楼cxc014(有心插柳柳不活,无心栽花花开花?)回复于 2005-02-26 16:51:45 得分 0
回复人: cat_dog(东方软件) ( ) 信誉:100
说的是正确的Top
36 楼YFY(天易)回复于 2005-02-26 16:59:40 得分 0
先顶下再看Top
37 楼redleaves(程序员)回复于 2005-02-26 17:25:17 得分 5
还是我给出正确答案吧:
如果代码:
#pragma pack(8)
struct S1{
char a;
long b;
};
struct S2 {
char c;
struct S1 d;
long long e;
};
#pragma pack()
sizeof(S2)结果为24.
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节.
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,11**,1111,****11111111
这里有三点很重要:
1.每个成员分别按自己的方式对齐,并能最小化长度
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐
Top
38 楼dongpy(51-->ARM)回复于 2005-02-26 17:26:37 得分 1
sizeof(s2) = 24Top
39 楼redleaves(程序员)回复于 2005-02-26 17:31:32 得分 1
补充一下,对于数组,比如:
char a[3];这种,它的对齐方式和分别写3个char是一样的.也就是说它还是按1个字节对齐.
如果写: typedef char Array3[3];
Array3这种类型的对齐方式还是按1个字节对齐,而不是按它的长度.
不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个.Top
40 楼dongpy(51-->ARM)回复于 2005-02-26 17:42:40 得分 0
学习,redleaves讲解的太透彻了!Top
41 楼yc0188(守护瓶(萍))回复于 2005-02-26 18:35:25 得分 0
讲的太好了.
Top
42 楼melonliu(I believe I can FLY!!)回复于 2005-02-26 18:38:34 得分 0
redleaves的讲解就像我最近看的嵌入式系统汇编,呵呵Top
43 楼yangfasheng(悟法:前面是绝路,希望在拐角)回复于 2005-02-26 18:41:16 得分 1
C99中支持long long e数据类型,char a,应该考虑字节对齐,
4+4+4+8
空3个字节Top
44 楼paddy102(▄︻┻┳═一)回复于 2005-02-26 20:20:57 得分 0
长见识了Top
45 楼ppcust(@小猪&毛毛虫@)回复于 2005-02-26 21:02:06 得分 0
支持。。。Top
46 楼wyd124(鱼日)回复于 2005-02-26 21:56:30 得分 0
如果把 #pragma pack(8) 换成 #pragma pack(1) 则两问的答案分别又是多少啊??Top
47 楼buptjay(刘鑫)回复于 2005-02-26 22:04:28 得分 0
长见识Top
48 楼wyd124(鱼日)回复于 2005-02-26 22:06:12 得分 1
S2 的内存布局我想是: 1******,11**1111,11111111 吧????
不知道对不对 ??Top
49 楼xiaofengxu(锋)回复于 2005-02-26 22:15:33 得分 1
请大虾们写出该题目在
#pragma pack(n), n = 1 2 4 8 16 下的答案以及内存分布图,以供大家参考。。。。。Top
50 楼sandon(厚积薄发)回复于 2005-02-27 00:05:50 得分 0
长见识了Top
51 楼GEATA(学习ing)回复于 2005-02-27 00:51:01 得分 0
MARKTop
52 楼a10002(A万零贰)回复于 2005-02-27 12:08:36 得分 1
蛮不错的!
这也是基础,我以前看过!
一开始还是被这里的人搞得不清了!直到看到正确答案!Top
53 楼Oversense(步步文)回复于 2005-02-28 10:32:11 得分 0
还有新看法没?Top
54 楼kobefly(科比--网络学习中)回复于 2005-02-28 10:38:07 得分 1
redleaves(ID最吊的网友)
我同意
这也是我所想说的
其实这个东西很容易搞混
自己多动手,就会明白拉Top
55 楼yjh1982(血精灵)回复于 2005-02-28 10:46:15 得分 1
可能还要对应到机器吧.比方32位下char最多填到4Top
56 楼redleaves(程序员)回复于 2005-02-28 11:02:00 得分 1
TO yjh1982(血精灵):
你可以试一下
struct S{
long long b;
char a;
};
这个结构是多大.Top
57 楼redleaves(程序员)回复于 2005-02-28 11:03:29 得分 1
补充一下:
上面的结构要加
#pragma pack(8)
struct S{
long long b;
char a;
};
#pragma pack(0)Top
58 楼rocshaw(太阳鸟(抵制日货))回复于 2005-02-28 11:04:45 得分 0
markTop
59 楼zhanghk(lion)回复于 2005-02-28 11:15:42 得分 0
做错一个呵呵学习Top
60 楼andycpp(幻瞳)回复于 2005-02-28 14:02:20 得分 1
redleaves(ID最吊的网友)
说得真是太好啦,终于彻底的理解了这个问题
题目上的 #pragma pack(8) 原来没起什么作用阿,呵呵,这个迷惑条件真是太经典了。Top
61 楼weigoal(荆棘鸟)回复于 2005-02-28 14:41:58 得分 0
不会啊,郁闷Top
62 楼gmmy0727(请多指教)回复于 2005-02-28 14:55:43 得分 0
学习一下Top
63 楼Snow_1980(风吹雪)回复于 2005-02-28 15:06:37 得分 0
终于看懂了~,对redleaves(ID最吊的网友)及楼主表示深深谢意Top
64 楼junnyfeng(风歌)回复于 2005-02-28 15:20:39 得分 1
1。24
2。空了2个字节(short 是两个字节)Top
65 楼xxgcr(西瓜超人)回复于 2005-02-28 16:44:38 得分 1
28
1Top
66 楼xxgcr(西瓜超人)回复于 2005-02-28 16:54:20 得分 1
不好意思,错了,应该是24和7Top
67 楼xxgcr(西瓜超人)回复于 2005-02-28 16:56:26 得分 1
不好意思,打错字了,应该是24和0Top
68 楼sanhill()回复于 2005-02-28 16:58:33 得分 5
sizeof(s2)是24
“题目上的 #pragma pack(8) 原来没起什么作用阿,呵呵,这个迷惑条件真是太经典了。”
错!错!错!
没起作用???如果不是pack 8 的话结果会怎么样?
你没有在实际编程中接触这样的问题吧?
sizeof(s2)在不同的pack下的结果
#pragma pack(1)后结果是 sizeof(char) + sizeof(short) + sizeof(long) + sizeof(long long) = 15
#pragma pack(2)后结果是 2 * sizeof(char) + sizeof(short) + sizeof(long) + sizeof(long long) = 16
#pragma pack(4)后结果是 4 * sizeof(char) + 2 * sizeof(short) + sizeof(long) + sizeof(long long) = 20
#pragma pack(8)和#pragma pack(16)后结果是一样的,都是 24
Top
69 楼xxgcr(西瓜超人)回复于 2005-02-28 17:12:05 得分 5
redleaves(ID最吊的网友)有个地方讲的不对,如下:
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,11**,1111,****11111111
===============
本人认为在s2内部,s1作为一个类型出现,os会把她认为是一个8字节长不可分割的部分,所以本人认为内存分布应该如下:
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,****,11**,1111,11111111
所以答案是24和2Top
70 楼HUDIEGU(神汉)回复于 2005-02-28 17:35:57 得分 1
楼上这么多能人啊,怎么都是高中的状态啊,算术题这么有条理,顶一下Top
71 楼xue23(xue23)回复于 2005-02-28 17:44:38 得分 5
有程序查一下各个变量的内存地址得知:
各个变量在内存中的位置为
c***aa**
bbbb****
dddddddd
测试代码为:
s2 ss;
cout << "ss.c = " << &ss << endl ;
cout << "ss.d.a = " <<&ss.d.a << endl;
cout << "ss.d.b = " <<&(ss.d.b) <<endl ;
cout << "ss.d = " <<&ss.e << endl;
print out 各个变量的内存地址不就可以看出来了吗。
所以答案是24,2.
但是我的想像中应该是这样的分布情况:
c*******
aa**bbbb
dddddddd
不知为什么会c和a放在一起,组成8位长度。Top
72 楼xue23(xue23)回复于 2005-02-28 17:47:59 得分 5
有程序查一下各个变量的内存地址得知:
写错,重写
各个变量在内存中的位置为
c***aa**
bbbb****
eeeeeeee
测试代码为:
s2 ss;
cout << "ss.c = " << &ss << endl ;
cout << "ss.d.a = " <<&ss.d.a << endl;
cout << "ss.d.b = " <<&(ss.d.b) <<endl ;
cout << "ss.e = " <<&ss.e << endl;
print out 各个变量的内存地址不就可以看出来了吗。
所以答案是24,2.
但是我的想像中应该是这样的分布情况:
c*******
aa**bbbb
eeeeeeee
不知为什么会c和a放在一起,组成8位长度。
Top
73 楼linao(一面学C++一面学C#)回复于 2005-02-28 17:50:22 得分 1
s2:
c = 4
sizeof(s1)=8
e = 8
sizeof(s2) = 20
c 占一位,应该是7吧Top
74 楼sanhill()回复于 2005-02-28 17:52:14 得分 1
但是在VC++ 6.00 中,内存中的存放结果就是 redleaves(ID最吊的网友) 讲的,没有错!
各位有兴趣可以在VC++中看一下内存的存放结果就知道了。Top
75 楼xue23(xue23)回复于 2005-02-28 17:55:52 得分 1
补充,我在的机器上,上述各地址如下:
ss.c = 0012FF68
ss.d.a = 0012FF6C
ss.d.b = 0012FF70
ss.e = 0012FF78
所以可以得出结论,在我用的编译器中(vc6).对于复杂结构来说,子结构在结构是平坦分布的。也就是说编译器并不把子结构当作一个整体来分配内存,而是可以拆分开来分配内存的。这样的目的是为了节省内存。
Top
76 楼mengxiangfengwz(小江)回复于 2005-02-28 18:24:49 得分 1
经本人调试(vc++6.0)
原题没有通过
提示 没有类型:long long e
将其改为double
1.sizeof(s2)=24
Top
77 楼redleaves(程序员)回复于 2005-02-28 18:36:12 得分 1
我说的那个规则就是标准中结构对齐的规则,这种规则没有什么可商量的,标准是这样定义的.
xue23(xue23)所说的把复杂成员(如结构)拆开分配的理解是错误的,虽然看上去像是这样.
具体处理方式我上面讲的规则里也有说明的.
Top
78 楼xue23(xue23)回复于 2005-02-28 19:50:21 得分 1
我想请问(redleaves(ID最吊的网友)), c为什么会占4个字节,而不是1或者8个字节呢?Top
79 楼redleaves(程序员)回复于 2005-02-28 21:52:51 得分 1
TO xue23
我在上面有说明啊,你没看么?
c只占1个字节,关键是d,S1中最长的对齐参数为4.因此,在S2中S1就要按4字节对齐.所以成员d要从第4个字节开始布局.这样c后面就会空3个字节.
如果你把S1中的b改成long long,那么,c后面就会空7个字节.
如果你把#pragma pack(8)改成#pragma pack(1),那么c后面就不会有空.
Top
80 楼xue23(xue23)回复于 2005-02-28 23:38:30 得分 1
我还是不敢同意ID最吊的网友兄的观点。在linux下实验此题的结论是什么呢。
我在redhat liux8下实验了一下。
得到结果如下:
sizeof (ss ) = 24
ss.c = 0xffff980
ss.d.a = 0xffff984
ss.d.b = 0xffff988
ss.e = 0xffff98c
可以看出是这样分配内存的。
c***
aa**
bbbb
eeee
eeee
是以4字节对齐。可见内存分配是和编译器有关的。
Top
81 楼RedH(Desen)回复于 2005-03-01 10:35:12 得分 1
24,7
这是针对微软的编译器的,各个平台不同。Top
82 楼RedH(Desen)回复于 2005-03-01 10:39:45 得分 1
补充一点,字节对齐为了优化内存管理,某些cpu的优化,或者是多cpu的协同工作。Top
83 楼redleaves(程序员)回复于 2005-03-01 12:56:44 得分 1
TO xue23(xue23):
我说的规则并不是我的观点,我是照标准说的.这个规则就是为了各各平台兼容才制定的,不会有平台间的差别的.
我试验了
GCC 2.95 3.1 3.3 3.4 4.0
MS C/C++ 7.0 7.1 8.0 beta
Borland C/C++ 5.6 6.0
Intel C/C++ 7.0 8.0 8.1
DigitalMars C/C++ 8.4
OpenWatcom 1.3
Codeplay C/C++ 2.1.7
结果都是一样的,不知道你用的什么编译器.
给出你的代码和编译参数好么?
你说你测试的结果是长度为24,不过你只给出了20个字节的分布.后面还有四个无用的空字节么?
如果有的话,那说明你是按8字节对齐的,可是如果是这样的话,成员e没有对齐到8字节边界上,那你的编译器肯定有问题(没把long long当8字节的对象对待).
如果长度是20的话,说明你是按4字节对齐.所以才会有那种排布.Top
84 楼tudou614(魔蟹座的SATAN)回复于 2005-03-01 12:57:52 得分 0
MARK下先,晚点看Top
85 楼redleaves(程序员)回复于 2005-03-01 12:58:27 得分 1
另外,请用下面的代码在你的平台上测试一下,看看结果:
#include <stdio.h>
#pragma pack(8)
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long long e;
};
#pragma pack()
int main( void ) {
s2 obj;
char * pC = (char *)&obj;
char * pD = (char *)&obj.d;
char * pE = (char *)&obj.e;
printf( "size:%d\n", sizeof(obj) );
for ( int i=0; i<sizeof( obj.c ); i++ ) {
printf( "c" );
}
for( char *p = pC + sizeof( obj.c ); p!= pD; p++ ) {
printf( "*" );
}
for ( int i=0; i<sizeof( obj.d.a ); i++ ) {
printf( "a" );
}
for( char *p = pD + sizeof( obj.d.a ); p!= (char *)&obj.d.b; p++ ) {
printf( "*" );
}
for ( int i=0; i<sizeof( obj.d.b ); i++ ) {
printf( "b" );
}
for( char *p = (char *)&obj.d.b + sizeof( obj.d.b ); p!= (char *)&obj.e; p++ ) {
printf( "*" );
}
for ( int i=0; i<sizeof( obj.e ); i++ ) {
printf( "e" );
}
for( char *p = (char *)&obj.e + sizeof( obj.e ); p!= (char *)&obj + sizeof(obj) ; p++ ) {
printf( "*" );
}
return 0;
}
Top
86 楼utstar(Universal Light)回复于 2005-03-01 13:32:44 得分 1
vmware里的debian linux(kernel 2.6.10)+gcc-3.4.4:
sizeof(s2)=20
Top
87 楼mengxiangfengwz(小江)回复于 2005-03-01 13:38:07 得分 1
不同的c编译器,不一定有相同的答案.
经本人调试(vc++6.0)
原题没有通过
提示 没有类型:long long e
将其改为double
1.sizeof(s2)=24
2.s2中c后面补7个字节
在s2中s1被看做一个8字节的类型.Top
88 楼mengxiangfengwz(小江)回复于 2005-03-01 14:04:41 得分 0
补充:redleaves(ID最吊的网友)说的是对的Top
89 楼saince(搜猫)回复于 2005-03-01 14:33:58 得分 0
MarkTop
90 楼rwxybh(行云)回复于 2005-03-01 15:28:19 得分 0
感谢redleaves(ID最吊的网友)!
学了不少!Top
91 楼xue23(xue23)回复于 2005-03-01 15:39:57 得分 1
对不起,写错了,在linux下 sizeof (ss) = 20. 我对redhat linux8 + g++.Top
92 楼zly1980(zly1980)回复于 2005-03-01 16:19:45 得分 1
我搞不懂讨论这样的问题有什么意义,回答得出的人就牛吗?回答不出的就没用吗?面试的公司为什么要这样的题目呢。Top
93 楼oicqkill(风情主人)回复于 2005-03-01 16:23:53 得分 3
#pragma pack(8)
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long e; // long long e;对的吗?怀疑.....
};
#pragma pack()
问
1.sizeof(s2) = 16
2.s2的s1中的a后面空了几个字节接着是b?Top
94 楼redleaves(程序员)回复于 2005-03-01 19:48:58 得分 1
TO zly1980(zly1980):
结构对齐是基础知识,这种问题只有一个目的,就是看你对语言细节的了解程度.
在网络通讯,多个模块交互的应用中这种东西是很常见.
这一类的东西还有像__stdcall,__cdecl,volatile,mutable这些东西.平常学习中很难遇到,但实际工作中却会用.Top
95 楼xue23(xue23)回复于 2005-03-01 23:16:06 得分 2
同意楼上的兄弟看法。这些东西又有多少可以随口说出呢?
__stdcall, __cdecl参数传入的顺序从右到左,不同是前者修改的函数的参数stack从被调用者清除,而后者由调用者清除。所以后者编译出来的二进制代码比较前者大。
volatile 定义的变量防止被编译器优化掉。
mutable定义的变量一般都非静态或者非常量类成员。它允许常量类成员对其赋值。
这些东西最基本,但往住不是初学者在短时间能够理解的。Top
96 楼fanhuixing(小白痴)回复于 2005-03-01 23:55:20 得分 1
1。24
2。空了2个字节(short 是两个字节)Top
97 楼buptrobin(听风)回复于 2005-03-02 11:26:14 得分 2
在linux下是这样的,gcc, 同样还有solaris2.8,
size:20
c***aa**bbbbeeeeeeee
不过aix5, hp11.11的话呢,是
size:24
c***aa**bbbb****eeeeeeee
tru64:
size:32
c*******aa******bbbbbbbbeeeeeeee
看来写面试题的时候,得说明什么平台,多少位的,hoho,否则.......Top
98 楼lzxjxsy(小眼睛)回复于 2005-03-02 11:30:53 得分 0
你在什么公司啊?
Top
99 楼Oversense(步步文)回复于 2005-03-02 12:54:33 得分 0
to buptrobin(听风)
你是不是把#pragma pack(8)去掉了编译的?
redleaves测试的可比你多哟Top
100 楼buptrobin(听风)回复于 2005-03-02 12:59:15 得分 2
我没有去掉#pragma pack(8),
就是用的他的程序.
这个问题应该是平台相关的.
Top
101 楼zhousqy(标准C匪徒)(甩拉,甩拉)回复于 2005-03-02 15:43:52 得分 0
高啊。Top
102 楼huangyang88(中国-必胜)回复于 2005-03-02 16:19:20 得分 2
sizeof(long long) = 8
sizeof(struct s2) = 20
0xbffff110 0xbffff114 0xbffff11c
gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)Top
103 楼huangyang88(中国-必胜)回复于 2005-03-02 16:21:38 得分 5
源代码如下:
#include <stdio.h>
#pragma pack(8)
struct s1{
short a;
long b;
};
struct s2{
char c;
struct s1 d;
long long e;
};
#pragma pack()
int main()
{
struct s2 ss;
printf("sizeof(long long) = %d\n", sizeof(long long));
printf("sizeof(struct s2) = %d\n", sizeof(struct s2));
printf("%p %p %p\n", &(ss.c), &(ss.d), &(ss.e));
return 0;
}
Top
104 楼apemancsdn(梦中是英雄)回复于 2005-03-02 16:29:42 得分 1
24, 7
如果想知道内存的结构看反汇编是最清楚的!
另外如果看不懂汇编,这里提供一个简单方法知道某个变量相对于结构体起始的地址
#define GetOffset(type, x) &(((type*)0)->x)
注:我的平台是WinXP + VC6.0Top
105 楼kwaon(蜗牛)回复于 2005-03-02 19:18:43 得分 0
真的学到了不少东西啊!!
谢谢你们了!
Top
106 楼xjtuzhw(飞影(★和谐社会,狗才谈政治★))回复于 2005-03-02 19:38:58 得分 0
好题目,越基础越重要Top
107 楼Mdeathys(junhuo)回复于 2005-03-02 20:54:28 得分 0
好文章,支持多贴些这样的文章Top
108 楼baqiao1211(一船明月一帆风)回复于 2005-03-02 21:50:25 得分 2
请大虾们写出该题目在
#pragma pack(n), n = 1 2 4 8 16 下的答案以及内存分布图,以供大家参考。。。。。
————————————————————————
n=1:15 0
n=2:16 1
n=4:20 3
n=8=16:24 3
(VC6+Intel CPU+Window 2K PRO)Top
109 楼JonSlive(天佑)回复于 2005-03-02 22:10:36 得分 2
是一个字节对齐问题。
前段时间我们项目组的一位对C++有研究的人专门讲过此问题。
在结构体s1内。
struct s1{
short a; //2字节
long b; //4字节。
};
但如果是这种:
struct s1{
long b; //4字节。
short a; //4字节 因为要进行对齐,和前面所占的存储空间要求一致
};
在S2中:
struct s2{
char c; // 8字节
s1 d; //8字节
{
short a; //4字节
long b; //4字节
}
long long e;//8字节
};
从这里就可以直接看出,在S2中,由于考虑字节对齐问题
那么,在a后面就应该还有2个字节,作为填充S2最后2个字节对齐的空间。Top
110 楼redleaves(程序员)回复于 2005-03-02 22:28:56 得分 1
TO buptrobin(听风):
并不是所有编译器都支持#pragma pack(n)这种语法,这并不是标准,#pragma这个预编译宏是由编译器厂商自己定义的
我写#pragma pack(8)只是强调我用的8字节对齐.不用平台/编译器的默认对齐方式不一样,如果你在编译器的选项中把对齐设为8字节,结果就是一样的了.Top
111 楼redleaves(程序员)回复于 2005-03-02 23:09:38 得分 1
TO buptrobin(听风):
还有,你在tru64平台中不知道用的什么编译器.它对标准的支持是有问题的.
平常,我们在程序中为了避免平台的差异,尽量使用long而不使用int(这也是这里为什么写long而不写int的原因)
因为在C89,90,99,C++98的标准中,int的长度是会随平台不同而变化的,long的长度却始终是固定的32位.
而你的编译器把long也变成了64位,结果肯定是不同的.Top
112 楼micemice1()回复于 2005-03-02 23:59:09 得分 0
强贴!UP~~~!Top
113 楼fireredfox(火狐狸)回复于 2005-03-03 09:07:08 得分 0
今天长了知识了。Top
114 楼xunfengxxx(寻风)回复于 2005-03-03 09:12:22 得分 0
可惜以后我最最熟悉的C++_再也不用了~Top
115 楼immc30(immc)回复于 2005-03-03 09:20:51 得分 0
感谢楼主和redleaves(ID最吊的网友)!Top
116 楼steedhorse(晨星)回复于 2005-03-03 09:35:51 得分 0
楼主揭帖吧。Top
117 楼ljhwht(有点郁闷)回复于 2005-03-03 11:26:06 得分 2
redhat linux 7.2
我的程序:
结果:
len(s1)=8
len(s2)=20
&s2.c=bffffa00,sizeof(c)=1
&s2.d=bffffa04,sizeof(d)=8
&s2.d.a=bffffa04,sizeof(a)=2
&s2.d.b=bffffa08,sizeof(b)=4
&s2.e=bffffa0c,sizeof(e)=8
ID最吊兄的程序结果:
size:20
c***aa**bbbbeeeeeeeeTop
118 楼ljhwht(有点郁闷)回复于 2005-03-03 11:28:18 得分 0
强烈同意 听风 兄!Top
119 楼utstar(Universal Light)回复于 2005-03-03 13:14:35 得分 1
因为在C89,90,99,C++98的标准中,int的长度是会随平台不同而变化的,long的长度却始终是固定的32位.
----------------
int 在32位平台和64位平台都是32位的,long在64位平台是64位的,推荐使用longTop
120 楼redleaves(程序员)回复于 2005-03-03 18:13:25 得分 84
To 楼上:
多数编译器在64位平台下,的确int是32位,long是64位.
不过根据我查看标准文档,文档里说只有"plain int"即"int"类型是随平台变化的,其它的整数类型都是定长的.
至于编译器为什么这么做,我就不得而知了.但如果64位台下long是64位,那C99中加入的long long类型可以说是多此一举了....Top
121 楼utstar(Universal Light)回复于 2005-03-05 12:13:43 得分 0
肯定是你理解错了。int 随平台变化没错,但是,那是指从16位到32位,而不是针对将来的64位。我在ia64,ibm,hp的64位平台都作过测试。一般64位平台遵守LP64模型,即long和pointer类型是64位的,其他类型长度一般与原来的32位平台相同
你说"如果64位台下long是64位,那C99中加入的long long类型可以说是多此一举了...."
我是不是也可以说"如果64位台下 int 是64位,那C99中加入的long long类型可以说是多此一举了...."
其实不能说它多此一举,至少在32位平台有用处,毕竟现在32位是主流。而且将来64位不能满足需要时,将long long扩展成128位也是可行的Top
122 楼bzwm(不走完美)回复于 2005-03-15 15:42:08 得分 0
redleaves(ID最吊的网友) 谢谢你,明白了不少!Top



