加载中…
个人资料
一叶知秋
一叶知秋
  • 博客等级:
  • 博客积分:0
  • 博客访问:425,158
  • 关注人气:82
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

sizeof总结

(2013-06-02 17:03:05)
标签:

sizeof

it

分类: C

定义:

    sizeof C语言的关键字,是操作符而不是函数,用于计算数据空间所占用内存的字节数。字节数的计算在程序编译时进行。

返回值:

    返回值类型为size_t,这是一个依赖于编译系统的值,一般定义为:

                          typedef unsigned int size_t;

指针的sizeof

32位计算机中,一个指针变量的返回值必定是4

int *p; sizeof(p)=4;
                 
sizeof(*p)相当于sizeof(int);      

数组的sizeof

数组的sizeof值等于数组所占用的内存字节数,数组在用作函数的参数时,会自动退化为指针类型.

  int a[10];  char b[]="hello";
             sizeof(a)
等于4*10=40;           sizeof(b)等于6;

数组做型参时,数组名称当作指针使用!!
               void  fun(char p[])    sizeof(p)
等于       

结构体的sizeof----------------VC下要注意内存对齐的问题。

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
       2)
结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍

    总之:数据对齐原则----内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。。。。。
如果结构体中含有数组,数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。

注意:空结构体(不含数据成员)的大小不为0,而是1

编译器的pack指令

用来调整结构体对齐方式,不同编译器名称和用法略有不同,VC6中通过#pragma pack实现:#pragma pack( n )n为字节对齐数,其取值为124816,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值。

含位域结构体的sizeof

位域成员不能单独被取sizeof值,我们这里要讨论的是含有位域的结构体的sizeof

intunsigned intbool可以作为位域类型,使用位域可以规定某个成员所能占用的空间,所以能在一定程度上节省结构体占用的空间,达到压缩存储的目的。

1)如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2)
如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3)
如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
4)
如果位域字段之间穿插着非位域字段,则不进行压缩
5)
整个结构体的总大小为最宽基本类型成员大小的整数倍。

联合体的sizeof

    整个联合体的sizeof也就是每个成员sizeof的最大值

sizeofstrlen的比较:
       1sizeof是运算符,strlen是函数。

2sizeof可以用类型做参数,strlen只能用char*做参数

     3sizeof运算结果在编译时执行,计算的是类型所占内存的大小,而strlen运行时执行,是用来计算字符串的实际长度

4strlen()只能计算字符数组的字符数,必须以"\0"为结束符。如果没有结束符,计算错误,其计算结果不包含\0本身所占空间。而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。

经典问题: 
      double* (*a)[3][6]; 
      cout<<sizeof(a)<<endl; // 4 a
为指针
      cout<<sizeof(*a)<<endl; // 72 *a
为一个有3*6个指针元素的数组
      cout<<sizeof(**a)<<endl; // 24 **a
为数组一维的6个指针
      cout<<sizeof(***a)<<endl; // 4 ***a
为一维的第一个指针
      cout<<sizeof(****a)<<endl; // 8 ****a
为一个double变量

问题解析: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 

 

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有