C/C++编程:宏offsetof()
理论
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()相关推荐
- 【C语言】宏offsetof的模拟实现 (计算结构体中某变量相对于首地址的偏移)
首先我们应该特别留意 : offsetof 是一个宏,并非是一个函数 ! 宏offsetof的介绍 : 参数:第一个是结构体类型名称,第二个是结构体成员名 返回类型:size_t无符号整形 引用的头文 ...
- c语言 offsetof函数,C 库宏 - offsetof()函数
宏offsetof 标准库stddef.h 定义 size_t offsetof(type, member); 分析 C 库宏 offsetof(type, member) 会生成一个类型为 size ...
- C库宏-offsetof()
在项目开发过程中,发现了offsetof()函数,随即查询了此函数,摘录如下: C库宏 - offsetof() 描述 C库宏offsetof(type, member-designator)会生成一 ...
- pythonmainoffset_宏offsetof分析
1.前言 在C语言的结构体中,由于字节对齐的问题,所以成员的地址并不能直接根据数据类型的大小进行计算,使用宏offsetof可以获得结构体成员相对于结构体首地址的字节偏移量. 2.offsetof宏实 ...
- C 语言编程 — 宏定义与预处理器指令
目录 文章目录 目录 前文列表 宏 预处理器 预处理器指令 预处理器指令示例 预处理器指令运算符 宏定义 简单宏定义 带参数的宏定义 符号吞噬问题 使用 do{}while(0) 结构 预定义的宏 常 ...
- 对宏offsetof理解
#ifndef offsetof #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER) #endif offset这个 ...
- C语言编程宏定义的优缺点,C语言重要知识点总结(二)--内存结构、函数调用过程(栈帧)、宏的优缺点以及##和#的使用...
一.内存结构 内存大致可以分为四个部分:代码段,静态存储区,堆,栈. 具体划分如下图所示: 栈:在执行函数时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束后会自动释放内存.栈内存的分配运算 ...
- 实现宏offsetof()
本期介绍
- 鼠标键盘 录制 可编程宏 /回放 工具 Macro Recorder 汉化 破解 优化
经常需要操作一些简单重复的工作 比如 就需要一些工具来做这些重复的工作来减轻工作量 鼠标键盘录制回放工具 用过很多 都不太理想 (Mouse Recorder 没有相应热键, 速度可调)(Pulov ...
最新文章
- 【转】【Mysql学习】之Mac上用终端使用mySQL
- linux nfs 配置_centos7 NFS 配置
- windows server 2012服务器IIS基本配置
- JAVA中CLASS.FORNAME的含义
- Scrapy读取设置文件(settings.py)
- iPhone 6S GPU到底多强
- luoguP3281 [SCOI2013]数数
- Linux 正在吞噬 Windows 和 Chrome OS!
- ECMall插件——余额支付
- 413.等差数列划分
- Confluence 表格快捷键
- c++ 小游戏 NO6 跑酷游戏
- vue出生日期转年龄
- 成熟好用的电池供电切换电路
- 7-19 评委打分 (15 分)
- 【NFS共享存储服务】
- 如何将打开的多个excel文件,显示为独立窗口?
- 怎么查找和自己专业有关的英文文献?
- 1582年日历怎么了_1582年日历图片
- 记一次太阳神三国杀的编译
热门文章
- 之前明信片比赛的作品——那些年的三中
- iro机器人地区选多少人_2019年第二十一届IRO国际机器人奥林匹克大赛总决赛在津举行...
- 重装系统后,mysql的安装与恢复数据
- 02_MySQL数据库导入——source指令以及Navicat导入数据库方法
- openssl的介绍和使用
- C++中typename的用法
- python忽略大小写_Python字符串忽略大小写实现搜索和替换
- python从txt拿取数据_python爬虫今日热榜数据到txt文件的源码
- 解决Mac睡眠启动后无声音
- 阿里达摩盘:画像营销洞察有哪5种玩法?