📜  实施自己的sizeof(1)

📅  最后修改于: 2023-12-03 15:39:08.225000             🧑  作者: Mango

实施自己的sizeof

在C语言中,sizeof是一个非常重要的操作符,它可以返回一个类型或变量的大小(以字节为单位)。在编程过程中,我们经常需要知道变量或类型的大小以便正确地分配内存空间。C语言提供了一个sizeof操作符,可以非常方便地获取类型或变量的大小。

但是,有时候sizeof无法满足我们的需求。比如,当我们需要获取一个结构体中所有成员变量的大小之和,sizeof就无法直接得到这个值。如果你使用sizeof来获取结构体的大小,只会得到结构体中每个成员变量的大小之和,并不包括结构体的内存对齐和填充。

针对这种情况,我们可以自己实现一个类似于sizeof的功能。下面是一个示例代码:

C语言实现
#include <stdio.h>
#include <stddef.h>

#define my_sizeof(type) ((size_t)(&((type *)0)->end))

struct MyStruct {
    int a;
    double b;
    char end;
};

int main() {
    printf("Size of MyStruct: %zu\n", sizeof(struct MyStruct));
    printf("Size of MyStruct using my_sizeof: %zu\n", my_sizeof(struct MyStruct));
    return 0;
}

在上面的代码中,我们使用了一个叫做offsetof的宏。它的作用是获取一个结构体成员变量相对于结构体首地址的偏移量。由于0的地址就是一块内存的开始地址,所以我们把结构体类型强制转换为指向0的指针,然后获取最后一个成员变量的偏移量。这样,我们就可以得到整个结构体的大小。

C++语言实现

在C++语言中,我们可以使用模板元编程来实现类似于sizeof的功能。下面是一个示例代码:

#include <iostream>

template <typename T>
struct MySizeof {
    static const size_t size = sizeof(T);
};

template <typename T>
struct MySizeof<T[]> {
    static const size_t size = 0;
};

template <typename T, size_t N>
struct MySizeof<T[N]> {
    static const size_t size = sizeof(T) * N;
};

struct MyStruct {
    int a;
    double b;
    char end;
};

int main() {
    std::cout << "Size of MyStruct: " << sizeof(MyStruct) << std::endl;
    std::cout << "Size of MyStruct using MySizeof: " << MySizeof<MyStruct>::size << std::endl;
    std::cout << "Size of int[10]: " << MySizeof<int[10]>::size << std::endl;
    std::cout << "Size of double[]: " << MySizeof<double[]>::size << std::endl;
    return 0;
}

在上面的代码中,我们定义了一个MySizeof模板结构体,它根据不同的数据类型(包括数组类型)返回不同的大小。对于非数组类型,我们直接返回sizeof的结果;对于数组类型,我们计算出数组元素的大小并乘以数组长度,最终得到数组的大小。

总的来说,自己实现sizeof操作符可以帮助我们更好地理解C/C++中内存的分配和对齐规则。同时,这也是一个很好的练习。