sizeof
作用:
- 查询对象或者类型的大小
- 在需要知道对象的实际大小时使用
语法:
sizeof( 类型 )
sizeof 表达式
注解:
- 结果取决于计算机架构
- 不能对函数类型、不完整类型或位域泛左值使用 sizeof。
- 当应用于引用类型时,其结果是被引用类型的大小。
- 当应用于类类型时,其结果是该类的对象的大小加上这种对象放入数组时所需的额外填充的大小的和
- sizeof 的结果始终非零,即使应用于空类。
- 当应用于某个表达式时,sizeof 并不对表达式进行求值,并且即便表达式代表多态对象,其结果也是该表达式的静态类型的大小。不进行左值向右值、数组向指针和函数向指针转换。不过,它在形式上对纯右值实参进行临时量实质化:sizeof 确定其结果对象的大小。 (C++17 起)
- 下列 sizeof 表达式总是求值为 1:
sizeof(char) sizeof(signed char) sizeof(unsigned char) sizeof(std::byte) //(C++17 起) sizeof(char8_t) // (C++20 起)
示例:
sizeof运算符返回表达式或者类型所占内存空间的字节数。它返回一个size_t类型的常量表达式。
假设有下面的结构体:
struct Point3d{
int x;
int y;
int z;
};
可以这样进行初始化:
Point3d pt;
memset(&pt, 0, sizeof(pt));
也可以这样初始化:
Point3d pt1;
memset(&pt1, 0, sizeof(Point3d));
也可以批量初始化:
Point3d ptarray[100];
memset(ptarray, 0, sizeof(ptarray));
许多和内存操作相关的处理都需要知道数据或类型占用内存空间的大小。这时就可以使用sizeof运算符。sizeof计算的对象可以是数据,也可以是类型。
有一点需要注意的是,如果运算的对象是指针,那么取得的就只能是指针本身的大小而不是指针指向数据的大小。例如下面的代码就不能初始化所有的x数组元素。
int x[10];
int *p = x;
memset(p, 0, sizeof(p)/sizeof(*p));
示例:
假设有如下结构体:
struct Image{
int width;
int height;
char data[10000];
};
可以这样初始化data成员:
Image image1;
memset(image1.data, 0, sizeof(iamge1.data));
C++11以后,也可以这样初始化:
Image image1;
memset(image1.data, 0, sizeof(Image::data));
注意sizeof的的参数,可以不通过对象,直接使用作用域运算符来获取成员的大小。
示例:
#include <iostream>
struct Empty {};
struct Base { int a; };
struct Derived : Base { int b; };
struct Bit { unsigned bit: 1; };
int main()
{
Empty e;
Base t;
Derived d;
Base& b = d;
[[maybe_unused]] Bit bit;
int a[10];
std::cout << "空类的大小: " << sizeof e << "\n" // 1
<< "指针的大小: " << sizeof &e << "\n" // 8
// ----- 不能对函数类型、不完整类型或位域泛左值使用 sizeof。 -------
// << "函数的大小: " << sizeof(void()) << "\n" // 错误
// << "不完整类型的大小: " << sizeof(int[]) << "\n" // 错误
// << "位域的大小: " << sizeof bit.bit << "\n" // 错误
<< "Bit 类的大小: " << sizeof(Bit) << '\n' // 4
<< "含有10个 int 的数组的大小: " << sizeof(int[10]) << "\n" // 4 * 10
<< "含有10个 int 的数组的大小 (2):" << sizeof a << "\n"
<< "含有10个 int 的数组的长度: " << ((sizeof a) / (sizeof *a)) << "\n"
<< "含有10个 int 的数组的长度 (2):" << ((sizeof a) / (sizeof a[0])) << "\n"
<< "Base 的大小: " << sizeof t << "\n" // 4 ---》int
<< "Derived 的大小: " << sizeof d << "\n"
<< "通过 Base 获取 Derived 的大小:" << sizeof b << "\n";
}
sizeof与strlen的区别
- sizeof是一个运算符,strlen是库函数
- sizeof的参数可以是数据的类型、也可以是变量;而strlen只能以结尾为
\0
的字符串作为参数 - 编译器在编译时就计算出了sizeof的结构,而strlen函数必须在运行时才能计算出来。
- sizeof计算的是数据类型占内存的大小,而strlen计算的是字符串实际的长度
- 数组做sizeof的参数不退化,传递给strlen就退化为指针了