您的位置:首页 > 其它

list.h链表练习

2014-03-26 21:07 232 查看
基于list.h写了一段小程序,果然短小精悍,以后链表就直接用它了。通常使用struct list_head ,应该是将其作为自定义结构体中的一部分。

 

有几个比较难理解的宏:

INIT_LIST_HEAD();声明一个链表头;

list_for_each (..) 遍历组成list_head链表的每个元素;

list_entry(...) 通过结构体某一个成员的指针,推算出整个结构体的起始地址,这是个很实用的做法;关键在于理解

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

其实就相当于 &((struct test *) object)>MEMBER;  注意->的优先级比 & 高,之前因为这个困惑了很久,以为对0地址再取地址,后来才明白是对MEMBER变量取地址。因为结构体起始地址为0,所以取得的这个值即是相对结构体起始地址的偏移。

list_for_each_entry ,相当于list_for_each和list_entry的组合使用,直接返回包含struct list_head的 父结构;

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "list.h"
/***
*使用list.h  实现链表数据排序
*
*/
#define MAX_NAME_LEN 10
struct mylist {
int num;
char name[MAX_NAME_LEN];
struct list_head list;
};

/**
* 通过内嵌list_head组织成一个双向链表
*
*/
struct mylist head;
int main(int argc,char *args[])
{

int i;

struct list_head *pos;
struct mylist *stack_list;
struct mylist *iterate_pos;

INIT_LIST_HEAD(&(head.list));

for(i=0;i<10;i++)
{
stack_list = (struct mylist *)malloc(sizeof(struct mylist));
stack_list->num = i+10;
list_add(&(stack_list->list),&(head.list));// list_add looks like a stack
}

// 使用list_for_each 先获取list_head指针,再使用list_entry获取父结构指针
list_for_each(pos,&(head.list))
{
iterate_pos = list_entry(pos,struct mylist,list);
printf("%d->",iterate_pos->num);
}
printf("\n");

//backward iterate
printf("backward iterate stack!\n");
list_for_each_prev(pos,&(head.list))
{
iterate_pos = list_entry(pos,struct mylist,list);
printf("%d->",iterate_pos->num);
}
printf("\n");

// iterate and replace one inode
printf("replace one inode!\n");
struct mylist *replace_node;
replace_node= (struct mylist *)malloc(sizeof(struct mylist));
replace_node->num= 55;

list_for_each(pos,&(head.list))
{
iterate_pos = list_entry(pos,struct mylist,list);
if(iterate_pos->num == 18)
{
list_replace((&iterate_pos->list),&(replace_node->list));
}
}

//使用list_for_each_entry 直接获取父结构指针并进行  遍历
printf("list use list_for_each_entry and check the replace inode\n");
struct mylist *entry_list;
entry_list =  (struct mylist *)malloc(sizeof(struct mylist));

list_for_each_entry(entry_list,&(head.list),list)
printf("%d-",entry_list->num);
printf("\n");

//delete list test
struct list_head *freetmp,*p;
struct mylist *freelist;
list_for_each_safe(freetmp,p,&head.list)
{
freelist= list_entry(freetmp, struct mylist, list);
printf("freeing item id= %d\n", freelist->num,freelist->name);
list_del(freetmp);
free(freelist);
}

if(list_empty(&head.list))
printf("list is empty now!\n");
return 0 ;

}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: