offsetof

 

今天偶然看到一个新东西—— offsetof ,发现值得为它写点东西。先看下 MSDN 的帮助文档,定义如下,其功能是获取结构体 structName 中成员 memberName 相对结构体开头地址的偏移量。

 

size_t offsetof( structName , memberName );

 

offsetof 是一个宏,其定义在头文件 stddef.h 中,如下

 

#define offsetof(s, m)   (size_t)&(((s *)0)->m)

 

看个例子,使用如下:

 

offsetof 为什么要强制类型转化 0 ,这是个考验你功底的问题。

((s *)0) ——强制转化成数据结构指针 , 并使其指向地址 0

((s *)0)->m ——使该指针指向成员 m

&(((s *)0)->m) ——获取该成员 m 的地址

(size_t)&(((s *)0)->m) ——转化这个地址为合适的类型

你可能会迷惑,这样强制转换后的结构指针怎么可以用来访问结构体字段?呵呵,其实这个表达式根本没有也不打算访问 m 字段。 ANSI C 标准允许任何值为 0 的常量被强制转换成任何一种类型的指针,并且转换结果是一个 NULL 指针,因此 ((s*)0) 的结果就是一个类型为 s* NULL 指针。如果利用这个 NULL 指针来访问 s 的成员当然是非法的,但 &(((s*)0)->m) 的意图并非想存取 s 字段内容,而仅仅是计算当结构体实例的首址为 ((s*)0) m 字段的地址。聪明的编译器根本就不生成访问 m 的代码,而仅仅是根据 s 的内存布局和结构体实例首址在编译期计算这个 ( 常量 ) 地址,这样就完全避免了通过 NULL 指针访问内存的问题。又因为首址的值为 0 ,所以这个地址的值就是字段相对于结构体基址的偏移。

这里有个地方需要注意 : 就是 offsetof 虽然同样适用于 union 结构,但它不能用于计算位域成员在数据结构中的偏移量。如下


 

 

参考 offsetof ,可以自己定义宏 SIZEOF ,计算结构体中成员的大小。如下图


 

 

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值