在 C++ 中,sizeof 是一个编译时运算符,以下是 sizeof 的详细用法及关键注意事项。

在 C++ 中,sizeof 是一个编译时运算符,用于计算对象或类型占用的内存大小(以字节为单位)。它既可用于基本类型、数组、结构体,也可用于类和指针。以下是 sizeof 的详细用法及关键注意事项:


一、sizeof 的基本用法

语法

cpp

复制

sizeof(类型)     // 直接指定类型
sizeof(表达式)   // 根据表达式结果类型计算
示例 1:基本类型

cpp

复制

cout << sizeof(int) << endl;    // 输出 4(常见平台)
cout << sizeof(double) << endl; // 输出 8
示例 2:变量或对象

cpp

复制

int x = 10;
double arr[5];
cout << sizeof(x) << endl;     // 输出 4(等价于 sizeof(int))
cout << sizeof(arr) << endl;   // 输出 5 * 8 = 40

二、sizeof 在数组中的应用

1. 静态数组的大小计算

cpp

复制

int arr[10];
cout << sizeof(arr) << endl;       // 输出 10 * 4 = 40(总字节数)
cout << sizeof(arr) / sizeof(int) << endl; // 输出 10(数组元素个数)
2. 陷阱:数组作为函数参数传递

当数组传递给函数时,会退化为指针,sizeof 无法正确计算数组大小:

cpp

复制

void func(int arr[]) {
    cout << sizeof(arr) << endl; // 输出指针大小(如 8,而非数组大小)
}

int main() {
    int arr[5];
    func(arr); 
    return 0;
}
3. 多维数组

cpp

复制

int matrix[3][4];
cout << sizeof(matrix) << endl;          // 3 * 4 * 4 = 48
cout << sizeof(matrix[0]) / sizeof(int) << endl; // 输出 4(第二维长度)

三、sizeof 与指针的陷阱

1. 指针与数组的区别

cpp

复制

int arr[5];
int* p = arr;

cout << sizeof(arr) << endl; // 输出 20(5 * 4)
cout << sizeof(p) << endl;   // 输出 8(指针变量的大小,与指向内容无关)
2. 动态分配的内存

sizeof 无法计算动态分配内存的大小:

cpp

复制

int* dynamicArr = new int[100];
cout << sizeof(dynamicArr) << endl; // 输出 8(指针大小,而非数组大小)

四、sizeof 在结构体和类中的应用

1. 内存对齐的影响

结构体/类的大小可能因内存对齐规则而大于成员大小的总和:

cpp

复制

struct Example {
    char c;     // 1 字节(对齐到 4 字节边界)
    int i;      // 4 字节
};
cout << sizeof(Example) << endl; // 输出 8(1 + 3填充 + 4)
2. 空类和虚函数

cpp

复制

class Empty {}; 
cout << sizeof(Empty) << endl; // 输出 1(空类占位)

class Base { virtual void func() {} };
cout << sizeof(Base) << endl;  // 输出 8(虚表指针大小,64位系统)

五、sizeof 的高级用法

1. 与 decltype 结合

cpp

复制

int x = 10;
cout << sizeof(decltype(x)) << endl; // 输出 4(等价于 sizeof(int))
2. 编译时计算

sizeof 在编译时求值,可用于模板元编程:

cpp

复制

template <typename T, size_t N>
void printSize(T (&arr)[N]) {
    cout << "数组大小:" << N << endl;
}

int arr[5];
printSize(arr); // 输出 "数组大小:5"

六、sizeof 与 strlen 的区别

场景sizeofstrlen
字符数组 char str[]计算总字节数(包括 \0计算字符串长度(直到 \0
动态字符串指针返回指针大小(如 8)需要有效 \0 结尾,否则未定义行为
示例

cpp

复制

char str[] = "Hello";
cout << sizeof(str) << endl;  // 输出 6('H','e','l','l','o','\0')
cout << strlen(str) << endl;  // 输出 5

七、总结:sizeof 的核心规则

  1. 编译时求值:结果在编译阶段确定,不执行表达式。

  2. 类型依赖:计算的是类型或对象的内存占用,而非逻辑内容。

  3. 数组退化:数组作为函数参数时会退化为指针,sizeof 失效。

  4. 内存对齐:结构体/类的大小受内存对齐规则影响。

  5. 替代方案:动态数组建议使用 std::vector 或 std::array


示例代码

cpp

复制

#include <iostream>
using namespace std;

int main() {
    // 静态数组
    int arr[5] = {1, 2, 3, 4, 5};
    cout << "数组总字节数:" << sizeof(arr) << endl;          // 输出 20
    cout << "数组元素个数:" << sizeof(arr)/sizeof(int) << endl; // 输出 5

    // 指针陷阱
    int* p = arr;
    cout << "指针大小:" << sizeof(p) << endl; // 输出 8(64位系统)

    // 结构体内存对齐
    struct Data { char c; int i; };
    cout << "结构体大小:" << sizeof(Data) << endl; // 输出 8

    return 0;
}

合理使用 sizeof 可以避免内存错误,但需时刻注意其限制和陷阱!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值