Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1732399
  • 博文数量: 782
  • 博客积分: 2455
  • 博客等级: 大尉
  • 技术积分: 4140
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-06 21:37
个人简介

Linux ,c/c++, web,前端,php,js

文章分类

全部博文(782)

文章存档

2015年(8)

2014年(28)

2013年(110)

2012年(307)

2011年(329)

分类: LINUX

2012-05-22 10:15:23

list_entry

  /* list_entry - get the struct for this entry
  * @ptr: the &struct list_head pointer.
  * @type: the type of the struct this is embedded in.
  * @member: the name of the list_struct within the struct.*/
  #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
编辑本段
描述

  我们使用list_entry()宏在linux链表中访问链表数据。
  原理为指针ptr指向结构体type中的成员member;通过指针ptr,返回结构体type的起始地址。
  定义中((size_t) &(type *)0)->member)意为:把0地址转化为type结构的指针,然后获取该结构中member成员的指针,并将其强制转换为size_t类型
编辑本段
例子

  如果我们有test_list结构:
  struct test_list{
  int testdata;
  struct list_head list;};
  struct test_list a;
  a.testdata = 5;
  struct test_list *pos = list_entry(&(a.testdata),struct test_list,testdata);
  结果:
  pos = &a;
  可测试:
  pos->testdata = 5
编辑本段
解释

  &((type *)0)->member:
  把“0”强制转化为指针类型,则该指针一定指向“0”(数据段基址)。因为指针是“type *”型的,所以可取到以“0”为基地址的一个type型变量member域的地址。那么这个地址也就等于member域到结构体基地址的偏移字节数。
  ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))):
  (char *)(ptr)使得指针的加减操作步长为一字节,(unsigned long)(&((type *)0)->member)等于ptr指向的member到该member所在结构体基地址的偏移字节数。二者一减便得出该结构体的地址,转换为 (type *)型的指针。
阅读(1526) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~