c语言lr分析器的设计与实现_C语言程序设计——深入解析offsetof的实现

dbf749940a9d495bd9e55f085f004166.png

我们在开发中,有可能用到offsetof,来求结构成员在结构中的偏移量。例如下面的代码:

60bca9929dbc5de8bdfa232f355dc1c4.png

上面代码的功能,是使用“offsetof”的功能,查询结构体TMyStruct中三个成员m_pcName、m_sAge、m_iScore的偏移量。

offsetof是函数吗?在Linux中,使用man命令查询offsetof的帮助文档,得到的信息如下:

#include size_t offsetof(type, member);

从帮助信息来看,offsetof简直一定是函数,但是我们很惊讶,C语言函数怎么能够传入这样的参数:

(1)结构类型名;

(2)没有给出结构变量名,直接使用成员变量。

真实的答案是,确实不能给C语言函数传入这种参数。offsetof也并不是函数,只是一个宏定义:

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

上面的宏定义让我们有点摸不着头脑,我们可以将这个宏定义变得复杂一点,但是更容易理解一些:

#define offsetof(TYPE, MEMBER) ((size_t)

((char *)&((TYPE *)0)->MEMBER - (char *)(TYPE *)0))

如果您是STM32的程序员,深入研究过STM32如何将一批寄存器变量组装成struct结构,您就理解C语言编译器对struct的处理方式:

在C语言中,对struct的处理方式,就是将struct变量的成员,变为struct变量的地址+偏移量,然后转换为对应的类型。

因此,offsetof宏定义最巧妙的地方,是欺骗编译器,把地址零当成某个结构类型变量的地址,然后算出偏移量。

讲到这里,基本上将offsetof的巧妙之处说完了。

现在延伸一下,上面的程序中,三个成员变量的偏移值应该是0,7,9吧?实际上,您猜错了,真实的答案是0,8,12:

c904dca8a50f8b3f93a1c43afcf5435e.png

为什么是这样的结果?这里先卖个关子,下节课讲述具体原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值