模拟实现offsetof

写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明

考察: offsetof宏的实现

描述:

C 库宏 offsetof(type, member-designator) 会生成一个类型为 size_t 的整型常量,它是一个结构成员相对于结构开头的字节偏移量。成员是由 member-designator 给定的,结构的名称是在 type 中给定的。 

声明:

下面是 offsetof() 宏的声明。

offsetof(type, member-designator)

参数说明: 

  • type -- 这是一个 class 类型,其中,member-designator 是一个有效的成员指示器。
  • member-designator -- 这是一个 class 类型的成员指示器。

返回值: 

该宏返回类型为 size_t 的值,表示 type 中成员的偏移量。

 实例:

#include <stddef.h>
#include<stdio.h>
struct S 
{
	char c1;
	int i;
	char c2;
};

int main()
{
	printf("S 结构中的 c1 偏移 = %d 字节。\n", (int)offsetof(struct S,c1));
	printf("S 结构中的 i  偏移 = %d 字节。\n", (int)offsetof(struct S,i));
	printf("S 结构中的 c2 偏移 = %d 字节。\n", (int)offsetof(struct S,c2));
}

模拟实现:

具体代码实现:

#define offsetof(TYPE,MEMBER) (size_t)(&((TYPE *)0) -> MEMBER)

struct S
{
	int a;
	float f;
	char c;
	short sh;
};

int main()
{
	printf("S 结构中的 a 偏移 = %d 字节。\n", offsetof(struct S,a));
	printf("S 结构中的 f 偏移 = %d 字节。\n", offsetof(struct S,f));
	printf("S 结构中的 c 偏移 = %d 字节。\n", offsetof(struct S,c));
	printf("S 结构中的 sh 偏移 = %d 字节。\n", offsetof(struct S,sh));
	return 0;
}

1. (type *)0,可以理解为把 0 地址强制转换为 type 结构体类型的指针,此时 0 就成了 type 结构体的首地址,指向该结构体,既然为结构体指针,那么自然可以引用该结构体的成员,所以 (type *)0)->member 的整体意义就是引用 type 结构体的成员 member。

2. &(type *)0)->member) 便是取该结构体成员 member 的地址。而结构体起始地址为 0 时,结构体成员的地址为多少,其相对于结构体的偏移量就为多少。所以此时结构体类型成员的地址就是该成员相对结构体起始地址的偏移量。

3. 经过上面的分析之后,这段代码的逻辑就很简单了,通过 &((TYPE *)0)->MEMBER) 先取 TYPE 结构体类型成员的地址,强制转换成 size_t 类型后返回结构体类型成员的地址。又因为结构体起始地址为 0 时,结构体成员的地址就是偏移量,所以最后 offsetof 便返回结构体中某个成员相对于结构体起始地址的偏移量。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值