理论

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

/*
* 参数: type -- 这是一个 class 类型,其中,member-designator 是一个有效的成员指示器。
*       member-designator -- 这是一个 class 类型的成员指示器。
* 返回值: 该宏返回类型为 size_t 的值,表示 type 中成员的偏移量
*/
offsetof(type, member-designator)

实践

#include <stddef.h>
#include <stdio.h>struct address {char name[50];char street[50];int phone;
};int main()
{printf("address 结构中的 name 偏移 = %d 字节。\n",offsetof(struct address, name));printf("address 结构中的 street 偏移 = %d 字节。\n",offsetof(struct address, street));printf("address 结构中的 phone 偏移 = %d 字节。\n",offsetof(struct address, phone));return(0);
}

#include <stddef.h>
#include <stdio.h>struct MBLOCK {size_t signature;size_t length;union {size_t align;char  payload[1]; /* actually a bunch of bytes */} u;
}MBLOCK;int main()
{printf("MBLOCK 结构中的 signature 偏移 = %lu 字节。\n",offsetof( struct MBLOCK, signature));  // 0printf("MBLOCK 结构中的 length 偏移 = %lu 字节。\n",offsetof(struct MBLOCK, length)); // 8printf("MBLOCK 结构中的 u 偏移 = %lu 字节。\n",offsetof(struct MBLOCK, u));  // 16printf("MBLOCK 结构中的 u.align 偏移 = %lu 字节。\n",offsetof(struct MBLOCK, u.align));  // 16printf("MBLOCK 结构中的 u.payload[0] 偏移 = %lu 字节。\n",offsetof(struct MBLOCK, u.payload[0])); // 16printf("MBLOCK 结构中的 u.payload[1] 偏移 = %lu 字节。\n",offsetof(struct MBLOCK, u.payload[1])); // 17printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",offsetof(struct MBLOCK, u.payload[2])); // 18printf("MBLOCK 结构中的 u.payload[12] 偏移 = %lu 字节。\n",offsetof(struct MBLOCK, u.payload[12])); // 28return(0);
}

offsetof作用是 相对于结构体开始的内存地址偏移了多少

当然,我们可以给结构体起一个别名,这样就不需要每次都创建一个结构体了(结果和上面是一样的)

#include <stddef.h>
#include <stdio.h>typedef  struct MBLOCK {size_t signature;size_t length;union {size_t align;char  payload[1];    /* actually a bunch of bytes */} u;
}MBLOCK;int main()
{printf("MBLOCK 结构中的 signature 偏移 = %lu 字节。\n",offsetof(  MBLOCK, signature));  // 0printf("MBLOCK 结构中的 length 偏移 = %lu 字节。\n",offsetof( MBLOCK, length)); // 8printf("MBLOCK 结构中的 u 偏移 = %lu 字节。\n",offsetof( MBLOCK, u));  // 16printf("MBLOCK 结构中的 u.align 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.align));  // 16printf("MBLOCK 结构中的 u.payload[0] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[0])); // 16printf("MBLOCK 结构中的 u.payload[1] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[1])); // 17printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[2])); // 18printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[12])); // 28return(0);
}
#include <stddef.h>
#include <stdio.h>typedef  struct MBLOCK {size_t signature;size_t length;union {size_t align;char  payload[1];    /* actually a bunch of bytes */} u;
}MBLOCK;int main()
{printf("MBLOCK 结构中的 signature 偏移 = %lu 字节。\n",offsetof(  MBLOCK, signature) + 4);printf("MBLOCK 结构中的 length 偏移 = %lu 字节。\n",offsetof( MBLOCK, length) + 100); // 108 ----> 它的意思是先找到offsetof( MBLOCK, length),然后在偏移100.不会影响原来的内存printf("MBLOCK 结构中的 u 偏移 = %lu 字节。\n",offsetof( MBLOCK, u));  // 16printf("MBLOCK 结构中的 u.align 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.align) );  // 16printf("MBLOCK 结构中的 u.payload[0] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[0])); // 16printf("MBLOCK 结构中的 u.payload[1] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[1])); // 17printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[2])); // 18printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",offsetof( MBLOCK, u.payload[12])); // 28return(0);
}


我们可以使用结果体来找到相对某个内存地址偏移多少

#include <stddef.h>
#include <stdio.h>typedef  struct MBLOCK {size_t signature;size_t length;union {size_t align;char  payload[1];    /* actually a bunch of bytes */} u;
}MBLOCK;#define SPACE_FOR(len)  (offsetof(MBLOCK, u.payload[0]) + len)
int main()
{printf("相对MBLOCK 结构中的 u.payload[0] 偏移 4字节  = %lu 字节。\n", SPACE_FOR(4));  // 20printf("相对MBLOCK 结构中的 u.payload[0] 偏移 84字节 = %lu 字节。\n", SPACE_FOR(84));  // 100printf("相对MBLOCK 结构中的 u.payload[0] 偏移 -16字节= %lu 字节。\n", SPACE_FOR(-16));return(0);
}

C/C++编程:宏offsetof()相关推荐

  1. 【C语言】宏offsetof的模拟实现 (计算结构体中某变量相对于首地址的偏移)

    首先我们应该特别留意 : offsetof 是一个宏,并非是一个函数 ! 宏offsetof的介绍 : 参数:第一个是结构体类型名称,第二个是结构体成员名 返回类型:size_t无符号整形 引用的头文 ...

  2. c语言 offsetof函数,C 库宏 - offsetof()函数

    宏offsetof 标准库stddef.h 定义 size_t offsetof(type, member); 分析 C 库宏 offsetof(type, member) 会生成一个类型为 size ...

  3. C库宏-offsetof()

    在项目开发过程中,发现了offsetof()函数,随即查询了此函数,摘录如下: C库宏 - offsetof() 描述 C库宏offsetof(type, member-designator)会生成一 ...

  4. pythonmainoffset_宏offsetof分析

    1.前言 在C语言的结构体中,由于字节对齐的问题,所以成员的地址并不能直接根据数据类型的大小进行计算,使用宏offsetof可以获得结构体成员相对于结构体首地址的字节偏移量. 2.offsetof宏实 ...

  5. C 语言编程 — 宏定义与预处理器指令

    目录 文章目录 目录 前文列表 宏 预处理器 预处理器指令 预处理器指令示例 预处理器指令运算符 宏定义 简单宏定义 带参数的宏定义 符号吞噬问题 使用 do{}while(0) 结构 预定义的宏 常 ...

  6. 对宏offsetof理解

    #ifndef offsetof #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER) #endif offset这个 ...

  7. C语言编程宏定义的优缺点,C语言重要知识点总结(二)--内存结构、函数调用过程(栈帧)、宏的优缺点以及##和#的使用...

    一.内存结构 内存大致可以分为四个部分:代码段,静态存储区,堆,栈. 具体划分如下图所示: 栈:在执行函数时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束后会自动释放内存.栈内存的分配运算 ...

  8. 实现宏offsetof()

    本期介绍

  9. 鼠标键盘 录制 可编程宏 /回放 工具 Macro Recorder 汉化 破解 优化

    经常需要操作一些简单重复的工作 比如 就需要一些工具来做这些重复的工作来减轻工作量 鼠标键盘录制回放工具 用过很多  都不太理想 (Mouse Recorder 没有相应热键, 速度可调)(Pulov ...

最新文章

  1. 【转】【Mysql学习】之Mac上用终端使用mySQL
  2. linux nfs 配置_centos7 NFS 配置
  3. windows server 2012服务器IIS基本配置
  4. JAVA中CLASS.FORNAME的含义
  5. Scrapy读取设置文件(settings.py)
  6. iPhone 6S GPU到底多强
  7. luoguP3281 [SCOI2013]数数
  8. Linux 正在吞噬 Windows 和 Chrome OS!
  9. ECMall插件——余额支付
  10. 413.等差数列划分
  11. Confluence 表格快捷键
  12. c++ 小游戏 NO6 跑酷游戏
  13. vue出生日期转年龄
  14. 成熟好用的电池供电切换电路
  15. 7-19 评委打分 (15 分)
  16. 【NFS共享存储服务】
  17. 如何将打开的多个excel文件,显示为独立窗口?
  18. 怎么查找和自己专业有关的英文文献?
  19. 1582年日历怎么了_1582年日历图片
  20. 记一次太阳神三国杀的编译

热门文章

  1. 之前明信片比赛的作品——那些年的三中
  2. iro机器人地区选多少人_2019年第二十一届IRO国际机器人奥林匹克大赛总决赛在津举行...
  3. 重装系统后,mysql的安装与恢复数据
  4. 02_MySQL数据库导入——source指令以及Navicat导入数据库方法
  5. openssl的介绍和使用
  6. C++中typename的用法
  7. python忽略大小写_Python字符串忽略大小写实现搜索和替换
  8. python从txt拿取数据_python爬虫今日热榜数据到txt文件的源码
  9. 解决Mac睡眠启动后无声音
  10. 阿里达摩盘:画像营销洞察有哪5种玩法?