内核链表学习注释

来源:互联网 发布:数据库常用地约束包括 编辑:程序博客网 时间:2024/06/07 14:23

首先先看内核链表的定义:linux-/include/linux/list.h


struct list_head {        struct list_head *next, *prev;};

看出来内核链表(循环表)只有前驱和后继指针,没有数据域,这是和一般的单双链表的区别

示意图:


初始化链表:

#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \        struct list_head name = LIST_HEAD_INIT(name)
LIST_HEAD(name)相当于struct list_head name = LIST_HEAD_INIT(name)={ &(name), &(name) } 定义并初始化了前驱和后继指针。等于下边

struct list_head {
        struct list_head *next, *prev;
}head={&(head),&(head)} 就是一般的结构体定义并初始化。


添加节点:

static inline void __list_add(struct list_head *newer,                              struct list_head *prev,                              struct list_head *next){        newer->next = next;        newer->prev = prev;        next->prev = newer;        prev->next = newer; }//插入节点操作
static inline void mlist_add(struct list_head *newer, struct list_head *head){        __list_add(newer, head, head->next);}//头插法,遍历时数据逆序
static inline void mlist_add_tail(struct list_head *newer, struct list_head *head){        __list_add(newer, head->prev, head);}//尾插法,遍历时数据正序

代码:

#include<string.h>#include<stdlib.h>#include<stdio.h>#include"list.h"typedef struct _stu  {      char name[20];      int num;      struct list_head list;  }stu;    //定义了宿主结构体stu 在宿主结构体中定义了struct list_head的变量list  int main()  {      stu *pstu;      stu *tmp_stu;      struct list_head stu_list;  //定义了头节点    struct list_head *pos;      int i = 0;            INIT_LIST_HEAD(&stu_list);  //对头节点进行初始化          pstu = malloc(sizeof(stu)*5);  //对宿主结构体申请空间          for(i=0;i<5;i++)      {          sprintf(pstu[i].name,"Stu%d",i+1);  //格式化数据写进成员变量name中        pstu[i].num = i+1;         mlist_add_tail( &(pstu[i].list), &stu_list);//尾插法      //mlist_add( &(pstu[i].list), &stu_list);  //头插法             }   //对宿主结构体初始化并添加到以stu_list为头节点的链表中              list_for_each(pos,&stu_list)  //?    {          tmp_stu = list_entry(pos, stu, list);          printf("student num: %d\tstudent name: %s\n",tmp_stu->num,tmp_stu->name);      }          mlist_del(&(pstu[4].list));  //删除的节点    printf("使用list_del()删除pstu[3]\n");      list_for_each(pos,&stu_list)      {          tmp_stu = list_entry(pos, stu, list);          printf("student num: %d\tstudent name: %s\n",tmp_stu->num,tmp_stu->name);               }            mlist_move(&(pstu[2].list),&stu_list);  //删除节点再头插进去    printf("把pstu[2]移至head和head->next两个指针所指向的结点之间\n");      list_for_each(pos,&stu_list)      {          tmp_stu = list_entry(pos, stu, list);          printf("student num: %d\tstudent name: %s\n",tmp_stu->num,tmp_stu->name);      }      mlist_move_tail(&(pstu[1].list),&stu_list); //删除节点再尾插进去     printf("把pstu[1]移至head和head->prev两个指针所指向的结点之间\n");      list_for_each(pos,&stu_list)      {          tmp_stu = list_entry(pos, stu, list);          printf("student num: %d\tstudent name: %s\n",tmp_stu->num,tmp_stu->name);      }      free(pstu);      return 0;  }




 
原创粉丝点击