新手的学习之路—sizeof 的总结(1)

来源:互联网 发布:淘宝出售假冒违规处罚 编辑:程序博客网 时间:2024/06/08 00:44

以前对各种变量类型的存储字节总是模模糊糊,用到的时候才去网上查找。这次自己准备也做个总结,期间vs上验证用到sizeof,然后顺便总结了struct和class的情况。


(1)基本变量

 变量类型32编译器64编译器int44short22long44long long88float44double88char11bool11enum44指针44


可以看出,在win下32位和64位编译器基本变量存储字节的最大区别就是:指针


(2)数组

当对数组名使用sizeof时,其返回整个数组的大小;但作为指针传递进函数后,只是作为一个普通的指针,其大小为4,比如:

int a[3]={1,2,3};cout<<sizeof(a);//输出12cout<<size(a);//输出4//----------------------------------------------------int size(int *p){return sizeof(p);}

(3)struct

若结构体为空,其大小为1;

若不为空,结构体的存储比较复杂,并不是简单的字节相加,比如:

struct student{     char name;    intid;    double score;};

按照我们一般的想法结构体的字节数sizeof(student)=1+4+8=13,然而我们在代码中验证后就会发现sizeof(student)=16;这是为什么呢?:原来是因为内存存储的字节对齐 造成的。所谓的字节对齐是为了加快计算机的处理速度,我们一般把数据类型都放在能够被其字节大小整除的地址上。比如对于结构体student,假设此结构体的存储首地址pt能够被1和4,8整除(char ,int和double 的存储字节数),其实事实上计算机也是这样安排的,存储过程如下:

name占一个字节,直接存储

id如果直接存储,则id的存储地址(pt+1)不会被4整除,因此我们为了使字节对齐,就会在name后面填充3个字节然后存储id

score直接存储的地址可以被8整除,所以我们不用填充字节

总的字节数sizeof(student)=4+4+8=16;

为了总结出一般的规律,我们使用偏移量这个概念:结构体成员存储地址与结构体首地址的偏移字节数。计算结构体大小时,请按照以下准则:

1.各成员变量的偏移量必须为该成员大小的整数倍,如不够则在上一个变量后填充字节数

2.结构体的总大小必须为成员变量中最宽类型的整数倍,如不够则在最后的变量后填充字节数

例:

struct teacher{   char name;   short age;   double salary;   int id;};

name 偏移量为0,直接存储1个字节(已占用1个字节)

age 若直接存储偏移量为1,不是2的倍数,所以在name后面填充1个字节然后存储(已占用4个字节)

salary 若直接存储偏移量为4,不是8的倍数,所以age后面填充4个字节(已占用16个字节)

id 若直接存储偏移量为16,是4的倍数,所以直接存储(已占用20个字节)

20不是double(teacher结构体中最宽类型)字节的整数倍,所以填充4个字节使其成为整数倍。最后得出结构体的大小为24个字节


(4)结构体中包含复合类型

struct A{char v1;double  v2;};struct B{int  v1;A   v2;char v3;};

1.复合型变量的偏移量必须为  该变量中最宽数据类型大小 的整数倍;

2.先将复合型变量解散为基本变量,再寻找结构体中最宽的数据类型

上述例子中srtuct B:

v1偏移量为0,是4的整数倍,直接存储(已占用4个字节)

v2 若直接存储偏移量为4,不是8(v2中最宽数据类型double字节数)的整数倍,所以在v1后填充4个字节数然后存储(已占用24个字节)

v3  若直接存储偏移量为24,是1的整数倍,直接存储(已占用25个字节)

25不是double(B中最宽类型)字节的整数倍,所以填充7个字节使其成为整数倍。最后得出结构体的大小为32个字节

0 0
原创粉丝点击