【C语言刷题】模拟实现offsetof宏

本篇文章目录

  • 1. 宏offsetof的作用
  • 2. 分析该如何模拟实现
  • 3.模拟实现

1. 宏offsetof的作用

在www.cplusplus.com中对offsetof宏的功能描述:
【C语言刷题】模拟实现offsetof宏_第1张图片

这个宏的作用就是传入一个结构体类型和一个成员名,返回这个成员相对比这个结构体起始位置的偏移量(字节数),如果不懂的话可以看这篇文章:计算结构体的大小!结构体内存对齐的意义是什么?。

2. 分析该如何模拟实现

有这么一个结构体:

struct Test {
	char c;
	int a;
	char* str;
};

根据结构体的内存对齐规则,得出它的大小与成员的内存布局如下(假设机器是64位平台):
【C语言刷题】模拟实现offsetof宏_第2张图片
那么如何得到c、a或str相对于起始位置的偏移量呢?其实非常简单,比如想要得到c的偏移量,用c、a或str的地址减去这个结构体的起始位置,得到的就是中间相差的字节数,这个字节数也就相当于相对于起始位置的偏移量了。
【C语言刷题】模拟实现offsetof宏_第3张图片

3.模拟实现

#include 
#include  

// 模拟实现offsetof宏
#define OFFSETOF(type, member) (size_t)(&(((type*)0)->member))

struct Test {
	char c;
	int a;
	char* str;
};

int main() {
	printf("%zd ", offsetof(struct Test, c));
	printf("%zd ", offsetof(struct Test, a));
	printf("%zd\n", offsetof(struct Test, str));
	
	printf("%zd ", OFFSETOF(struct Test, c));
	printf("%zd ", OFFSETOF(struct Test, a));
	printf("%zd\n", OFFSETOF(struct Test, str));
	return 0;
}

运行结果对比:
【C语言刷题】模拟实现offsetof宏_第4张图片

&(((type*)0)->member)我认为在0的位置处有一个type*的结构体,然后将它的成员地址取出,这个成员的起始地址就是相对于结构体起始位置的偏移量了,因为结构体的起始位置我认为是0,成员地址减去0的地址等于不用减。一般而言,0这种地址是不能使用的,但我这里并没有解引用,只是看看但不用是没有问题的。

你可能感兴趣的:(刷题,C语言,c语言)