• C++
  • C++ 中 `sizeof` 运算符的通俗易懂教程

  • @ 2025-3-26 21:55:13

以下是关于 C++ 中 sizeof 运算符的通俗易懂教程:

1. 什么是 sizeof

sizeof 是 C++ 的一个运算符,用于计算数据类型、变量或表达式在内存中占用的字节数。
它的作用类似于“量尺”,可以测量数据占据的内存空间。

2. 基本语法

sizeof(数据类型/变量/表达式)
  • 可以省略括号(仅对类型有效):sizeof int
  • 对变量或表达式必须加括号:sizeof(a)

3. 常见用法示例

(1)数据类型的大小

cout << sizeof(int) << endl;    // 输出:4(通常)
cout << sizeof(double) << endl; // 输出:8
cout << sizeof(char) << endl;   // 输出:1

(2)变量的大小

int a = 10;
cout << sizeof(a) << endl; // 输出:4(与 int 类型大小一致)

(3)数组的大小

int arr[] = {1, 2, 3};
cout << sizeof(arr) << endl; // 输出:12(3个int,每个4字节)

(4)结构体的大小

struct Person {
    int age;    // 4字节
    char name;  // 1字节
    double score; // 8字节
};
cout << sizeof(Person) << endl; // 输出:16(存在内存对齐)

4. 注意事项

(1)数组与指针的区别

int arr[] = {1, 2, 3};
int* ptr = arr;

cout << sizeof(arr) << endl; // 输出:12(整个数组的大小)
cout << sizeof(ptr) << endl; // 输出:8(指针本身的大小,与平台有关)

(2)类的大小

  • 空类默认占 1 字节(用于区分实例)。
  • 包含成员变量的类按成员总大小计算(考虑内存对齐)。
  • 成员函数不占用类的内存。
class Empty {};
class Student {
    int id;       // 4字节
    char gender;  // 1字节
};
cout << sizeof(Empty) << endl;    // 输出:1
cout << sizeof(Student) << endl;  // 输出:8(4+1=5,对齐到8)

(3)字符串与 strlen 的区别

char str[] = "abc";
cout << sizeof(str) << endl; // 输出:4(包含终止符 '\0')
cout << strlen(str) << endl; // 输出:3(不包含终止符)

5. 常见误区

  1. sizeof 是运算符,不是函数
    可以直接对类型使用:sizeof int

  2. 结果在编译时确定
    sizeof 的结果在编译阶段就已知,与运行时数据无关。

  3. 指针的大小与类型无关
    int*char*double*sizeof 结果相同(取决于平台)。

6. 实际应用场景

  • 计算数组元素个数
    int arr[] = {1,2,3}; int len = sizeof(arr)/sizeof(arr[0]);
  • 内存分配
    char* buffer = new char[sizeof(Person)];
  • 调试与优化
    检查结构体的内存对齐是否合理。

7. 平台差异

  • 不同编译器或操作系统下,sizeof(int) 可能是 4 或 2 字节。
  • 64 位系统中指针大小为 8 字节,32 位系统为 4 字节。

通过以上示例和说明,你可以快速掌握 sizeof 的基本用法和常见注意事项。如果有具体问题,可以随时提问!

3 条评论

  • @ 2025-5-4 12:08:15
    struct Person {
        int age;    // 4字节
        char name;  // 1字节
        double score; // 8字节
    };
    cout << sizeof(Person) << endl; // 输出:16(存在内存对齐)
    

    你提供的代码主要是在探究结构体 Person 的内存占用情况。在 C++ 里,结构体的大小并非简单地等于其各个成员大小之和,这是因为存在内存对齐机制。

    内存对齐的作用

    内存对齐的目的在于提升内存访问效率。计算机在访问内存时,通常是按照特定的字节边界进行的。若数据存储在符合其自身大小的边界上,就能更快地被访问。

    代码分析

    struct Person {
        int age;    // 4字节
        char name;  // 1字节
        double score; // 8字节
    };
    
    • int age:占据 4 个字节。
    • char name:占据 1 个字节。
    • double score:占据 8 个字节。

    内存对齐规则

    • 每个成员的起始地址必须是该成员大小的整数倍。
    • 结构体的总大小必须是其最大成员大小的整数倍。

    具体分析

    1. int age 从偏移量 0 开始,占用 4 个字节(偏移量 0 - 3)。
    2. char name 从偏移量 4 开始,占用 1 个字节(偏移量 4)。
    3. double score 要求起始地址是 8 的整数倍,所以它的起始偏移量为 8,因此在 char name 之后会填充 3 个字节(偏移量 5 - 7),double score 占用 8 个字节(偏移量 8 - 15)。

    结构体总大小

    综合以上分析,结构体 Person 的总大小为 16 字节。

    代码验证

    #include <iostream>
    struct Person {
        int age;    // 4字节
        char name;  // 1字节
        double score; // 8字节
    };
    
    int main() {
        std::cout << sizeof(Person) << std::endl;
        return 0;
    }
    

    运行上述代码,输出结果会是 16。

    总结

    由于内存对齐的影响,结构体 Person 的总大小为 16 字节,而非各成员大小之和 13 字节。

    • @ 2025-5-4 12:05:55
      #include<iostream>
      using namespace std;
      int main() {
      	//cout<<"你\0好"<<endl;
      	//cout << sizeof("你") << endl;   // 输出:3
      	//2 + 1('\0')字符串结束标志符
      	//cout << sizeof("abc") << endl; //4
      	int arr[] = {1,2,3};// cout<<sizeof(arr)<<endl;
      	
      	int len = sizeof(arr)/sizeof(arr[0]);
      	cout<<len<<endl;
      	return 0;
      }
      
      • @ 2025-5-4 12:00:03
        #include<iostream>
        using namespace std;
        int main() {
        	cout<<"你\0好"<<endl;
        	cout << sizeof("你") << endl;   // 输出:3
        	//2 + 1('\0')字符串结束标志符
        	cout << sizeof("abc") << endl; //4
        	return 0;
        }
        
        • 1