sizeof()的作用,sizeof表示什么,sizeof()的简单介绍

sizeof()的作用,sizeof表示什么,sizeof()的简单介绍

zeof运算符以字节为单位给出其操作数的存储大小。

(1)基本概念

zeof运算符以字节为单位给出其操作数的存储大小。操作数可以是用括号括起来的表达式或类型名。操作数的存储大小由操作数的类型决定。

(2)使用方法

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在结构中的应用

请看下面的结构:复制代码如下:struct MyStruct { double doubchar chint I;};将sizeof用于结构MyStruct时会发生什么?sizeof(MyStruct)是什么?也许你会这样问:

sizeof(my struct)=sizeof(double)sizeof(char)sizeof(int)=13

以下是测试代码:复制代码如下:# includingnamespace STDstruct MyStruct { double doubchar chint I;};

int main(){ my struct ms;cout sizeof(ms)endl;返回0;}测试结果:

但是在VC中测试上述结构的大小时,你会发现sizeof(ms)是16。其实这是VC对变量存储的特殊处理。为了提高CPU的存储速度,VC对齐了一些变量的起始地址。默认情况下,VC规定每个成员变量的起始地址相对于结构起始地址的偏移量必须是变量类型所占用字节数的倍数。

常见类型的对齐

类型

对齐(变量起始地址相对于结构起始地址的偏移量)

偏移量必须是sizeof(char),它是1的倍数。

(同Internationalorganizations)国际组织

偏移量必须是sizeof(int),它是4的倍数。

两倍

偏移量必须是sizeof(double),它是8的倍数。

短的

偏移量必须是sizeof(short),它是2的倍数。

漂浮物

偏移量必须是sizeof(float),它是4的倍数。

每个成员变量在存储的时候,按照它在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整自己的位置,空出来的字节VC会自动填充。同时,为了保证结构的大小是结构字节边界数(即在结构中占用空间最大的类型所占用的字节数)的倍数,VC在为最后一个成员变量申请空间后,会根据需要自动填充空出的字节。复制代码如下:struct MyStruct

{

双doub

char ch

int I;

};在为上述结构分配空间时,VC根据成员变量的顺序和对齐方式为第一个成员doub分配空间,其起始地址与结构相同(刚好offset 0是sizeof(double)的倍数),成员变量占用sizeof(double)=8字节;接下来,为第二成员ch分配空间。此时,下一个可赋值地址到结构起始地址的偏移量为8,是sizeof(char)的倍数。因此,在偏移量8处存储ch满足对齐,成员变量占用sizeof(char)=1个字节。接下来为第三个成员I分配空间,此时下一个可赋值地址到结构体起始地址的偏移量为9,不是sizeof(int)=4的倍数。为了满足对齐对偏移量的约束,VC自动填充3个字节(这3个字节没什么可放的),下一个可赋值地址到结构起始地址的偏移量是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 ch双doubint I;};VC环境下,sizeof(MyStruct)为24。结合上面提到的一些空间分配原则,分析VC是如何为上面的结构分配空间的:

复制代码如下:struct MyStruct

{

char ch//偏移量为0,满足对齐。ch占用1个字节;

双doub//下一个可用地址的偏移量是1,而不是sizeof(double)=8

//的倍数,需要7个字节来使偏移量为8(满足对齐

//mode),所以VC自动填充7个字节,doub存储在偏移量8处

//在地址处,占用8个字节。

int I;//下一个可用地址的偏移量是16,是sizeof(int)=4的两倍。

//number,满足int的对齐,所以不需要VC自动填充,我保存。

//放在偏移量为16的地址,占用4个字节。

};//所有成员变量都分配了空间,空间总大小为1 7 8 4=20,不是结构。

//节边界的数量(即在sizeof结构中占据最大空间的类型所占据的字节数)

//(double)=8),因此需要填充4个字节来满足结构的大小

///sizeof(double)=8)=8的倍数。因此,结构的总大小为:sizeof(MyStruct)为1 7 8 4 4=24。总共7 ^ 4=11字节由VC自动填充,不放任何有意义的东西。

VC结构存储的特殊处理确实提高了CPU存储变量的速度,但有时也会带来一些麻烦。我们还屏蔽了变量的默认对齐方式,可以自己设置变量的对齐方式。

#pragma pack(n)是在VC中提供的,用来设置要与n个字节对齐的变量。n字节对齐是指变量起始地址的偏移量分两种情况:一是如果n大于等于变量占用的字节数,偏移量必须满足默认对齐;第二,如果n小于变量的类型所占用的字节数,则偏移量是n的倍数,因此不需要满足默认对齐。对结构的总大小也有约束,分为以下两种情况:如果n大于所有成员变量类型占用的字节数,那么结构的总大小必须是空间最大的变量所占空间的倍数;否则一定是n的倍数。

下面是它的用法示例:

复制代码如下:#pragma pack(push) //保存对齐状态#pragma pack(4) //设置为4字节对齐结构MyStruct { char ch双doubint I;};#pragma pack(pop) //恢复对齐状态的测试结果:

(sizeof用法总结

1.参数是数据类型或通用变量。

如sizeof(int)、sizeof(long)等。在这种情况下,需要注意的是,不同的系统或编译器得到的结果可能是不同的。例如,int类型在16位系统中占用2个字节,在32位系统中占用4个字节。

2.参数是数组或指针。

这里有一个例子。

复制代码如下:int a[50];//sizeof(a)=4 * 50=200;找出数组所占的空间。

int * a=new int[50];//sizeof(a)=4;a是指针,sizeof(a)是指针的大小。当然,在32位系统中,它占用4个字节。3.参数是其他的。

复制代码如下:int func(char s[5]){ return 1;//当函数的参数被传递时,系统将其视为指针,所以sizeof(s)实际上是在求指针的大小。} sizeof(func( 1234 );//因为func的返回类型是int,所以相当于找sizeof(int),它的值是4。

sizeof()的作用,sizeof表示什么,sizeof()的简单介绍