解题-offsetof 宏的模拟实现

文章目录

前言

一、了解offsetof 

二、模拟实现

总结


前言

路漫漫其修远兮,吾将上下而求索;


一、了解offsetof 

  • offsetof
  • 功能:计算结构体变量中其成员相对于其首地址的偏移量;
  • offsetof(type , member);
  • 所要引用的头文件:<stddef.h>
  • 其第一个宏参为type, 即为该结构体变量的类型;第二个宏参为member ,意思为所要计算的结构体成员的名字;
  • 返回类型:size_t

注:offsetof 为宏,不为函数;因为函数的参数一定不会是类型;

我们先画出结构体变量s 在内存总的布局,如下图:

  • 由上图可知,成员a 的偏移量为0 , 成员 i 的偏移量为4 ,成员c 的偏移量为 8;

看图容易理解,但是若想要通过计算得到偏移量该如何做呢?

  • 如果起始位置的地址为0的话,此时取出成员a 的地址便是其偏移量,同理取出成员i 、成员c 的地址对应的也是其偏移量;即当起始地址为0的时候,相应地取出其地址便是得到了其偏移量;

那么如何让结构体变量的其实地址为0呢?

  • 0这个地址的空间是不可以进行访问的,但是并不代表不可以使用这个地址;只要将地址0进行强制类型转换成该结构体变量类型的地址;

当我们拥有一个结构体变量的地址,便可以利用这个地址找到它的成员;

二、模拟实现

模拟实现的代码如下:

#include<stdio.h>

struct S
{
	char a;
	int i;
	char c;
};

#define OFFSETOF(type,member_name) (size_t)(&(((type*)0)->member_name))

int main()
{
	struct S s;
	printf("%zd\n", OFFSETOF(struct S, a));
	printf("%zd\n", OFFSETOF(struct S, i));
	printf("%zd\n", OFFSETOF(struct S, c));

	return 0;
}

代码执行结果如下:

注:

#define 定义了一个宏OFFSETOF ,其宏参有两个,分别为 type 、member_name ,宏体为(size_t)(&(((type*)0)->member_name)) 

宏体的解析:

type 为结构体类型,member_name 为成员名

第一步,将结构体变量的首地址改为0  : (type*)0

第二步,利用结构体变量的地址找到其成员,会利用到箭头操作符 ->  : ((type*)0)->member_name

第三步,该成员的地址便为其偏移量 : &(((type*)0)->member_name)

第四步,宏offsetof 的返回值为 size_t  : (size_t)( &(((type*)0)->member_name))


总结

offsetof 不是函数,是宏

0地址处的空间只要不去访问它,是可以使用的;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值