pythonmainoffset_宏offsetof分析

1、前言

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

2、offsetof宏实现

在C标准库中offsetof的声明如下,需要包含头文件:

size_t offsetof(type, member);

参数:

type:结构体类型

member:结构体中成员的名称

返回值:

返回类型为size_t的值,表示type中member的偏移量

该宏在Linux内核源码内的实现如下:

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

通过上面这个宏为什么能获取到结构体某个成员的偏移地址呢?首先,偏移地址的计算方法为:

当前的成员地址-结构体首地址=偏移地址

在offsetof宏中,将0地址强制转换成了(TYPE *)类型,也就是说结构体的首地址为0,所以根据偏移地址计算方法,可以知道当前成员的地址也就等于偏移地址,所以宏offsetof将成员的地址取出并返回,获得的就是某个成员的偏移地址了,返回值为size_t类型,需要引起一定的注意。

3、实例

下面是一个offsetof的使用实例,代码如下所示:

#include

#include

#include

struct s {

int i;

char c;

double d;

char a[];

};

int main(int argc, char *argv[])

{

printf("sizeof(struct s)=%zd\n", sizeof(struct s));

printf("offsets: i=%zd; c=%zd; d=%zd; a=%zd.\n",

offsetof(struct s, i), offsetof(struct s, c),

offsetof(struct s, d), offsetof(struct s, a));

exit(EXIT_SUCCESS);

}

使用gcc编译后运行结果如下所示:

L3Byb3h5L2h0dHBzL2ltZzIwMTguY25ibG9ncy5jb20vYmxvZy8xNjI1MDMzLzIwMTkwOC8xNjI1MDMzLTIwMTkwODI5MTE0MzE4OTY4LTQ4NTI5ODMxNi5wbmc=.jpg

由于字节对齐的原因,所以结构体s的大小为16个字节,假设结构体首地址从0开始,由于int类型占用4字节,所以地址0到3为变量i所用,char类型占用1字节,地址4为变量c所用,由于需要字节对齐并且double类型的开始地址必须是8的整数倍,因此地址5到7被填充,double类型占用8字节,地址8到15被变量d所用,a的地址则从地址16开始,因此,通过宏offsetof便可以得到结构体成员的偏移地址。

参考:

https://www.runoob.com/cprogramming/c-macro-offsetof.html

https://www.cnblogs.com/litifeng/p/7685378.html

container_of宏定义分析---linux内核

问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...

剖析linux内核中的宏-----------offsetof

offsetof用于计算TYPE结构体中MEMBER成员的偏移位置. #ifndef offsetof#define offsetof(TYPE, MEMBER) ((size_t) &((T ...

linux内核container_of宏定义分析

看见一个哥们分析container_of很好,转来留给自己看 一.#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMB ...

《linux 内核全然剖析》 笔记 CODE_SPACE 宏定义分析

在memory.c里面.遇到一个宏定义,例如以下: #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ current->sta ...

宏&lowbar;CRTIMP分析

CRTIMP是C run time implement的简写,C运行库的实现的意思. 作为用户代码,不应该使用这个东西. 该参数决定 运行时 到底用 动态链接库 还是静态链接 #ifndef _CRT ...

C语言-宏定义与使用分析

1.C语言中的宏定义 #define是预处理器处理的单元实体之— #define定义的宏可以出现在程序的任意位置 #define定义之后的代码都可以使用这个宏 2.定义宏常量 #define定义的宏常 ...

C语言笔记(结构体与offsetof、container&lowbar;of之前的关系)

关于结构体学习,需要了解:结构体的定义和使用.内存对齐.结构体指针.得到结构体元素的偏移量(offsetof宏实现) 一.复习结构体的基本定义和使用 typedef struct mystruct { ...

linux内核中socket的创建过程源码分析(详细分析)

1三个相关数据结构. 关于socket的创建,首先需要分析socket这个结构体,这是整个的核心. 104 struct socket { 105         socket_state       ...

嵌入式C语言自我修养 04:Linux 内核第一宏:container&lowbar;of

4.1 typeof 关键字 ANSI C 定义了 sizeof 关键字,用来获取一个变量或数据类型在内存中所占的存储字节数.GNU C 扩展了一个关键字 typeof,用来获取一个变量或表达式的类型 ...

随机推荐

非maven项目导入idea几点心得总结

这个问题一共有3种解决办法1. 你下载好的文件应该是src 和Webcontent是在同一个目录下的.只要把Webcontent放入到src下就行.这种就变成maven的目录结构.因为你这个目录结构应 ...

Yii-数据模型- rules类验证器方法详解

public function rules(){ return array( array('project_id, type_id, status_id, owner_id, requester_id ...

在不同平台上CocosDenshion所支持的音频格式

在大多数平台上,cocos2d-x调用不同的SDK API来播放背景音乐和音效.CocosDenshion在同一时间只能播放一首背景音乐,但是能同时播放多个音效. 背景音乐 Platform supp ...

python手记&lpar;51&rpar;

python通过声音将文件内容隐藏,实现原理是将文件的内容分别插入到声音文件的不同位置中做为当次采样的数据,目前是对英文文本文档加解密 #!/usr/bin/env python # -*- codi ...

RSA原理、ssl认证、Tomcat中配置数字证书以及网络传输数据中的密码学知识

情形一:接口的加.解密与加.验签 rsa不是只有加密解密,除此外还有加签和验签.之前一直误以为加密就是加签,解密就是验签.这是错误的! 正确的理解是: 数据传输的机密性:公钥加密私钥解密是密送,保 ...

iOS日历中给一个事件添加多个提醒

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) iOS自带的日历应用中,我们最多只能给一个事件设置2个提醒,但 ...

mysql学习3

1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引, 会保存在额外的文件中. 作用: 约束 加速查找 1.1.建立索引 a.额外的文件保存特殊的数据结构 ...

&OpenCurlyDoubleQuote;字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛 1010 Count

思路:矩阵快速幂.推一下初始矩阵就好了 #include #define LL long long #define fi first #define se s ...

网卡phy9161A

硬件1. 网口网口使用4根信号线:两根发送,两根接收.一对信号线中一根承载0——+2.5V信号电压,而另一根负载的电压是0——-2.5V,因此可产生一个5Vpp的信号差.RJ45中有用的就是4根信号线 ...

更快写入的落脚点不是线程数而是mysql连接数 对数据库 批处理 批写入

批提交mysql 单线程的批提交 nohup  python fromRedisoToMysqlSingleThreadOneConnBatchInsert.py 100 10.24.192.192 ...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值