既然我们分析了list.h,那么就要学以致用,因为通过具体的例子我们才能真实感受到双链表的用法。本文首先为你呈现一个最基本的双链表使用方法,然后在引用另外两个例子,大家可以去亲自试试。
1.简单的学生管理系统
这里学生管理系统只是个基本模型:用户输入数据,然后通过输出重定向到stuInfo.txt文件当中。先看学生信息数据结构:
struct postinfo { char id[20]; char name[20]; char sex[10]; char addr[50]; char email[20]; struct list_head list; };
正如我们前面所说的那样,整个双链表是通过struct list_head结构链接起来的,这样我们每次对某个结点的操作,都是先获得list字段的地址,进而通过list_entry宏获得当前结点的地址。
首先,创建头指针。注意我这里说的是头指针,并不是头结点,因此你应该可以理解为什么下面会首先创建一个struct list_head类型的变量,而不是struct postinfo类型的变量。
struct list_head head; INIT_LIST_HEAD(&head);
创建好头指针,我们接下来就去增加学生信息。每次都先生成一个struct postinfo类型的变量tmp,再将每次要增加的信息都暂时保存在此变量中,接着就利用上次我们所说的增加函数:
list_add_tail(&(tmp->list),head);
注意这里我们使用的是&(tmp->list),正如我们一开始所说的每次对结点的操作实际上都是通过list字段去完成的。
添加完毕后,如何去打印数据?使用我们的遍历宏。pos只是一个struct list_head类型的指针,这个宏会首先使得pos指向head->next,即list链表的第一个结点(而非第一个学生信息结点)。每次移动链表后,通过pos获得当前结点的地址,那么就可以获得其他数据字段的地址了。
list_for_each(pos,head) { pinfo=list_entry(pos,struct postinfo,list); printf("%s %s %s %s %s\n",pinfo->id,pinfo->name,pinfo->sex,pinfo->addr,pinfo->email); }
这个演示程序关键部分就是这样,其他地方只要你有C语言基础,就可以完成的。
2.遍历进程
具体过程请点击这里。
test
[回复一下]
test~~~~
[回复一下]
文章写的都很不错,尤其是对list.h的分析和使用,都很深刻,让我收益匪浅,谢谢,强烈支持!
[回复一下]
edsionte 回复:
19 8 月, 2010 at 10:41
分享知识也是一种快乐。大家共同学习。
[回复一下]
刚开始自己写老师不明白那个 INIT_LIST_HEAD 参数,这个【头指针,头结点】的说明,一看一下就明白了
Nice~
[回复一下]
milk 回复:
29 4 月, 2014 at 11:25
@milk, 老是。。。。不是老师 = =
[回复一下]
edsionte 回复:
29 4 月, 2014 at 16:44
@milk, 谢谢。希望对你有帮助。
[回复一下]
我在4.15版本内核的list.h头文件中,诸如__list_del这样的宏定义,不再是简单的赋值语句,而是改成了作用等价的WRITE_ONCE宏,请问这样做的原因是什么?
[回复一下]