Chinaunix首页 | 论坛 | 博客
  • 博客访问: 177443
  • 博文数量: 30
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-23 19:45
文章分类

全部博文(30)

文章存档

2016年(2)

2010年(3)

2009年(8)

2008年(17)

我的朋友

分类: LINUX

2008-10-12 20:10:17

遍历:

这部分代码比较长不过有些还比较相似的,所以不用担心,我们来一步一步往下看。

#define (, , ) \

(, , )

List_entry()这个宏又牵扯到一个宏container_of(),有必要把这个宏详细分析下,这个宏用途很广,说明其也很重要。

//在头文件include/linux/kernel.h中有此定义。

#define (, , ) ({ \

const ( (( *)0)-> ) * = (); \

( *)( (char *) - (,) );})

他的作用是:通过结构中的某个变量获取结构本身的指针。

typeof()offsetof(),它们返回的是某个变量的类型和结构中某变量在结构中的偏移量。typeof()gcc的扩展。

offsetof宏定义在[include/linux/stddef.h]中:

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

offsetof宏的实现非常巧妙,它把0地址转化为TYPE结构的指针,然后获取该结构中MEMBER成员的指针,并将其强制类型转换为 size_t类型。于是,由于结构从0地址开始定义,因此,强制转换后的MEMBER成员地址,实际上就是它在结构中的偏移量,这也显示出了C语言中指针的强大。

看下面的图六可以帮助理解。ptr是指向结构体type类型中的一个成员(member)的指针,这样三个参数我们都知道了,第319_mptr强制转换成ptr所指向的类型,然后把ptr赋给它。320_mptr减去membertype中的偏移量(由offsetof(type,member)算出),这样就等于将ptr指针向后移动了offsetof()个偏移量,即就是指针指向了type指向的位置。一般使用时member成员为struct list_head结构(注意这个,这就是这个宏的妙用,在后面的文章中将会举个例子说明它的妙处)。

综上述可知list_entry()可以得到一个type类型的结构体。

#define (, , ) \

(()->, , )

知道了list_entry()的用法,list_first_entry()就无需多言了吧。

#define (, ) \

for ( = ()->; (->), != (); \

= ->)

此函数作用:循环访问一个链表。遍历访问是这样进行的:head是链表头,从head->next开始,一直到pos指向最后一个项即就是head->prev为止,函数prefetch()是预先取得下一个链表项,为了加快速度。

#define (, ) \

for ( = ()->; != (); = ->)

这个宏和list_for_each()类似,不同之处在于,这个没有预取函数prefetch(),一般是短链表才使用这个宏。

/**

* list_for_each_prev - iterate over a list backwards

* @pos: the &struct list_head to use as a loop cursor.

* @head: the head for your list.

*/

#define (, ) \

for ( = ()->; (->), != (); \

= ->)

此宏和list_for_each()相反,沿着相反的方向(head->prev)遍历,最后是pos指向了head->next

#define (, , ) \

for ( = ()->, = ->; != (); \

= , = ->)

这个宏是list_for_each()的“安全版”,它先将pos的下一个即pos->next赋给n,然后pos=n;防止了pos->next在未赋值给pos前被移除造成的链表断裂。

#define (, , ) \

for ( = (()->, (*), ); \

(->.), &-> != (); \

= (->., (*), ))

遍历一个给定链表,member为链表项中的成员,为struct head_list型,head为链表头,最后将指向链表的最后一项。

#define (, , ) \

for ( = (()->, (*), ); \

(->.), &-> != (); \

= (->., (*), ))

list_for_each_entry()类似,只不过是反向遍历而已。

阅读(1677) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~