linux学习------一分析list.h 之 宏定义部分.docxVIP

linux学习------一分析list.h 之 宏定义部分.docx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
/wzyhb123456789/article/details/5853856Linux学习------分析list.h 之 宏定义部分 分类: /wzyhb123456789/article/category/722786Linux C 2010-08-31 17:55 446人阅读 /wzyhb123456789/article/details/5853856评论(0) javascript:void(0);收藏 /wzyhb123456789/article/details/5853856举报 ?在系统的头文件中,有很多函数是用宏定义的方式定义的,在list.h中,对双向链表进行遍历的函数都是通过这种方式定义的,其中有许多很巧妙的地方,也是很有意思的,短小精干。下面接着上一篇文章的内容继续分析一下list.h。?首先是下面这个宏定义:#define?list_entry(ptr,?type,?member)?/ ??container_of(ptr,?type,?member)???大致一看,就知道这个宏是调用container_of的,我们再看一下它是如何定义的:#define?container_of(ptr,?type,?member)?({??????????????????????/ ??const?typeof(?((type?*)0)-member?)?*__mptr?=?(ptr);????/???(type?*)(?(char?*)__mptr?-?offsetof(type,member)?);})???看着很复杂,我们先大致扫描一下,发现其中的offsetof,它的宏定义如下:#define?offsetof(TYPE,?MEMBER)?((size_t)?((TYPE?*)0)-MEMBER)??好了,到此对于我们要分析的第一个宏的所有有关宏都找出来了,我们再逆推上去,分析它的作用。最后一个宏,是先把0强制类型转换成为指向一个TYPE型数据的指针,然后取其中的MEMBER成员,再取它的地址,最后再强制类型转换成size_t型,就是unsigned long型,也就是MEMBER成员的地址,而该TYPE型数据的首地址为0,所以这个地址也就是MEMBER成员的偏移量,所以offsetof(TYPE, MEMBER)得到的是TYPE类型数据中成员MEMBER的地址偏移量。然后我们再一起看上一个宏,第一句话:const typeof( ((type *)0)-member ) *__mptr = (ptr) ,看等号左边,先把0强制类型转换成为指向一个type型数据空间的指针,然后取其中的成员member,然后通过typeof得到这个成员member的类型,然后定义一个指向这个类型数据的指针命名为__mptr,并赋值为ptr;再看第二句话:(type *)( (char *)__mptr - offsetof(type,member) ) ,把上面得到的__mptr减去成员member的偏移量,然后在强制类型转换成指向type型空间的指针,也就是地址,也就是得到了type类型的首地址,也就得到了一个指针,可以用它做“-”运算,得到其结构体中的任意一个值。好了,这个宏说完了,总结一句话,它的作用就是得到这个type类型的结构体的指针,然后通过它获取其中的元素,它这样定义的原因可能是为了增加极高的可移植性吧,反正它基本包括了所有种可能。?第一个总算分析完了,开始看第二个,内容如下:#define?list_first_entry(ptr,?type,?member)?/ ??list_entry((ptr)-next,?type,?member)???一看就轻松一点了,因为它正是调用了第一个宏来定义的,就是找到ptr-next的地址,也就是第一节点的地址,所以它叫list_first_entry。?迫不及待的来看下几个:#define?list_for_each(pos,?head)?/ ??for?(pos?=?(head)-next;?prefetch(pos-next),?pos?!=?(head);?/???pos?=?pos-next)??#define?__list_for_each(pos,?head)?/ ??for?(pos?=?(head)-next;?pos?!=?(head);?pos?=?pos-next)???这两个宏有两点不同,1、名字不同,第二个要多两个下划线(--!),2、在for循环的条件中第二个要少一个prefetch(pos-next)。先看内容较少的那个,循环的初值为pos=(head)-next,就是指向第一个结点,循环体是不断地向后指,循环条件是pos不是head

文档评论(0)

xiaoxue8 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档