sizeof()用法汇总

sizeof()功能:计算数据空间的字节数 1.与strlen()比较       strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为‘\0‘的数组元素。       而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。 2.指针与静态数组的sizeof操作       指针均可看为变量类型的一种。所有指针变量的sizeof 操作结果均为4。 注意:int *p; sizeof(p)=4;                   但sizeof(*p)相当于sizeof(int);            对于静态数组,sizeof可直接计算数组大小;       例:int a[10];char b[]="hello";               sizeof(a)等于4*10=40;               sizeof(b)等于6; 注意:数组做型参时,数组名称当作指针使用!!                void  fun(char p[])                {sizeof(p)等于4}

经典问题:       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。 3.格式的写法    sizeof操作符,对变量或对象可以不加括号,但若是类型,须加括号。 4.使用sizeof时string的注意事项    string s="hello";    sizeof(s)等于string类的大小,sizeof(s.c_str())得到的是与字符串长度。 5.union 与struct的空间计算    总体上遵循两个原则:    (1)整体空间是 占用空间最大的成员(的类型)所占字节数的整倍数    (2)数据对齐原则----内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。。。。。    注意:数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。 例:[引用其他帖子的内容] 因为对齐问题使结构体的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中才有这样的差异。   所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。

补充:不要让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类型放在程序的开始或者最后。

相关常数:

sizeof int:4

sizeof short:2

sizeof long:4

sizeof float:4

sizeof double:8

sizeof char:1

sizeof p:4

sizeof WORD:2

sizeof DWORD:4

时间: 2024-10-11 17:43:06

sizeof()用法汇总的相关文章

C#中DllImport用法汇总

(转) 最近使用DllImport,从网上google后发现,大部分内容都是相同,又从MSDN中搜集下,现将内容汇总,与大家分享. 大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能呢?答案是肯定的,大家可以通过C#中的DllImport直接调用这些功能. DllImport是System.Runtime.InteropServices命名空间下的

【Android】Android背景选择器selector用法汇总

一.创建xml文件,位置:drawable/xxx.xml,同目录下记得要放相关图片 <?xml version="1.0" encoding="utf-8" ?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 默认时的背景图片--> <item android:drawable="@draw

sizeof用法总结

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 ty

sizeof()用法总汇

sizeof()功能:计算数据空间的字节数 1.与strlen()比较       strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素.       而sizeof计算数据(包括数组.变量.类型.结构体等)所占内存空间,用字节数表示. 2.指针与静态数组的sizeof操作    指针均可看为变量类型的一种.所有指针变量的sizeof 操作结果均为4. 注意:int *p; sizeof(p)=4;  但sizeof(*p)相当于sizeof(int)

WordPress函数query_posts用法汇总

最近经常有网友跟我咨询WordPress函数query_posts的相关用法,说起来query_posts实在是太强大,参数无数,用法更是无数,如果让我说它的用法,我根本没法一一说清楚.开始之前,你可以先看看query_posts的官方文档,query_posts的全部参数可以参考:WP_Query.不过看文档对很多人来说可能会很困难,本文将介绍几种常见的用法,不过一切用法都是从官方文档中来的,学会看文档才是王道. query_posts函数在WordPress主题中是用于控制哪些文章可以出现在

JavaScript中常见的字符串操作函数及用法汇总

1.字符串转换 字符串转换是最基础的要求和工作,你可以将任何类型的数据都转换为字符串,你可以用下面三种方法的任何一种: ? 1 2 var num= 19; // 19 var myStr = num.toString(); // "19" 你同样可以这么做: ? 1 2 var num= 19; // 19 var myStr = String(num); // "19" 或者,再简单点儿: ? 1 2 var num= 19; // 19 var myStr =

正则表达式常用用法汇总 __西科大C语言

正则表达式,又称正规表示法.常规表示法.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则.在很多文本编辑器里,正则表达式通常被用来检索.替换那些符合某个模式的文本. 正则表达式,有木有人像我一样,学了好几遍却还是很懵圈,学的时候老明白了,学完了忘光了.好吧,其实还是练的不够,所谓温故而知新,可以为师矣,今天就随我来复习一下这傲娇的正则表达式吧. 为啥要有正则表达式呢?其

mysqldump 用法汇总

mysql mysqldump 只导出表结构 不导出数据 复制代码代码如下: mysqldump --opt -d 数据库名 -u root -p > xxx.sql 备份数据库  复制代码代码如下: #mysqldump 数据库名 >数据库备份名 #mysqldump -A -u用户名 -p密码 数据库名>数据库备份名 #mysqldump -d -A --add-drop-table -uroot -p >xxx.sql 1.导出结构不导出数据  复制代码代码如下: mysql

sizeof用法

sizeof sizeof常用于统计数据类型大小,如:int,double,char,float等等.但是它的统计通过一个实 验,让我有了不可思议的发现,平常我们可以用sizeof(int)来测试,int类型占用内存是不是4个byte. 对于统计字符串,感觉上是没有统计最后的'\0';事实验证确实没有统计如: char zifu[] = {W,e,i,x,i,a,n,g,f,e,i} 利用sizeof(zifu)或sizeof zifu统计第一个字符直到最后一个字符占用的总大小,具体的解释是: