关闭

C语言的那些小秘密之链表(三)

发表于:2011-12-15 10:38

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:bigloomy(CSDNblog)    来源:51Testing软件测试网采编

  看看上面的代码,我们做的基本工作都有那些呢?

  1、定义了一个宿主结构体stu,并且在宿主结构体中我们定义了一个struct list_head 类型的list变量;

  2、定义一个头结点并且对其进行初始化工作;

  3、对定义的一个宿主结构体变量申请内存空间;

  4、对申请的宿主结构体变量初始化和添加到以stu_list为头结点的链表中。

  在上面值得注意的就是list_for_each()和list_entry(),我们会在接下来的部分讲解,读者在这儿只需要知道它们两个在此合在一起的作用就是打印出宿主结构stu中每个数据。sprintf()的使用就不在这里讲解了,很简单,相信读者猜都可以猜出它的功能。读者如果一开始对上面的文字描述部分有什么疑惑或者不解的现在看了代码的实现应该都懂了,list_add_tail()的使用和list_add()类似,读者可以自己修改代码实现。如果一开始对于list_add()不太理解的读者,现在对于list_add()的理解现在可以参考运行结果和上面的文字描述部分。

  我们接着往下看。

  1. static inline void __list_del(struct list_head * prev, struct list_head * next)  
  2. {  
  3.     next->prevprev = prev;  
  4.     prev->nextnext = next;  
  5. }

  在prev和next指针所指向的结点之间,两者互相所指。其实也就是prev为待删除的结点的前面一个结点,next为待删除的结点的后面一个结点。

  1. static inline void list_del(struct list_head *entry)  
  2. {  
  3.     __list_del(entry->prev, entry->next);  
  4.     entry->next = LIST_POISON1;  
  5.     entry->prev = LIST_POISON2;  
  6. }

  删除entry所指的结点,同时将entry所指向的结点指针域封死。在这里值得注意的是LIST_POISON1、LIST_POISON2。它们在list.h中的宏定义如下:

  #define LIST_POISON1  ((void *) 0x00100100)

  #define LIST_POISON2  ((void *) 0x00200200)

  对LIST_POISON1、LIST_POISON2的说明,Linux 内核中有这么一句话:These are non-NULL pointers that will result in page faults under normal circumstances,used to verify that nobody uses  non-initialized list entries。也就是说它们并不是空指针,但是访问这样的指针在正常情况下是会导致出错的。其实按照我们一般的思路都是把entry->next 和entry->prev 赋值为NULL,使得不可以通过该节点进行访问。但是在这里使用了一种特殊的方法。注意:我在linux环境下以上宏的值不用修改是不会出错的,但是在vc下就会出错,不允许使用那两个值,所以要修改为NULL。

  1. static inline void list_del_init(struct list_head *entry)  
  2. {  
  3.         __list_del(entry->prev, entry->next);  
  4.         INIT_LIST_HEAD(entry);  
  5. }

53/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号