注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mr.Right

不顾一切的去想,于是我们有了梦想。脚踏实地的去做,于是梦想成了现实。

 
 
 

日志

 
 
关于我

人生一年又一年,只要每年都有所积累,有所成长,都有那么一次自己认为满意的花开时刻就好。即使一时不顺,也要敞开胸怀。生命的荣枯并不是简单的重复,一时的得失不是成败的尺度。花开不是荣耀,而是一个美丽的结束,花谢也不是耻辱,而是一个低调的开始。

网易考拉推荐

offsetof用法 C++计算成员地址的内存偏移量  

2012-12-29 19:56:53|  分类: 学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

offsetof宏解析


今天看代码时,发现一个有用的东东,offsetof(s,m),这是一个宏,MSDN文档的说明如下:

Retrieves the offset of a member from the beginning of its parent structure.

size_t offsetof(
structName,
memberName 
);


Parameters

structName 
Name of the parent data structure.


memberName 
Name of the member in the parent data structure for which to determine the offset.


Return Value


offsetof returns the offset in bytes of the specified member from the beginning of its parent data structure. It is undefined for bit fields.
 
Remarks

The offsetof macro returns the offset in bytes of memberName from the beginning of the structure specified by structName. You can specify types with the struct keyword.

Note 


offsetof is not a function and cannot be described using a C prototype.

跟踪代码发现定义如下:

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

然后到网上查了一下,发现还真的是很有用,附带一位大侠的解说:

struct AAA 

    int i; 
    int j; 
}; 

struct AAA *pAAA; 
pAAA=new AAA;


这时,pAAA实际上是一个Pointer, 指向某一确定的内存地址,比如0x1234; 
而 pAAA->i 整体是一个int型变量,其地址是&(pAAA->i) ,'&'为取址运算符; 
那么&(pAAA->i)一定等于0x1234,因为i是结构体AAA的第一个元素。 
而&(pAAA->j)一定是0x1234 + 0x4 = 0x1238; 因为sizeof(int) = 4;

这个做法的巧妙之处就是:它把“0”作为上例中的pAAA,那么 &(pAAA->j)就是j的offset啦。

解析结果是: 
(s *)0 ,将 0 强制转换为Pointer to "s" 
可以记 pS = (s *)0 ,pS是指向s的指针,它的值是0; 
那么pS->m就是m这个元素了,而&(pS->m)就是m的地址,而在本例中就是offset啦 

再把结果强制转换为size_t型的就OK 了,size_t其实也就是int啦!!

也就是说:

0 ---> (s *)0

原来的0是数值类型,现在是结构体指针类型,尽管类型变了,但其值还是不变,也就是说还是0,但这个值的意义变了,现在是地址,而不是数值。

&(((s *)0)->m)求出字段m的地址值,但由于首地址是0,所以&(((s *)0)->m)求出字段m相对于首地址的偏移值。

  评论这张
 
阅读(932)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016