例说Linux内核链表(二)

链表使用

我认为熟悉内核链表功能最好的方法就是看一些简单的实例,实例是一个非常好的素材去更好的理解链表。

下面是一个例子,包含创建,添加,删除和遍历链表。

<span style="font-size:14px;"><span style="color:#330099;">#include <stdio.h>
#include <stdlib.h>

#include "list.h"


struct kool_list{
	int to;
	struct list_head list;
	int from;
	};//自定义欲链接的数据额结构,并包含双向链表结构

int main(int argc, char **argv){

	struct kool_list *tmp;
	struct list_head *pos, *q;
	unsigned int i;

	struct kool_list mylist;
	INIT_LIST_HEAD(&mylist.list);//初始化一个链表表头

	/* 向<span style="font-family: Arial, Helvetica, sans-serif;">mylist中添加元素</span><span style="font-family: Arial, Helvetica, sans-serif;"> */</span>
	for(i=5; i!=0; --i){
		tmp= (struct kool_list *)malloc(sizeof(struct kool_list));
		
		/* INIT_LIST_HEAD(&tmp->list); 
		 *
		 * this initializes a dynamically allocated list_head. we
		 * you can omit this if subsequent call is add_list() or 
		 * anything along that line because the next, prev
		 * fields get initialized in those functions.
		 */
		printf("enter to and from:");
		scanf("%d %d", &tmp->to, &tmp->from);

		/* add the new item 'tmp' to the list of items in mylist */
		list_add(&(tmp->list), &(mylist.list));//项链表中添加新的元素节点,tmp中的list
		/* you can also use list_add_tail() which adds new items to
		 * the tail end of the list
		 */
	}
	printf("\n");


	/* now you have a circularly linked list of items of type struct kool_list.
	 * now let us go through the items and print them out
	 */


	/* list_for_each() is a macro for a for loop. 
	 * first parameter is used as the counter in for loop. in other words, inside the
	 * loop it points to the current item's list_head.
	 * second parameter is the pointer to the list. it is not manipulated by the macro.
	 */
	printf("traversing the list using list_for_each()\n");
	list_for_each(pos, &mylist.list){//遍历链表,pos依次指向链表的元素

		/* at this point: pos->next points to the next item's 'list' variable and 
		 * pos->prev points to the previous item's 'list' variable. Here item is 
		 * of type struct kool_list. But we need to access the item itself not the 
		 * variable 'list' in the item! macro list_entry() does just that. See "How
		 * does this work?" below for an explanation of how this is done.
		 */
		 tmp= list_entry(pos, struct kool_list, list);//获得包含pos节点的数据结构<span style="font-family: Arial, Helvetica, sans-serif;">struct kool_list指针</span>

		 /* given a pointer to struct list_head, type of data structure it is part of,
		  * and it's name (struct list_head's name in the data structure) it returns a
		  * pointer to the data structure in which the pointer is part of.
		  * For example, in the above line list_entry() will return a pointer to the
		  * struct kool_list item it is embedded in!
		  */

		 printf("to= %d from= %d\n", tmp->to, tmp->from);

	}
	printf("\n");
	/* since this is a circularly linked list. you can traverse the list in reverse order
	 * as well. all you need to do is replace 'list_for_each' with 'list_for_each_prev'
	 * everything else remain the same!
	 *
	 * Also you can traverse the list using list_for_each_entry() to iterate over a given
	 * type of entries. For example:
	 */
	printf("traversing the list using list_for_each_entry()\n");
	list_for_each_entry(tmp, &mylist.list, list)
		 printf("to= %d from= %d\n", tmp->to, tmp->from);
	printf("\n");
	

	/* now let's be good and free the kool_list items. since we will be removing items
	 * off the list using list_del() we need to use a safer version of the list_for_each() 
	 * macro aptly named list_for_each_safe(). Note that you MUST use this macro if the loop 
	 * involves deletions of items (or moving items from one list to another).
	 */
	printf("deleting the list using list_for_each_safe()\n");
	list_for_each_safe(pos, q, &mylist.list){
		 tmp= list_entry(pos, struct kool_list, list);
		 printf("freeing item to= %d from= %d\n", tmp->to, tmp->from);
		 list_del(pos);
		 free(tmp);
	}

	return 0;
}</span>
</span>
<img src="http://blogimg.chinaunix.net/blog/upfile2/081023224717.jpg" alt="" />
关于内核链表的常用的几个API实现,将在例说Linux内核链表(三)中介绍。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。