5-8万年薪顶级嵌入式,京沪深就业地 浅谈并行编程中的任务分解模式
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

Intel和微软和本公司同时出现的面试题

楼主Oversense(步步文)2005-02-24 17:10:39 在 C/C++ / C++ 语言 提问

#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

相关问题

  • 微软面试题!
  • 微软面试题
  • 微软面试题,Sql
  • 一道微软面试题
  • 微软面试题之二
  • 微软面试题目(一)
  • 微软面试题目(二)
  • 微软面试题目(三)
  • 微软的面试题目?
  • 微软面试考题

关键词

  • 64位
  • c++
  • 编译器
  • 平台
  • 内存
  • 结构
  • vc
  • bffffa
  • pragma pack
  • long

得分解答快速导航

  • 帖主:Oversense
  • Varg
  • Varg
  • wwwllg
  • fisker0303
  • wwwllg
  • laowang456
  • wenddy112
  • alec626
  • kobefly
  • goodluckyxl
  • kobefly
  • eric_shenzhen
  • yrhkxg
  • ybt631
  • w7x
  • tongdegang2005
  • FePwaw
  • waterinsunny
  • Augustus
  • redchina
  • redchina
  • zhengwei1984222
  • zhengwei1984222
  • shishulv
  • Jackallen
  • rwxybh
  • cat_dog
  • redleaves
  • dongpy
  • redleaves
  • yangfasheng
  • wyd124
  • xiaofengxu
  • a10002
  • kobefly
  • yjh1982
  • redleaves
  • redleaves
  • andycpp
  • junnyfeng
  • xxgcr
  • xxgcr
  • xxgcr
  • sanhill
  • xxgcr
  • HUDIEGU
  • xue23
  • xue23
  • linao
  • sanhill
  • xue23
  • mengxiangfengwz
  • redleaves
  • xue23
  • redleaves
  • xue23
  • RedH
  • RedH
  • redleaves
  • redleaves
  • utstar
  • mengxiangfengwz
  • xue23
  • zly1980
  • oicqkill
  • redleaves
  • xue23
  • fanhuixing
  • buptrobin
  • buptrobin
  • huangyang88
  • huangyang88
  • apemancsdn
  • baqiao1211
  • JonSlive
  • redleaves
  • redleaves
  • ljhwht
  • utstar
  • redleaves

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
x 提问