sizeof是C/C++中的一个操作符(operator)是也,简单的说其作
用就是返回一个对象或者类型所占的内存字节数。
用就是返回一个对象或者类型所占的内存字节数。
1. sizeof 基本数据类型
这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型,由于它们都是和系统相关的,所以在不同的系统下取值可能不同,这务必引起我们的注意。但是,这同编译器也有关系。
如果编译器定义 int 等价 short int,
sizeof(int) 就是2 -- TC 如此
如果编译器定义 int 不等价 short int,
sizeof(int) 就是4 -- VC++ 如此
这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型,由于它们都是和系统相关的,所以在不同的系统下取值可能不同,这务必引起我们的注意。但是,这同编译器也有关系。
如果编译器定义 int 等价 short int,
sizeof(int) 就是2 -- TC 如此
如果编译器定义 int 不等价 short int,
sizeof(int) 就是4 -- VC++ 如此
2. sizeof 指针变量
在32位计算机中,一个指针变量的sizeof结果通常是4(注意结果是以字节为单位),在64位系统中指针变量的sizeof结果通常为8,此外指针变量的sizeof值与指针所指的对象没有任何关系。
3. sizeof 数组
数组的sizeof值等于数组所占用的内存字节数。
在32位计算机中,一个指针变量的sizeof结果通常是4(注意结果是以字节为单位),在64位系统中指针变量的sizeof结果通常为8,此外指针变量的sizeof值与指针所指的对象没有任何关系。
3. sizeof 数组
数组的sizeof值等于数组所占用的内存字节数。
4. sizeof 结构体
编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能需要加入填充字节,所以结构体的sizeof值就不是简单的成员的sizeof相加了。
编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能需要加入填充字节,所以结构体的sizeof值就不是简单的成员的sizeof相加了。
字节对齐的细节和编译器实现相关,一般满足以下三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
说明:
(1)这里所说的“数据宽度”就是指其sizeof的大小。由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。
(2)有一个影响sizeof的重要参量还未被提及,那便是编译器的pack指令。它是用来调整结构体对齐方式的,不同编译器名称和用法略有不同,VC6中通过#pragma pack实现,也可以直接修改/Zp编译开关。#pragma pack的基本用法为: #pragma pack( n ),n为字节对齐数,其取值为1、2、4、8、16,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准。
(3)“空结构体”(不含数据成员)的大小不为0,而是1。
说明:
(1)这里所说的“数据宽度”就是指其sizeof的大小。由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。
(2)有一个影响sizeof的重要参量还未被提及,那便是编译器的pack指令。它是用来调整结构体对齐方式的,不同编译器名称和用法略有不同,VC6中通过#pragma pack实现,也可以直接修改/Zp编译开关。#pragma pack的基本用法为: #pragma pack( n ),n为字节对齐数,其取值为1、2、4、8、16,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准。
(3)“空结构体”(不含数据成员)的大小不为0,而是1。
5. sizeof 联合体
结构体在内存组织上是顺序式的,联合体则是重叠式,各成员共享一段内存,所以整个联合体的sizeof也就是每个成员sizeof的最大值。
结构体在内存组织上是顺序式的,联合体则是重叠式,各成员共享一段内存,所以整个联合体的sizeof也就是每个成员sizeof的最大值。
6。sizeof 类
sizeof 类和结构差不多,但要注意的是:
1) 没有虚函数:sizeof 类的大小只针对数据成员而言
2) 有虚函数:sizeof类的大小针对数据成员和其中包含的虚表指针大小而言,在类中只包含一个虚表指针时和包含多个虚表指针时大小是不一样的,这应该高度重视。
sizeof 类和结构差不多,但要注意的是:
1) 没有虚函数:sizeof 类的大小只针对数据成员而言
2) 有虚函数:sizeof类的大小针对数据成员和其中包含的虚表指针大小而言,在类中只包含一个虚表指针时和包含多个虚表指针时大小是不一样的,这应该高度重视。