CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

最近笔试面试,狂考sizeof ,大家一起学习

楼主bigbigwind8()2006-03-07 09:00:19 在 C/C++ / C++ 语言 提问

解析C语言中的sizeof    
   
  一、sizeof的概念     
    sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。     
   
  二、sizeof的使用方法     
    1、用于数据类型     
   
    sizeof使用形式:sizeof(type)     
   
    数据类型必须用括号括住。如sizeof(int)。     
   
    2、用于变量     
   
    sizeof使用形式:sizeof(var_name)或sizeof var_name     
   
    变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。     
   
    注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。     
   
    如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。     
   
  三、sizeof的结果     
    sizeof操作符的结果类型是size_t,它在头文件    
   
  中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。     
   
    1、若操作数具有类型char、unsigned char或signed char,其结果等于1。     
   
    ANSI C正式规定字符类型为1字节。     
   
    2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、float、double、long double类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。     
   
    3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。     
   
    4、当操作数具有数组类型时,其结果是数组的总字节数。     
   
    5、联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。     
   
    让我们看如下结构:     
   
    struct {char b; double x;} a;     
   
    在某些机器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。     
   
    这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。     
   
    6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。     
   
  四、sizeof与其他操作符的关系     
    sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。如i*sizeof(int);其中i为int类型变量。     
   
  五、sizeof的主要用途     
    1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:     
   
    void *malloc(size_t size),     
   
    size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。     
   
    2、sizeof的另一个的主要用途是计算数组中元素的个数。例如:     
   
    void * memset(void * s,int c,sizeof(s))。     
   
  六、建议     
    由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。 问题点数:10、回复次数:207Top

1 楼bigbigwind8()回复于 2006-03-07 09:01:46 得分 0

本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主要用法。    
   
  1、   sizeof应用在结构上的情况    
   
  请看下面的结构:    
   
  struct   MyStruct    
   
  {    
   
  double   dda1;    
   
  char   dda;    
   
  int   type    
   
  };    
   
  对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求:    
   
  sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13    
   
  但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗?    
   
  其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。    
   
  类型    
  对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)    
   
  Char    
  偏移量必须为sizeof(char)即1的倍数    
   
  int    
  偏移量必须为sizeof(int)即4的倍数    
   
  float    
  偏移量必须为sizeof(float)即4的倍数    
   
  double    
  偏移量必须为sizeof(double)即8的倍数    
   
  Short    
  偏移量必须为sizeof(short)即2的倍数    
   
   
   
  各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。    
   
  下面用前面的例子来说明VC到底怎么样来存放结构的。    
   
  struct   MyStruct    
   
  {    
   
  double   dda1;    
   
  char   dda;    
   
  int   type    
   
  };    
   
  为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为:sizeof(MyStruct)=8+1+3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。    
   
  下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况:    
   
  struct   MyStruct    
   
  {    
   
  char   dda;    
   
  double   dda1;    
   
  int   type    
   
  };    
   
  这个结构占用的空间为多大呢?在VC6.0环境下,可以得到sizeof(MyStruc)为24。结合上面提到的分配空间的一些原则,分析下VC怎么样为上面的结构分配空间的。(简单说明)    
   
  struct   MyStruct    
   
  {    
   
  char   dda;//偏移量为0,满足对齐方式,dda占用1个字节;    
   
  double   dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8    
   
  //的倍数,需要补足7个字节才能使偏移量变为8(满足对齐    
   
  //方式),因此VC自动填充7个字节,dda1存放在偏移量为8    
   
  //的地址上,它占用8个字节。    
   
  int   type;//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍    
   
  //数,满足int的对齐方式,所以不需要VC自动填充,type存    
   
  //放在偏移量为16的地址上,它占用4个字节。    
   
  };//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构    
   
  //的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof    
   
  //(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为    
   
  //sizeof(double)=8的倍数。    
   
   
   
  所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。    
   
   
   
  VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。    
   
  VC中提供了#pragma   pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;    
   
  否则必须为n的倍数。下面举例说明其用法。    
   
  #pragma   pack(push)   //保存对齐状态    
   
  #pragma   pack(4)//设定为4字节对齐    
   
  struct   test    
   
  {    
   
  char   m1;    
   
  double   m4;    
   
  int   m3;    
   
  };    
   
  #pragma   pack(pop)//恢复对齐状态    
   
  以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma   pack(4)改为#pragma   pack(16),那么我们可以得到结构的大小为24。(请读者自己分析)    
   
  2、   sizeof用法总结    
   
  在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对sizeof的用法做个总结。    
   
  A.   参数为数据类型或者为一般变量。例如sizeof(int),sizeof(long)等等。这种情况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2个字节,在32位系统中占4个字节。    
   
  B.   参数为数组或指针。下面举例说明.    
   
  int   a[50];   //sizeof(a)=4*50=200;   求数组所占的空间大小    
   
  int   *a=new   int[50];//   sizeof(a)=4;   a为一个指针,sizeof(a)是求指针    
   
  //的大小,在32位系统中,当然是占4个字节。    
   
  C.   参数为结构或类。Sizeof应用在类和结构的处理情况是相同的。但有两点需要注意,第一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关。    
   
  第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一    
   
  个实例在内存中都有唯一的地址。    
   
  下面举例说明,    
   
  Class   Test{int   a;static   double   c};//sizeof(Test)=4.    
   
  Test   *s;//sizeof(s)=4,s为一个指针。    
   
  Class   test1{   };//sizeof(test1)=1;    
   
  D.   参数为其他。下面举例说明。    
   
  int   func(char   s[5]);    
   
  {    
   
  cout<    
  //数的参数在传递的时候系统处理为一个指针,所    
   
  //以sizeof(s)实际上为求指针的大小。    
   
  return   1;    
   
  }    
   
  sizeof(func(“1234”))=4//因为func的返回类型为int,所以相当于    
   
  //求sizeof(int).    
   
   
   
  以上为sizeof的基本用法,在实际的使用中要注意分析VC的分配变量的分配策略,这样的话可以避免一些错误。    
   
  Top

2 楼windking21(想玩玩WOW 真的那么难吗)回复于 2006-03-07 09:03:14 得分 0

挺细致得Top

3 楼lbing7(向青润老大学习!!!)回复于 2006-03-07 09:27:40 得分 10

怎么样都得跟楼主学学  
  Top

4 楼Could(翻墙鹦鹉)回复于 2006-03-07 10:29:42 得分 0

very   good,  
  thank   youTop

5 楼syd1207(既然选择远方,便只顾风雨兼程。。。)回复于 2006-03-07 10:56:50 得分 0

study!~Top

6 楼ouyh12345(五岭散人)回复于 2006-03-07 12:11:42 得分 0

写得挺好的,收藏了Top

7 楼infidel(Leo.C)回复于 2006-03-07 12:23:48 得分 0

markTop

8 楼wang0303101(蓝色幻想)回复于 2006-03-07 12:29:06 得分 0

谢谢楼主了,写的很详细,辛苦了!Top

9 楼phaetonbl(凳子)回复于 2006-03-07 12:49:00 得分 0

很全面Top

10 楼Rick_ang(东方未名)回复于 2006-03-07 13:00:24 得分 0

好..学习了Top

11 楼paituo(拍拖)回复于 2006-03-07 13:01:44 得分 0

收藏。Top

12 楼deutsch(人民)回复于 2006-03-07 13:11:17 得分 0

楼主说的比较的详细了,不过主体是c的运作,c++可能还有不同的  
  如抽象类继承等,而且sizeof的实现还和编译器有一定的关系,在vc和gcc编译的就有可能得到不同的结果。  
  我认为深入探索c++对象模型那本书分析的比较全面了Top

13 楼sk_fault(晨光一线)回复于 2006-03-07 13:11:54 得分 0

真的值得好好学习!!!Top

14 楼yangyzqo(欺世盗名来灌水)回复于 2006-03-07 13:59:09 得分 0

留名学习Top

15 楼yuanyou(元友)回复于 2006-03-07 14:02:09 得分 0

好啊!Top

16 楼ugg(逸学堂(exuetang.net))回复于 2006-03-07 14:27:10 得分 0

lz文章不错,exuetang.net引用一下  
  网址如下  
  http://www.exuetang.net/article/NewsViewAdmin.aspx?NewsID=197  
   
  如果lz认为侵占你版权,请告知,我会在第一时间删除.Top

17 楼linux_wince(自由的飞)回复于 2006-03-07 14:28:43 得分 0

好好学习!Top

18 楼ximig(xiao)回复于 2006-03-07 14:40:57 得分 0

好!!!  
  谢谢搂主~~~!  
   
  收藏~~~~~~~~~~Top

19 楼advancedchan(try)回复于 2006-03-07 14:52:34 得分 0

THXTop

20 楼afeu007(梦里开宝马)回复于 2006-03-07 15:00:57 得分 0

收藏......  
  Top

21 楼wanyong775(渔民:小小的网少年)回复于 2006-03-07 16:25:35 得分 0

markTop

22 楼citywanderer2005(流浪狗)回复于 2006-03-07 16:30:12 得分 0

markTop

23 楼popoxx(我笑)回复于 2006-03-08 08:12:36 得分 0

收藏,感谢楼主Top

24 楼siteer0344()回复于 2006-03-08 08:39:07 得分 0

www.source520.com           免费免注册80G源码书籍下载Top

25 楼cgspwei()回复于 2006-03-08 09:05:44 得分 0

写的细致,收藏Top

26 楼cg5353(努力学习中)回复于 2006-03-08 09:23:38 得分 0

原创的吗,写的不错Top

27 楼hawk21c(跨越高山)回复于 2006-03-08 10:02:08 得分 0

挺好的   感谢楼主!Top

28 楼hansin(将冰山劈开)回复于 2006-03-08 10:04:14 得分 0

upTop

29 楼hflin(小枫)回复于 2006-03-08 10:22:48 得分 0

学习Top

30 楼tiemuzh777(初始化)回复于 2006-03-08 10:32:56 得分 0

以前看过,但是还是觉得需要不断学习!认真学习,仔细研究!  
  收藏了。Top

31 楼abillchen(依然)回复于 2006-03-08 10:43:35 得分 0

很好,学习了Top

32 楼yleiou(单刀匹马)回复于 2006-03-08 11:00:23 得分 0

学习Top

33 楼jq_lbx(jqlbx)回复于 2006-03-08 11:01:42 得分 0

好好好Top

34 楼csu_yzb(白杨)回复于 2006-03-08 11:07:18 得分 0

受益匪浅Top

35 楼Darkay_Lee()回复于 2006-03-08 11:26:54 得分 0

我认为理解sizeof的关键就是sizeof的值是在编译期间有编译器计算的,所以,编译时候编译器所能看到的类型的值就是sizeof的值。Top

36 楼ChenSu2008(北海沉书)回复于 2006-03-08 12:57:57 得分 0

学习。  
  长见识。  
  Top

37 楼shrinerain(圣影雨)回复于 2006-03-08 13:12:05 得分 0

不错~~Top

38 楼bbbbcccc()回复于 2006-03-08 14:08:02 得分 0

http://valenhua.go3.icpcn.com/Top

39 楼csShooter(Sharp Shooter)回复于 2006-03-08 15:15:23 得分 0

mark  
  Top

40 楼freebendy(風→繼續吹)回复于 2006-03-08 15:21:16 得分 0

#include   "stdafx.h"  
  using   namespace   std;  
  #pragma   pack(push)//保存对齐状态  
  #pragma   (4)  
   
   
  struct   test  
  {  
  char   m1;  
  double   m4;  
  int   m3;  
  };  
   
  int   _tmain(int   argc,   _TCHAR*   argv[])  
  {        
  size_t   size;  
  size=sizeof(test);  
  cout<<size<<endl;  
  system("pause");  
  return   0;  
  }  
  怎么我在vc.net和devcpp上运行都是24?  
  Top

41 楼microfans(不要输给自己说的话!)回复于 2006-03-08 15:24:57 得分 0

拷我手机里了,好好研究一下1Top

42 楼Randomize()回复于 2006-03-08 15:52:50 得分 0

樓主和我面的公司差不多形式的考題,無奈鄙人相當於C盲.今一見矛色頓開.Top

43 楼alexanderxyh(喜欢字母C)回复于 2006-03-08 17:00:43 得分 0

不错的帖子Top

44 楼qianjinrail(呵呵)回复于 2006-03-08 17:50:37 得分 0

mark  
  Top

45 楼adintr(www.adintr.com)(风流总被雨打风吹去)回复于 2006-03-08 17:53:50 得分 0

搞不懂现在的公司为什么这么喜欢考   sizeofTop

46 楼duanhuicen(sanlang)回复于 2006-03-08 17:59:11 得分 0

向无私奉献的人致敬!Top

47 楼luckdog01(luckdog)回复于 2006-03-08 18:03:43 得分 0

好贴   收藏了Top

48 楼xyunsh(学海无涯,回头是岸)回复于 2006-03-08 18:24:33 得分 0

markTop

49 楼mozhu916(蓝是那么的天,白是那么的云)回复于 2006-03-08 18:25:36 得分 0

标记一下Top

50 楼fiftymetre(50米深蓝)回复于 2006-03-08 19:52:06 得分 0

sizeof详解  
   
  1、什么是sizeof  
   
          首先看一下sizeof在msdn上的定义:  
   
          The   sizeof   keyword   gives   the   amount   of   storage,   in   bytes,   associated   with   a   variable   or   a   type   (including   aggregate   types).   This   keyword   returns   a   value   of   type   size_t.  
   
          看到return这个字眼,是不是想到了函数?错了,sizeof不是一个函数,你见过给一个函数传参数,而不加括号的吗?sizeof可以,所以sizeof不是函数。网上有人说sizeof是一元操作符,但是我并不这么认为,因为sizeof更像一个特殊的宏,它是在编译阶段求值的。举个例子:  
   
  cout<<sizeof(int)<<endl;   //   32位机上int长度为4  
  cout<<sizeof(1==2)<<endl;   //   ==   操作符返回bool类型,相当于   cout<<sizeof(bool)<<endl;  
   
          在编译阶段已经被翻译为:  
   
  cout<<4<<endl;  
  cout<<1<<endl;  
   
          这里有个陷阱,看下面的程序:  
   
  int   a   =   0;  
  cout<<sizeof(a=3)<<endl;  
  cout<<a<<endl;  
   
          输出为什么是4,0而不是期望中的4,3???就在于sizeof在编译阶段处理的特性。由于sizeof不能被编译成机器码,所以sizeof作用范围内,也就是()里面的内容也不能被编译,而是被替换成类型。=操作符返回左操作数的类型,所以a=3相当于int,而代码也被替换为:  
   
  int   a   =   0;  
  cout<<4<<endl;  
  cout<<a<<endl;  
   
          所以,sizeof是不可能支持链式表达式的,这也是和一元操作符不一样的地方。  
   
          结论:不要把sizeof当成函数,也不要看作一元操作符,把他当成一个特殊的编译预处理。  
   
  2、sizeof的用法  
   
          sizeof有两种用法:  
       
          (1)sizeof(object)  
          也就是对对象使用sizeof,也可以写成sizeof   object   的形式。例如:  
   
          (2)sizeof(typename)  
          也就是对类型使用sizeof,注意这种情况下写成sizeof   typename是非法的。下面举几个例子说明一下:  
   
   
  int   i   =   2;  
  cout<<sizeof(i)<<endl;   //   sizeof(object)的用法,合理  
  cout<<sizeof   i<<endl;   //   sizeof   object的用法,合理  
  cout<<sizeof   2<<endl;   //   2被解析成int类型的object,   sizeof   object的用法,合理  
  cout<<sizeof(2)<<endl;   //   2被解析成int类型的object,   sizeof(object)的用法,合理  
  cout<<sizeof(int)<<endl;//   sizeof(typename)的用法,合理  
  cout<<sizeof   int<<endl;   //   错误!对于操作符,一定要加()  
   
          可以看出,加()是永远正确的选择。  
   
          结论:不论sizeof要对谁取值,最好都加上()。  
   
   
  3、数据类型的sizeof  
   
  (1)C++固有数据类型  
   
          32位C++中的基本数据类型,也就char,short   int(short),int,long   int(long),float,double,   long   double  
  大小分别是:1,2,4,4,4,8,   10。  
   
          考虑下面的代码:  
   
  cout<<sizeof(unsigned   int)   ==   sizeof(int)<<endl;   //   相等,输出   1  
   
          unsigned影响的只是最高位bit的意义,数据长度不会被改变的。  
   
          结论:unsigned不能影响sizeof的取值。  
   
  (2)自定义数据类型  
   
          typedef可以用来定义C++自定义类型。考虑下面的问题:  
   
  typedef   short   WORD;  
  typedef   long   DWORD;  
  cout<<(sizeof(short)   ==   sizeof(WORD))<<endl;   //   相等,输出1  
  cout<<(sizeof(long)   ==   sizeof(DWORD))<<endl;   //   相等,输出1  
   
          结论:自定义类型的sizeof取值等同于它的类型原形。  
   
  (3)函数类型  
   
          考虑下面的问题:  
   
  int   f1(){return   0;};  
  double   f2(){return   0.0;}  
  void   f3(){}  
   
  cout<<sizeof(f1())<<endl;   //   f1()返回值为int,因此被认为是int  
  cout<<sizeof(f2())<<endl;   //   f2()返回值为double,因此被认为是double  
  cout<<sizeof(f3())<<endl;   //   错误!无法对void类型使用sizeof  
  cout<<sizeof(f1)<<endl;     //   错误!无法对函数指针使用sizeof        
  cout<<sizeof*f2<<endl;     //   *f2,和f2()等价,因为可以看作object,所以括号不是必要的。被认为是double  
   
          结论:对函数使用sizeof,在编译阶段会被函数返回值的类型取代,  
   
  4、指针问题  
   
          考虑下面问题:  
   
  cout<<sizeof(string*)<<endl;   //   4  
  cout<<sizeof(int*)<<endl;   //   4  
  cout<<sizof(char****)<<endl;   //   4  
   
          可以看到,不管是什么类型的指针,大小都是4的,因为指针就是32位的物理地址。  
   
          结论:只要是指针,大小就是4。(64位机上要变成8也不一定)。  
   
          顺便唧唧歪歪几句,C++中的指针表示实际内存的地址。和C不一样的是,C++中取消了模式之分,也就是不再有small,middle,big,取而代之的是统一的flat。flat模式采用32位实地址寻址,而不再是c中的   segment:offset模式。举个例子,假如有一个指向地址   f000:8888的指针,如果是C类型则是8888(16位,   只存储位移,省略段),far类型的C指针是f0008888(32位,高位保留段地址,地位保留位移),C++类型的指针是f8888(32位,相当于段地址*16   +   位移,但寻址范围要更大)。  
   
  5、数组问题  
   
          考虑下面问题:  
   
  char   a[]   =   "abcdef";  
  int   b[20]   =   {3,   4};  
  char   c[2][3]   =   {"aa",   "bb"};  
   
   
  cout<<sizeof(a)<<endl;   //   7  
  cout<<sizeof(b)<<endl;   //   20  
  cout<<sizeof(c)<<endl;   //   6  
   
   
          数组a的大小在定义时未指定,编译时给它分配的空间是按照初始化的值确定的,也就是7。c是多维数组,占用的空间大小是各维数的乘积,也就是6。可以看出,数组的大小就是他在编译时被分配的空间,也就是各维数的乘积*数组元素的大小。  
   
          结论:数组的大小是各维数的乘积*数组元素的大小。  
   
          这里有一个陷阱:  
   
  int   *d   =   new   int[10];  
   
  cout<<sizeof(d)<<endl;   //   4  
   
          d是我们常说的动态数组,但是他实质上还是一个指针,所以sizeof(d)的值是4。  
   
          再考虑下面的问题:  
   
  double*   (*a)[3][6];  
   
  cout<<sizeof(a)<<endl;     //   4  
  cout<<sizeof(*a)<<endl;     //   72  
  cout<<sizeof(**a)<<endl;   //   24  
  cout<<sizeof(***a)<<endl;   //   4  
  cout<<sizeof(****a)<<endl;   //   8  
   
          a是一个很奇怪的定义,他表示一个指向   double*[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。  
   
          既然a是执行double*[3][6]类型的指针,*a就表示一个double*[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。同样的,**a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof(double*)=24。***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。至于****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。  
   
   
   
  Top

51 楼fiftymetre(50米深蓝)回复于 2006-03-08 19:52:24 得分 0

6、向函数传递数组的问题。  
   
          考虑下面的问题:  
  #include   <iostream>  
  using   namespace   std;  
   
  int   Sum(int   i[])  
  {  
  int   sumofi   =   0;  
  for   (int   j   =   0;   j   <   sizeof(i)/sizeof(int);   j++)   //实际上,sizeof(i)   =   4  
  {  
      sumofi   +=   i[j];  
  }  
  return   sumofi;  
  }  
   
  int   main()  
  {  
  int   allAges[6]   =   {21,   22,   22,   19,   34,   12};  
  cout<<Sum(allAges)<<endl;  
  system("pause");  
  return   0;  
  }  
   
          Sum的本意是用sizeof得到数组的大小,然后求和。但是实际上,传入自函数Sum的,只是一个int   类型的指针,所以sizeof(i)=4,而不是24,所以会产生错误的结果。解决这个问题的方法使是用指针或者引用。  
   
          使用指针的情况:  
  int   Sum(int   (*i)[6])  
  {  
  int   sumofi   =   0;  
  for   (int   j   =   0;   j   <   sizeof(*i)/sizeof(int);   j++)   //sizeof(*i)   =   24  
  {  
      sumofi   +=   (*i)[j];  
  }  
  return   sumofi;  
  }  
   
  int   main()  
  {  
  int   allAges[]   =   {21,   22,   22,   19,   34,   12};  
  cout<<Sum(&allAges)<<endl;  
  system("pause");  
  return   0;  
  }  
          在这个Sum里,i是一个指向i[6]类型的指针,注意,这里不能用int   Sum(int   (*i)[])声明函数,而是必须指明要传入的数组的大小,不然sizeof(*i)无法计算。但是在这种情况下,再通过sizeof来计算数组大小已经没有意义了,因为此时大小是指定为6的。  
  使用引用的情况和指针相似:  
   
  int   Sum(int   (&i)[6])  
  {  
  int   sumofi   =   0;  
  for   (int   j   =   0;   j   <   sizeof(i)/sizeof(int);   j++)  
  {  
      sumofi   +=   i[j];  
  }  
  return   sumofi;  
  }  
   
  int   main()  
  {  
  int   allAges[]   =   {21,   22,   22,   19,   34,   12};  
  cout<<Sum(allAges)<<endl;  
  system("pause");  
  return   0;  
  }  
          这种情况下sizeof的计算同样无意义,所以用数组做参数,而且需要遍历的时候,函数应该有一个参数来说明数组的大小,而数组的大小在数组定义的作用域内通过sizeof求值。因此上面的函数正确形式应该是:  
  #include   <iostream>  
  using   namespace   std;  
   
  int   Sum(int   *i,   unsigned   int   n)  
  {  
  int   sumofi   =   0;  
  for   (int   j   =   0;   j   <   n;   j++)  
  {  
      sumofi   +=   i[j];  
  }  
  return   sumofi;  
  }  
   
  int   main()  
  {  
  int   allAges[]   =   {21,   22,   22,   19,   34,   12};  
  cout<<Sum(i,   sizeof(allAges)/sizeof(int))<<endl;  
  system("pause");  
  return   0;  
  }  
   
  7、字符串的sizeof和strlen  
   
          考虑下面的问题:  
   
  char   a[]   =   "abcdef";  
  char   b[20]   =   "abcdef";  
  string   s   =   "abcdef";  
   
  cout<<strlen(a)<<endl;     //   6,字符串长度  
  cout<<sizeof(a)<<endl;     //   7,字符串容量  
  cout<<strlen(b)<<endl;     //   6,字符串长度  
  cout<<strlen(b)<<endl;     //   20,字符串容量  
  cout<<sizeof(s)<<endl;     //   12,   这里不代表字符串的长度,而是string类的大小  
  cout<<strlen(s)<<endl;     //   错误!s不是一个字符指针。  
   
  a[1]   =   '\0';  
  cout<<strlen(a)<<endl;     //   1  
  cout<<sizeof(a)<<endl;     //   7,sizeof是恒定的  
   
   
          strlen是寻找从指定地址开始,到出现的第一个0之间的字符个数,他是在运行阶段执行的,而sizeof是得到数据的大小,在这里是得到字符串的容量。所以对同一个对象而言,sizeof的值是恒定的。string是C++类型的字符串,他是一个类,所以sizeof(s)表示的并不是字符串的长度,而是类string的大小。strlen(s)根本就是错误的,因为strlen的参数是一个字符指针,如果想用strlen得到s字符串的长度,应该使用sizeof(s.c_str()),因为string的成员函数c_str()返回的是字符串的首地址。实际上,string类提供了自己的成员函数来得到字符串的容量和长度,分别是Capacity()和Length()。string封装了常用了字符串操作,所以在C++开发过程中,最好使用string代替C类型的字符串。  
   
   
  8、从union的sizeof问题看cpu的对界  
   
          考虑下面问题:(默认对齐方式)  
   
  union   u  
  {  
      double   a;  
      int   b;  
  };  
   
  union   u2  
  {  
      char   a[13];  
      int   b;  
  };  
   
  union   u3  
  {  
      char   a[13];  
      char   b;  
  };  
   
  cout<<sizeof(u)<<endl;     //   8  
  cout<<sizeof(u2)<<endl;     //   16  
  cout<<sizeof(u3)<<endl;     //   13  
   
          都知道union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。所以对于u来说,大小就是最大的double类型成员a了,所以sizeof(u)=sizeof(double)=8。但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而u2是16呢?关键在于u2中的成员int   b。由于int类型成员的存在,使u2的对齐方式变成4,也就是说,u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的对界)。  
   
          结论:复合数据类型,如union,struct,class的对齐方式为成员中对齐方式最大的成员的对齐方式。  
   
          顺便提一下CPU对界问题,32的C++采用8位对界来提高运行速度,所以编译器会尽量把数据放在它的对界上以提高内存命中率。对界是可以更改的,使用#pragma   pack(x)宏可以改变编译器的对界方式,默认是8。C++固有类型的对界取编译器对界方式与自身大小中较小的一个。例如,指定编译器按2对界,int类型的大小是4,则int的对界为2和4中较小的2。在默认的对界方式下,因为几乎所有的数据类型都不大于默认的对界方式8(除了long   double),所以所有的固有类型的对界方式可以认为就是类型自身的大小。更改一下上面的程序:  
   
  #pragma   pack(2)  
  union   u2  
  {  
      char   a[13];  
      int   b;  
  };  
   
  union   u3  
  {  
      char   a[13];  
      char   b;  
  };  
  #pragma   pack(8)  
   
  cout<<sizeof(u2)<<endl;     //   14  
  cout<<sizeof(u3)<<endl;     //   13  
   
          由于手动更改对界方式为2,所以int的对界也变成了2,u2的对界取成员中最大的对界,也是2了,所以此时sizeof(u2)=14。  
   
          结论:C++固有类型的对界取编译器对界方式与自身大小中较小的一个。  
   
  Top

52 楼fiftymetre(50米深蓝)回复于 2006-03-08 19:53:18 得分 0

9、struct的sizeof问题  
   
          因为对齐问题使结构体的sizeof变得比较复杂,看下面的例子:(默认对齐方式下)  
   
  struct   s1  
  {  
      char   a;  
      double   b;  
      int   c;  
      char   d;    
  };  
   
  struct   s2  
  {  
      char   a;  
      char   b;  
      int   c;  
      double   d;  
  };  
   
  cout<<sizeof(s1)<<endl;   //   24  
  cout<<sizeof(s2)<<endl;   //   16  
   
          同样是两个char类型,一个int类型,一个double类型,但是因为对界问题,导致他们的大小不同。计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1和s2的对界都取最大的元素类型,也就是double类型的对界8。然后开始摆放每个元素。  
          对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,但是下一个元素d是double类型,要放到8的对界上,离1最接近的地址是8了,所以d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,16可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个元素d需要对界1,也正好落在对界上,所以d放在了20,结构体在地址21处结束。由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大小变成了24。  
          对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;下一个元素c的对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,占用总空间为16,正好是8的倍数。  
   
          这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:  
   
  struct   s1  
  {  
      char   a[8];  
  };  
   
  struct   s2  
  {  
      double   d;  
  };  
   
  struct   s3  
  {  
      s1   s;  
      char   a;  
  };  
   
  struct   s4  
  {  
      s2   s;  
      char   a;    
  };  
   
  cout<<sizeof(s1)<<endl;   //   8  
  cout<<sizeof(s2)<<endl;   //   8  
  cout<<sizeof(s3)<<endl;   //   9  
  cout<<sizeof(s4)<<endl;   //   16;  
   
          s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异。  
   
          所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。  
   
  10、不要让double干扰你的位域  
   
          在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码:  
   
  struct   s1  
  {  
      int   i:   8;  
      int   j:   4;  
      double   b;  
      int   a:3;  
  };  
   
  struct   s2  
  {  
      int   i;  
      int   j;  
      double   b;  
      int   a;  
  };  
   
  struct   s3  
  {  
      int   i;  
      int   j;  
      int   a;  
      double   b;  
  };  
   
  struct   s4  
  {  
      int   i:   8;  
      int   j:   4;  
      int   a:3;  
      double   b;  
  };  
   
  cout<<sizeof(s1)<<endl;     //   24  
  cout<<sizeof(s2)<<endl;     //   24  
  cout<<sizeof(s3)<<endl;     //   24  
  cout<<sizeof(s4)<<endl;     //   16  
   
          可以看到,有double存在会干涉到位域(sizeof的算法参考上一节),所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。  
   
          第一次写东西,发现自己的表达能力太差了,知道的东西讲不出来,讲出来的东西别人也看不懂,呵呵。另外,C99标准的sizeof已经可以工作在运行时了,打算最近找个支持C99的编译器研究一下。  
   
   
  Top

53 楼defyer007(深入浅出)回复于 2006-03-08 20:50:48 得分 0

这些东西在实际开发中有多大的意义...Top

54 楼defyer007(深入浅出)回复于 2006-03-08 21:07:06 得分 0

不过是好文章,mark一下!Top

55 楼gudulyn(冰楠)回复于 2006-03-08 21:43:07 得分 0

mark   and   study.Top

56 楼quicksandj2()回复于 2006-03-08 22:39:43 得分 0

markTop

57 楼clzi(楚浪子-我要变强!)回复于 2006-03-08 23:25:13 得分 0

mark!Top

58 楼liuminghong(长风)回复于 2006-03-09 08:36:49 得分 0

学习中  
  最近的面试好像考链表的也比较多Top

59 楼mmmcd(超超)回复于 2006-03-09 08:40:35 得分 0

支持!!!Top

60 楼Randomize()回复于 2006-03-09 10:10:34 得分 0

個人認為相當有意義!Top

61 楼passionke(每一步都改变未来,却只能有一种结局!)回复于 2006-03-09 13:10:33 得分 0

upTop

62 楼yxg80(林夕昱)回复于 2006-03-09 13:55:17 得分 0

mark,学习Top

63 楼cdo(Everything has a favourable turn)回复于 2006-03-09 15:32:50 得分 0

关于sizeof的面试题在csdn上好像有一段时间没看到了.以前谈论得很多的.还有位域的问题.Top

64 楼ytfrdfiw()回复于 2006-03-09 15:53:47 得分 0

很好。。。。Top

65 楼zhangwencui(文一)回复于 2006-03-09 17:07:01 得分 0

UP     学习中。Top

66 楼hsyouxishe(金笛玉洁)回复于 2006-03-09 17:38:13 得分 0

真是雪中送碳啊!!Top

67 楼luvybird()回复于 2006-03-09 22:24:01 得分 0

收藏  
  Top

68 楼howyougen(夫孝,德之本也,教之所由生也)回复于 2006-03-09 22:44:26 得分 0

楼主好人Top

69 楼Deneral(我是中国人)回复于 2006-03-09 23:29:38 得分 0

收藏Top

70 楼zengweipeng(zwp)回复于 2006-03-10 13:27:19 得分 0

up!!!!!!!!!!!!1Top

71 楼shifind(浪子哲)回复于 2006-03-10 14:18:24 得分 0

MarkTop

72 楼charley450(摆渡接班人)回复于 2006-03-10 15:39:08 得分 0

对楼主细致的讲解表示感谢  
  但是我好像发现了个问题用lz的分析方法不得其解  
  如果结构体是这样构造  
   
  struct   temp  
  {  
  double   var1;  
  int         var2;  
  char       var3;  
  };  
   
  是否sizeof(temp)就应该是13了呢?  
  照楼主的解释,var1的偏移量是0,是sizeof(double)的倍数;var2的偏移量是8,也是sizeof(int)的倍数;var3的偏移量是12,也是sizeof(var3)的倍数;那么完全不用去填充,sizeof(temp)的值就应该是sizeof(double)+sizeof(int)+sizeof(char)=13,可为什么我在VS6.0中运行的结果是16呢?  
   
  希望高手可以为我解释一下。Top

73 楼charley450(摆渡接班人)回复于 2006-03-10 15:41:11 得分 0

楼主不好意思,我没看全~~~  
  大家无视我好了Top

74 楼cyt2005(Airroll)回复于 2006-03-10 15:41:54 得分 0

up   up  
  and   learningTop

75 楼sukyin()回复于 2006-03-10 16:22:27 得分 0

charley450(摆渡接班人)有意思哦~~Top

76 楼zeroless(111111000000零寻觅壹中.....)回复于 2006-03-10 16:26:24 得分 0

mark~~~~~~~~~~~~~~~~~~~~  
  thxs!!!Top

77 楼TERRYYRRET(命运)回复于 2006-03-10 20:35:06 得分 0

学习Top

78 楼ruodeer(看我的个性签名都给我分)回复于 2006-03-10 22:28:23 得分 0

留到面试结束Top

79 楼clzi(楚浪子-我要变强!)回复于 2006-03-10 23:18:26 得分 0

好东西,学习Top

80 楼sparrow009(奇疯)回复于 2006-03-11 14:19:31 得分 0

好东西啊!  
  哈哈哈Top

81 楼zxx110(新)回复于 2006-03-11 15:42:39 得分 0

markTop

82 楼Helloooooo(每天,我都新的)回复于 2006-03-11 17:08:09 得分 0

掌握这些需要知道实质,不然光记忆这些条款就很费力了。  
   
  1,SIZEOF的执行时间  
  2,字节对齐的知识Top

83 楼dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-03-11 19:35:33 得分 0

很久没有看到这么专业的强贴了,  
  一定要顶一下  
  <  
  <  
  <  
  <  
  <Top

84 楼yinqing_yx(淘汰引擎)(玩虚一族)回复于 2006-03-11 22:39:24 得分 0

啊     认真看完了     如果面试出上的话   我请各位吃饭啊!  
  先顶了~~~~~~~~~~~~~Top

85 楼FlyInCC(C++,叫我如何不爱你)回复于 2006-03-12 00:53:30 得分 0

mark.  
  好贴,学习中...Top

86 楼wkcmail(asdf)回复于 2006-03-12 01:01:22 得分 0

mark  
  Top

87 楼cnromp(星龙)回复于 2006-03-12 10:56:45 得分 0

好东西   收藏起来了!Top

88 楼francis_zj(健健)回复于 2006-03-12 10:57:21 得分 0

不错啊楼主Top

89 楼Free_Wind22(还没想好...)回复于 2006-03-12 11:28:37 得分 0

谢谢~~  
      markTop

90 楼this927470(锄禾日当午)回复于 2006-03-12 11:33:53 得分 0

收藏,谢谢Top

91 楼windha()回复于 2006-03-12 16:18:19 得分 0

写的好啊~Top

92 楼xueqiangjava(红眼睛)回复于 2006-03-12 17:41:26 得分 0

谢谢Top

93 楼laoren_80(老车站)回复于 2006-03-12 17:46:27 得分 0

lihai    
  Top

94 楼hopechen(成灰)回复于 2006-03-12 21:22:54 得分 0

I   MARKTop

95 楼angel_rabbit(zj_rabbit)回复于 2006-03-13 13:29:43 得分 0

mark,....Top

96 楼icwin(www.cat898.com.cn)回复于 2006-03-13 14:49:01 得分 0

upTop

97 楼Allblus(爽)回复于 2006-03-13 14:49:09 得分 0

好贴收藏Top

98 楼iamcaicainiao(老菜,长征)回复于 2006-03-13 15:07:58 得分 0

8错8错。  
   
  up搂主和50米。Top

99 楼whutcl8110(whut)回复于 2006-03-13 15:40:41 得分 0

好人好贴Top

100 楼whutcl8110(whut)回复于 2006-03-13 15:47:33 得分 0

如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式  
  是不是就是下面的规则:  
   
   
  Char    
  偏移量必须为sizeof(char)即1的倍数    
   
  int    
  偏移量必须为sizeof(int)即4的倍数    
   
  float    
  偏移量必须为sizeof(float)即4的倍数    
   
  double    
  偏移量必须为sizeof(double)即8的倍数    
   
  Short    
  偏移量必须为sizeof(short)即2的倍数  
  Top

101 楼Stefine(CSDN最菜滴猩猩)回复于 2006-03-13 18:33:52 得分 0

路过Top

102 楼tatbaby(岛主)回复于 2006-03-13 18:44:19 得分 0

mark!Top

103 楼LuZhou(卢周)回复于 2006-03-13 18:52:40 得分 0

谢谢呦!Top

104 楼flyinf_guo(过过)回复于 2006-03-13 19:27:20 得分 0

学习Top

105 楼luocolor1()回复于 2006-03-13 22:07:13 得分 0

学习Top

106 楼start1298(hugo)回复于 2006-03-14 11:23:29 得分 0

study~~~~!!!!!Top

107 楼hank_xin(hanlei)回复于 2006-03-14 12:19:59 得分 0

受益了,谢谢楼主!Top

108 楼wjlsmail(小脖领)回复于 2006-03-14 12:41:41 得分 0

StudyTop

109 楼FeelingWELL(FeelingWELL)回复于 2006-03-14 13:35:28 得分 0

mark!  
  sizeof在C语言中大多用于为指针变量分配内存空间,与malloc配合使用  
  如:         void   f(....)  
                        {....  
                      ....  
                            *p=(double*)malloc(10*sizeof(double));  
                    ....  
                        }  
  上例作用是为指针变量p分配10个double型字符的空间  
  sizeof(double)的作用是测量double型字符的长度~Top

110 楼xiang1358(向圣海)回复于 2006-03-14 14:01:35 得分 0

mark   学习Top

111 楼jitongwang()回复于 2006-03-15 00:42:52 得分 0

很有收获!Top

112 楼ycy589(ycy589)回复于 2006-03-15 14:58:18 得分 0

学习Top

113 楼jiangzhu20(小蒋)回复于 2006-03-15 15:30:53 得分 0

学习Top

114 楼czp(万非)回复于 2006-03-15 16:10:31 得分 0

Mark!Top

115 楼dragonhux(dragon(清水))回复于 2006-03-15 16:26:27 得分 0

 
  struct   temp  
  {  
  double   var1;       占用8字节  
  int         var2;       占用4字节  
  char       var3;       占用1字节  
                                补充3字节   结构必须按struct中最大元素的  
                                长度补齐(按double长度的倍数补齐,即8的倍数)  
  };  
  所有sizeof(temp)=16  
   
  to   charley450(摆渡接班人)   (   )   信誉:100    
   
  对楼主细致的讲解表示感谢  
  但是我好像发现了个问题用lz的分析方法不得其解  
  如果结构体是这样构造  
   
  struct   temp  
  {  
  double   var1;  
  int         var2;  
  char       var3;  
  };  
   
  是否sizeof(temp)就应该是13了呢?  
  照楼主的解释,var1的偏移量是0,是sizeof(double)的倍数;var2的偏移量是8,也是sizeof(int)的倍数;var3的偏移量是12,也是sizeof(var3)的倍数;那么完全不用去填充,sizeof(temp)的值就应该是sizeof(double)+sizeof(int)+sizeof(char)=13,可为什么我在VS6.0中运行的结果是16呢?  
   
  希望高手可以为我解释一下。Top

116 楼wangtopcool(逆水行舟,不进则退)回复于 2006-03-15 17:27:15 得分 0

学习...Top

117 楼njuzgj(罐子)回复于 2006-03-15 17:32:49 得分 0

学习Top

118 楼cattlenzq(吃狼的豆腐(不要给分了,散起来真麻烦!))回复于 2006-03-16 18:47:27 得分 0

没说的顶Top

119 楼Rietch(易水寒冰)回复于 2006-03-16 19:48:05 得分 0

不错,不错,楼主分析得不错!!Top

120 楼z040304374(xin)回复于 2006-03-16 20:12:50 得分 0

不错,不错,楼主分析得very   good!!!~~~~  
  Top

121 楼bg205(chenyx)回复于 2006-03-16 21:59:39 得分 0

学习Top

122 楼turbocamel(骆驼◎沙漠.com)回复于 2006-03-16 22:49:37 得分 0

sizeof("AA")是多少呢?  
  运行系统vc6.0,   win2kTop

123 楼cyblueboy83(爱情白痴—电脑迷)回复于 2006-03-16 23:42:22 得分 0

不错,收藏Top

124 楼femalelover(楼主, 请把用不着的可用分捐给我1/3 :()回复于 2006-03-17 11:08:32 得分 0

sizeof("AA")是多少呢?  
  运行系统vc6.0,   win2k  
  -------------------  
  竟然是三字节!为什么Top

125 楼femalelover(楼主, 请把用不着的可用分捐给我1/3 :()回复于 2006-03-17 11:21:44 得分 0

class   A  
  {  
  public:  
  int     n_a; //4  
  char   c_b; //1  
  float   f_d; //4  
  double   d_c; //8  
  public:  
  A(){};  
    ~A(){};  
  virtual   void   o(){};  
   
  };  
  不加虚函数,sizeof(A)=24,这个没问题.  
  加一个虚函数,sizeof(A)=32;   这仍然可以按楼主说的解释.  
  加九个个虚函数,仍然是   32,奇怪吗.   好像解释不来了.Top

126 楼FeelingWELL(FeelingWELL)回复于 2006-03-17 11:28:29 得分 0

 
  struct   temp  
  {  
  double   var1;       占用8字节  
  int         var2;       占用4字节  
  char       var3;       占用1字节  
                                补充3字节   结构必须按struct中最大元素的  
                                长度补齐(按double长度的倍数补齐,即8的倍数)  
  };  
  所有sizeof(temp)=16  
   
  to   charley450(摆渡接班人)   (   )   信誉:100    
   
  对楼主细致的讲解表示感谢  
  但是我好像发现了个问题用lz的分析方法不得其解  
  如果结构体是这样构造  
   
  struct   temp  
  {  
  double   var1;  
  int         var2;  
  char       var3;  
  };  
   
  是否sizeof(temp)就应该是13了呢?  
  照楼主的解释,var1的偏移量是0,是sizeof(double)的倍数;var2的偏移量是8,也是sizeof(int)的倍数;var3的偏移量是12,也是sizeof(var3)的倍数;那么完全不用去填充,sizeof(temp)的值就应该是sizeof(double)+sizeof(int)+sizeof(char)=13,可为什么我在VS6.0中运行的结果是16呢?  
   
  希望高手可以为我解释一下。  
       
  所说的结构体大小,应该就是结构体中占用字节最大的类型,它的大小就是结构体的大小  
  如:struct   temp{double   a;  
                                  int   b;  
                                  float   c;  
                                  char   d;  
                                                  }         //temp的大小就double类型的大小,即8字节Top

127 楼SanFire(SanFire)回复于 2006-03-17 14:22:02 得分 0

前文提及,结构的存储空间是结构中占存储空间最大的变量的存储空间的整数倍。  
  在  
  struct   temp  
  {  
  double   var1;  
  int   var2;  
  char   var3;  
  };  
  中,显然sizeof(   double   )   =   8;  
  而13显然不是8的倍数。于是编译系统(vs6.0)自动对齐空间,填充3byte的空间,最后得到16的大小。Top

128 楼gao89098082(正宗饼子堂堂主)回复于 2006-03-17 14:48:11 得分 0

狂考你sizeof的公司是华为的子公司慧通吧NNDTop

129 楼shine51151(美丽心情)回复于 2006-03-17 15:55:38 得分 0

RE:  
   
  sizeof("AA")是多少呢?  
  运行系统vc6.0,   win2k  
   
  你忘了字符串的后面还有个系统自动附加上的结束符‘\0’!  
  所以共占3字节!!Top

130 楼afeu007(梦里开宝马)回复于 2006-03-17 17:39:14 得分 0

markTop

131 楼turbocamel(骆驼◎沙漠.com)回复于 2006-03-17 17:56:32 得分 0

sizeof("AA")  
  我得运行结果是4,怎么解释Top

132 楼kypck_()回复于 2006-03-17 18:29:37 得分 0

我曾经去某外企笔试是考了道题目是:  
  class   AAA  
  {}  
   
  ...  
  cout   <<   sizeof(AAA);  
  ...  
  我说这个和编译器有关,结果那人硬是说是1(因为他在vc下试过),争的面都红了,我狂昏。Top

133 楼sjjf(水晶剑锋)回复于 2006-03-17 19:05:06 得分 0

先mark在看Top

134 楼xombat(壞牧羊人)回复于 2006-03-18 16:45:19 得分 0

mark   oTop

135 楼shenmea00000(学习中~~~)回复于 2006-03-18 23:47:02 得分 0

真不错哈  
  Top

136 楼qifa(DoItNow)回复于 2006-03-19 02:02:18 得分 0

学习。。。Top

137 楼waxic(waxic)回复于 2006-03-19 14:45:10 得分 0

好Top

138 楼tudou614(魔蟹座的SATAN)回复于 2006-03-20 01:20:26 得分 0

mkTop

139 楼brianlu(-)回复于 2006-03-20 09:40:06 得分 0

markTop

140 楼crystal521(【云淡风轻】)回复于 2006-03-20 09:40:57 得分 0

supportTop

141 楼oosky2004(我要好东西)回复于 2006-03-20 11:59:46 得分 0

来过。  
  Top

142 楼fightintokyo()回复于 2006-03-20 17:37:10 得分 0

marK.Top

143 楼zhoujiamurong(有分俺就不要,俺要知识)回复于 2006-03-21 12:44:56 得分 0

还不错,不过仅仅用于面试Top

144 楼roger_77(阿生)(路漫漫长,上下索求)回复于 2006-03-21 13:02:38 得分 0

不错的东东,收下好好看.  
  3QTop

145 楼r_s(星期四)回复于 2006-03-22 09:11:13 得分 0

学习&&收藏!Top

146 楼wave2050(hello word)回复于 2006-03-22 13:13:39 得分 0

!bucuo     !Top

147 楼liyusen007(森)回复于 2006-03-22 16:39:06 得分 0

sizeof("AA")  
  我得运行结果是4,怎么解释  
  答:“AA”是字符串常量指针Top

148 楼frland()回复于 2006-03-23 15:42:38 得分 0

其实就两个用法,一个是类型大小,如 sizeof(int)  
  另一个是变量大小,取决于定义时的声明  
   
  char*   buf=new   char[255];  
  sizeof(buf)=sizeof(char*)=4;  
   
  char   buf[255];  
  sizeof(buf)=sizeof(char[255])=255;Top

149 楼frland()回复于 2006-03-23 15:44:57 得分 0

c++的特点就是对内存的直接控制,出问题最多也是这里,如果只当"笔试"专用,那太初级了Top

150 楼lcb2008(安徽の刀)回复于 2006-03-24 00:42:27 得分 0

好东东!  
  不过,对于“对类型使用sizeof,注意这种情况下写成sizeof   typename是非法的。”   这一点一般书上也都是这么介绍的,不过偶发现下面的代码也可以运行,木有问题。(VC6,   VS2003)  
  typedef   int   INT;  
  cout   <<   sizeof   INT   <<   endl;  
  只要sizeof   xxx,xxx类型不是直接的内置类型(关键字显蓝色),貌似都可以用,自定义类也可以。  
  Top

151 楼xys123456(xys)回复于 2006-03-25 09:55:11 得分 0

不错,不过似乎少了:类的sizeofTop

152 楼tandylee()回复于 2006-03-26 02:24:12 得分 0

好东东阿Top

153 楼shantai(阿山)回复于 2006-03-26 03:11:24 得分 0

study   +   ing   ...Top

154 楼iicup(双杯献酒)回复于 2006-03-26 15:34:56 得分 0

sizeof的结果是对象的内存大小(字节数),  
  这个数据的具体大小通常并不是非常重要,  
  对于一般应用而言,我们甚至连什么是字节都不需要知道.  
  现在都一窝风考这个东西,  
  只能说是出题人浅薄.  
  (需要接近底层硬件编程的公司不在此列)Top

155 楼tidyduck(辨不清东南西北)回复于 2006-03-27 10:14:23 得分 0

嗯,很重要,mark一下!Top

156 楼sky911911(assda)回复于 2006-03-27 10:19:47 得分 0

ding!Top

157 楼shot411(上帝的马甲)回复于 2006-03-28 20:12:35 得分 0

goodTop

158 楼lilywon(小猫妙妙)回复于 2006-03-28 22:36:10 得分 0

好好学习,同时向无私的人致敬。Top

159 楼junjie_2006(俊杰)回复于 2006-03-28 22:56:07 得分 0

up   upTop

160 楼maguschen(进化++)回复于 2006-03-28 23:59:15 得分 0

拜读过~!   :)Top

161 楼iamwiner(烛泪)回复于 2006-03-29 11:56:26 得分 0

收藏.Top

162 楼roger_77(阿生)(路漫漫长,上下索求)回复于 2006-03-29 13:12:10 得分 0

好东东,我也收藏了。  
  Top

163 楼steed_jet(训练中de英雄)回复于 2006-03-29 14:15:07 得分 0

学习一下Top

164 楼10325(海上的云)回复于 2006-03-30 16:45:11 得分 0

我也来学学  
  谢谢Top

165 楼lid0770(卡卡)回复于 2006-03-30 18:31:59 得分 0

UPTop

166 楼codesun(木木)回复于 2006-03-31 14:36:18 得分 0

day   day   upTop

167 楼soloxiao(红色孤独)回复于 2006-04-01 15:53:03 得分 0

作个记号Top

168 楼soloxiao(红色孤独)回复于 2006-04-01 15:59:18 得分 0

struct   sx  
  {  
          unsigned   char   a[4];  
          unsigned   short   len;  
          unsigned   char   b[1];  
  };  
   
  为了执行sizeof(sx)=7  
  添加#pragma   pack(1)   ,请问大家设定为1是否会降低程序的执行效率或者有没有什么影响  
  Top

169 楼Angly1018(#一*直¥在!)回复于 2006-04-01 23:03:39 得分 0

很好價值,學習。Top

170 楼justrun2005(机枪)回复于 2006-04-02 02:17:02 得分 0

50mi   竟然抢搂主的风头??建议扣性欲!!!Top

171 楼crescentg(我找不到改昵称的地方了,谁教教我呀)回复于 2006-04-02 20:23:05 得分 0

经典!markTop

172 楼csj50(行风)回复于 2006-04-02 21:42:38 得分 0

markTop

173 楼yuanchuang(元创)回复于 2006-04-07 10:06:03 得分 0

markTop

174 楼LiHubei(lhb)回复于 2006-04-07 10:50:22 得分 0

学习Top

175 楼brookqdc(小溪)回复于 2006-04-07 11:22:33 得分 0

我觉得这对于初级学者,真的是不错!  
   
  了解了一些深入的问题,认识不那么肤浅了,谢谢楼主!Top

176 楼yleiou(单刀匹马)回复于 2006-04-08 17:56:54 得分 0

很好收藏Top

177 楼huakaizizai(花开自在)回复于 2006-04-08 18:07:09 得分 0

好东西谢谢楼主啦!Top

178 楼pottichu(拉拉是头猪)回复于 2006-04-08 21:47:39 得分 0

收藏,有空的时候再研究。Top

179 楼sdw47125465(大为)回复于 2006-04-08 22:15:12 得分 0

mark!!Top

180 楼super00tiger(路人甲)回复于 2006-04-08 22:26:12 得分 0

不错  
   
   
  markTop

181 楼doudou52520(烈日严严)回复于 2006-04-08 23:32:43 得分 0

mark   ```  
  Top

182 楼xiongmao007()回复于 2006-04-09 11:23:12 得分 0

占位Top

183 楼ytfrdfiw()回复于 2006-04-10 08:50:57 得分 0

upTop

184 楼Acoolice()回复于 2006-04-10 10:53:54 得分 0

studyTop

185 楼pkgod(pkgod)回复于 2006-04-13 20:32:27 得分 0

很好的帖子,学到东西了。最近在看.net的东西,它也有调用unmanaged   code的情况,里面也有对struct的引用。StructLayout.packTop

186 楼dch4890164(巴拉克)回复于 2006-04-13 21:18:28 得分 0

mark!Top

187 楼yekeleaf()回复于 2006-05-17 01:08:40 得分 0

mark!Top

188 楼lxkim()回复于 2006-05-17 09:09:12 得分 0

学习!Top

189 楼fine10000(好心情)回复于 2006-05-17 11:10:07 得分 0

学习!  
  Top

190 楼gjianpro(#ifndef _DEBUG)回复于 2006-05-17 11:44:51 得分 0

dingTop

191 楼code_tin(代码罐头[看来牛魔王快做不成了])回复于 2006-05-17 11:57:52 得分 0

楼主能告知一下帖的是哪本书上的么?  
  我直接去看书去。Top

192 楼sarh2os()回复于 2006-05-17 12:08:28 得分 0

细节出真知!支持楼主!Top

193 楼changyanxiao(踏雪无情)回复于 2006-05-17 14:59:12 得分 0

markTop

194 楼ywhbn(天涯)回复于 2006-05-17 15:14:46 得分 0

收藏Top

195 楼cppstar(密雨繁星)回复于 2006-05-17 15:32:38 得分 0

mark   tooTop

196 楼Bilter()回复于 2006-05-17 15:54:08 得分 0

写的很详细,谢谢楼主!Top

197 楼shala99(STEVEN)回复于 2006-05-17 17:17:24 得分 0

GOOD   MARK~Top

198 楼Gucciwu(一意孤行 www.57studio.net)回复于 2006-05-17 17:48:48 得分 0

谢了,又学了不少:)Top

199 楼coldwindtang(风)回复于 2006-05-17 20:35:03 得分 0

mark  
  Top

200 楼lhsoft(PB只会用5.0版)回复于 2006-05-17 21:06:01 得分 0

markTop

201 楼djfu(飞龙在天)回复于 2006-05-17 21:08:41 得分 0

markTop

202 楼weiting623()回复于 2006-05-19 10:32:19 得分 0

凑个热闹Top

203 楼sharpdew(风刃)回复于 2006-05-19 10:34:31 得分 0

我怎么觉得这个我们已经讨论过不下10次了,呵呵!Top

204 楼liguang8212()回复于 2006-05-19 10:55:33 得分 0

haotie   !Top