当前位置: 首页 > news >正文

offsetof宏的实现

题目:写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明
注:这个题目主要是在考察offsetof宏的实现

1.offsetof函数的定义

#include <stddef.h>  
size_t offsetof(type, member);

但请注意,实际上offsetof是一个宏,而不是一个函数
它接受两个参数:一个结构体类型和一个该类型中的成员名称,并返回该成员在结构体中的字节偏移量
使用举例:

#include <stddef.h>
#include<stdio.h>
struct S 
{double a;int b;char c;
};int main()
{printf("S 结构中的 a 偏移 = %d 字节。\n", (int)offsetof(struct S,a));//0printf("S 结构中的 b 偏移 = %d 字节。\n", (int)offsetof(struct S,b));//8printf("S 结构中的 c 偏移 = %d 字节。\n", (int)offsetof(struct S,c));//12
}

2.offsetof的模拟实现

我们假设结构体起始地址是0,则其成员的地址取出来再强制类型转换为int便可以表示结构体中某个成员相对于起始位置的偏移量

StructType是结构体类型名,MemberName是成员名。具体操作方法是:

  1. 先将0转换为一个结构体类型的指针,相当于某个结构体的首地址是0。此时,每一个成员的偏移量就成了相对0的偏移量,这样就不需要减去首地址了。这只是一个计算技巧,我们并没有真正去访问地址0的内存(否则会导致程序崩溃)
  2. 对该指针用->访问其成员,并取出地址,由于结构体起始地址为0,此时成员偏移量直接相当于对0的偏移量,所以得到的值直接就是对首地址的偏移量
  3. 取出该成员的地址,强转成size_t并打印,就求出了这个偏移量
#define OFFSETOF(StructType, MemberName) (size_t)&(((StructType *)0)->MemberName)// (StructType *)0  *用于将数字0强制转换成一个指向StructType结构体类型的指针
struct StructType
{int a;char c;double d;
};
int main()
{printf("%d\n", OFFSETOF(struct StructType, a));printf("%d\n", OFFSETOF(struct StructType, c));printf("%d\n", OFFSETOF(struct StructType, d));return 0;
}

注意:这里有一个关键点在于,C编译器在编译时就知道结构体内每个成员的精确偏移量,而OFFSEROF宏只是利用编译器的这个知识来获取偏移量数值,并不真正访问内存
这个过程不会影响真实内存
因为这个过程完全发生再编译阶段,而不是运行时:
4. 编译器在编译时就知道结构体的内存布局
5. 当看到这个表达式时,编译器直接计算偏移量数值
6. 最终生成的代码中不包含任何实际访问地址0的操作
7. 结果是一个编译时常量,直接嵌入到最终的可执行文件中

类比理解,可以把其想象成:
8. 你有一张建筑蓝图(结构体定义)
9. 你想知道某个房间距离大楼入口有多远(成员偏移量)
10. 你说:“假设大楼入口在坐标0点,那么房间的坐标就是它距离入口的偏移量”
11. 你不需要真正建造这栋大楼就能计算出这个距离

http://www.xdnf.cn/news/1402705.html

相关文章:

  • Cybero: 1靶场渗透
  • HarmonyOS 应用开发:基于API 12及以上的现代化实践
  • 华为对“业务对象”是怎样定义与应用的?
  • Windows系统提示“找不到文件‘javaw‘”
  • react虚拟列表实现及原理
  • Git与DevOps实战:从版本控制到自动化部署
  • docker 启动一个clickhouse , docker 创建ck数据库
  • 介绍分布式事务之Seata
  • 【系统分析师】高分论文:论系统测试技术及应用
  • IAR工程如何搭建vscode+clangd编辑环境
  • day42-Ansible
  • “人工智能+”行动重磅发布!ElfBoard助力嵌入式教育智能化升级
  • 【Java】常见数据结构及方法
  • EVidenceModeler v2.1 安装与使用--生信工具58
  • 嵌入式开发学习 C++:day02
  • mysql(自写)
  • 10. 函数和匿名函数(二)
  • 数值分析——误差的来源与分类、误差的基本概念(绝对误差、相对误差、有效数字)
  • 国标调查:引领汽车消费市场健康发展的理性指南
  • 奥普新汽车声学测试方案书
  • 基于单片机温控风扇ds18b20系统Proteus仿真(含全部资料)
  • 矿物类型分类实战:从数据预处理到多模型对比
  • 计算机体系结构之流水线与指令级并行
  • 离线大文件与断点续传:ABP + TUS + MinIO/S3
  • Android FrameWork - 开机启动 SystemServer 进程
  • Science:机器学习模型进行遗传变异外显率预测
  • 项目管理的关键成功因素
  • 全栈开源,高效赋能——启英泰伦新官网升级上线!
  • 链表(1)
  • 继电器的作用、选型和测量-超简单解读