CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

关于sizeof(struct) 问题,字节对齐,有详细说明最好wen

楼主juping_chen(jack)2006-06-01 20:06:34 在 C/C++ / C语言 提问

#pragma   pack(3)  
  struct   astruct{  
  char   w;  
  int   a;  
  char   r;  
  int   c;  
  double   b;  
  };   //sizeof(astruct)=13 问题点数:20、回复次数:10Top

1 楼wanfustudio(雁南飞:知识之败,慕虚名而不务潜修也)回复于 2006-06-01 20:12:17 得分 0

看来又要拿分了:)  
  关键字:sizeof,字节对齐,多继承,虚拟继承,成员函数指针  
   
  前向声明:  
          sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着“辛苦我一个,幸福千万人”的伟大思想,我决定将其尽可能详细的总结一下。  
          但当我总结的时候才发现,这个问题既可以简单,又可以复杂,所以本文有的地方并不适合初学者,甚至都没有必要大作文章。但如果你想“知其然,更知其所以然”的话,那么这篇文章对你或许有所帮助。  
          菜鸟我对C++的掌握尚未深入,其中不乏错误,欢迎各位指正啊  
   
  1.   定义:  
          sizeof是何方神圣sizeof乃C/C++中的一个操作符(operator)是也,简单的说其作用就是返回一个对象或者类型所占的内存字节数。  
   
  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.  
          其返回值类型为size_t,在头文件stddef.h中定义。这是一个依赖于编译系统的值,一般定义为  
  typedef   unsigned   int   size_t;  
          世上编译器林林总总,但作为一个规范,它们都会保证char、signed   char和unsigned  
  char的sizeof值为1,毕竟char是我们编程能用的最小数据类型。  
   
  2.   语法:  
          sizeof有三种语法形式,如下:  
          1)   sizeof(   object   );   //   sizeof(   对象   );  
          2)   sizeof(   type_name   );   //   sizeof(   类型   );  
          3)   sizeof   object;   //   sizeof   对象;  
  所以,  
  int   i;  
  sizeof(   i   );   //   ok  
  sizeof   i;   //   ok  
  sizeof(   int   );   //   ok  
  sizeof   int;   //   error  
          既然写法3可以用写法1代替,为求形式统一以及减少我们大脑的负担,第3种写法,忘掉它吧!实际上,sizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一致的。这里,对象可以进一步延伸至表达式,即sizeof可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。如:  
  sizeof(   2   );   //   2的类型为int,所以等价于   sizeof(   int   );  
  sizeof(   2   +   3.14   );     //   3.14的类型为double,2也会被提升成double类型,所以等价于   sizeof(   double   );  
   
          sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用,我们来看一个完整的例子:  
  char   foo()  
  {  
          printf("foo()   has   been   called.\n");  
          return   'a';  
  }  
  int   main()  
  {  
          size_t   sz   =   sizeof(   foo()   );   //   foo()   的返回值类型为char,所以sz   =   sizeof(char   ),foo()并不会被调用  
          printf("sizeof(   foo()   )   =   %d\n",   sz);  
  }  
   
          C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算sizeof值,即下面这些写法都是错误的:  
          sizeof(   foo   );//   error  
          void   foo2()   {   }  
          sizeof(   foo2()   );//   error  
          struct   S  
          {  
                  unsigned   int   f1   :   1;  
                  unsigned   int   f2   :   5;  
                  unsigned   int   f3   :   12;  
          };  
          sizeof(   S.f1   );//   error  
   
  3.   sizeof的常量性  
          sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用,如:  
  char   ary[   sizeof(   int   )   *   10   ];   //   ok  
          最新的C99标准规定sizeof也可以在运行时刻进行计算,如下面的程序在Dev-C++中可以正确执行  
  Top

2 楼wanfustudio(雁南飞:知识之败,慕虚名而不务潜修也)回复于 2006-06-01 20:13:30 得分 0

贴这么多吧  
   
  实在太长了  
  你上我blog上看吧足有几万字:)  
  http://blog.csdn.net/wanfustudio/  
   
  Top

3 楼wanfustudio(雁南飞:知识之败,慕虚名而不务潜修也)回复于 2006-06-01 20:14:07 得分 0

http://blog.csdn.net/wanfustudio/archive/2006/05/02/705681.aspxTop

4 楼happytang(一只叫苏格拉底的猪)回复于 2006-06-01 21:02:41 得分 0

2.1   自然对界  
   
    struct是一种复合数据类型,其构成元素既可以是基本数据类型(如   int、long、float等)的变量,也可以是一些复合数据类型(如array、struct、union等)的数据单元。对于结构体,编译器会自动进行成员变量的对齐,以提高运算效率。缺省情况下,编译器为结构体的每个成员按其自然对界(natural   alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。  
   
    自然对界(natural   alignment)即默认对齐方式,是指按结构体的成员中size最大的成员对齐。  
   
    例如:  
   
  struct   naturalalign  
  {  
    char   a;  
    short   b;  
    char   c;  
  };  
   
    在上述结构体中,size最大的是short,其长度为2字节,因而结构体中的char成员a、c都以2为单位对齐,sizeof(naturalalign)的结果等于6;  
   
    如果改为:  
   
  struct   naturalalign  
  {  
    char   a;  
    int   b;  
    char   c;  
  };  
   
    其结果显然为12。  
  指定对界  
   
    一般地,可以通过下面的方法来改变缺省的对界条件:  
   
    ·   使用伪指令#pragma   pack   (n),编译器将按照n个字节对齐;  
    ·   使用伪指令#pragma   pack   (),取消自定义字节对齐方式。  
   
    注意:如果#pragma   pack   (n)中指定的n大于结构体中最大成员的size,则其不起作用,结构体仍然按照size最大的成员进行对界。  
   
    例如:  
   
  #pragma   pack   (n)  
  struct   naturalalign  
  {  
    char   a;  
    int   b;  
    char   c;  
  };  
  #pragma   pack   ()  
   
    当n为4、8、16时,其对齐方式均一样,sizeof(naturalalign)的结果都等于12。而当n为2时,其发挥了作用,使得sizeof(naturalalign)的结果为8。  
  Top

5 楼happytang(一只叫苏格拉底的猪)回复于 2006-06-01 21:47:31 得分 0

http://www.blogcn.com/user43/gjloveht/index.html  
  http://vcpro.blogchina.com/1253903.html  
  1、2、4、8、16为#pragma   pack(n)中n的字节数,其他不符合的都按默认为8  
  你这个题不对吧,这样编译通过,sizeof也是24  
  n为2/4,sizeof就是20Top

6 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 22:01:42 得分 0

楼主用的是   TC   吧,  
  得到的结果是   14   唉,  
  怎么会是   13   呢   ...  
   
  一般#pragma   pack   跟的参数都是   2的次方,  
  没有用   3   这么怪异的   ...Top

7 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 22:10:45 得分 0

#pragma   pack(3)  
  struct   astruct{  
  char   w;     //内存编址   0     ,这里是一个相对编址  
  int   a;       //TC中为2字节,对齐到2,内存为2,3  
  char   r;     //内存编址   4  
  int   c;       //对齐,   内存编址   6,7  
  double   b;   //对齐,注意pragma   pack(3),对齐到3,内存编址   9,10,11,12  
  };    
   
  使用的内存是   0-12   共13字节,  
  楼主的答案不是这么得到的吧   ?    
  呵呵,注意最后所有空间还需要对齐操作的   ......Top

8 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 22:17:45 得分 0

好像高错了,  
  double   是8字节的....  
   
  似乎所有的变量对齐到   1   就有14个字节的空间了吧   ....Top

9 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 22:21:15 得分 0

16位TC下:  
  #pragma   pack(3)  
  struct   astruct{  
  char   w;     //内存编址   0     ,这里是一个相对编址  
  int   a;       //TC中为2字节,对齐到2,内存为2,3  
  char   r;     //内存编址   4  
  int   c;       //对齐,   内存编址   6,7  
  double   b;   //对齐,注意pragma   pack(3),对齐到3,  
                                        //内存编址   9,10,11,12,13,14,15,16  
  };  
   
  使用   0-16   共17字节,  
  对齐到   min[3,   sizeof(double)]   =   3,  
  结果应该是   18   字节   ...Top

10 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 22:23:22 得分 0

32位环境下,   比如VC:  
  #pragma   pack(3)  
  struct   astruct{  
  char   w;     //内存编址   0     ,这里是一个相对编址  
  int   a;       //4字节,对齐到3,内存为3,4,5,6  
  char   r;     //内存编址   7  
  int   c;       //对齐,   内存编址   9,10,11,12  
  double   b;   //对齐,注意pragma   pack(3),对齐到3,  
                                        //内存编址   15,16,17,18,19,20,21,22  
  };  
   
  使用   0-22   共23字节,  
  对齐到   min[3,   sizeof(double)]   =   3,  
  结果应该是   24   字节   ...Top

相关问题

关键词

得分解答快速导航

  • 帖主:juping_chen

相关链接

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

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo