linux内核链表
-
内核链表的本质
本质就是双向循环链表,linux把前面我们觉得有难度,容易写错的
指针操作封装成函数,直接给我们调用,大大方便我们写代码 -
内核链表的基本的原理
linux中定义了一个结构体,用来存放指针
struct list_head
{
struct list_head *next, *prev;
};
-
内核链表提供的常用接口函数
(1) 初始化节点中next和prev指针
INIT_LIST_HEAD(参数) //宏定义
参数: 表示内核链表中用来存放指针的那个结构体(2) 插入数据
list_add_tail(struct list_head *new, struct list_head *head)
参数:new --》你要尾插的新节点中的小结构体指针
head --》链表的表头中的小结构体指针
功能一: 把new插入到head表示的链表的尾部
功能二: 把new插入到另外一个节点的前面list_add(struct list_head *new, struct list_head *head)
参数:new --》你要尾插的新节点中的小结构体指针
head --》链表的表头中的小结构体指针
功能一:把new插入到头节点和第一个有效节点之间
功能二:把new插入到另外一个节点的后面(3) 删除数据
void list_del(struct list_head *entry)
参数:entry --》你要删除的那个节点中的小结构体指针(4) 遍历链表
list_for_each_entry(pos, head, member) //宏函数,本质是for循环
参数:pos --》用来遍历内核链表的大结构体指针
head --》链表的表头中的小结构体指针
member --》小结构体在大结构体中的名字(5) 其它函数
void list_move(struct list_head *list,struct list_head *head)
void list_move_tail(struct list_head *list,struct list_head *head)
内核链表的使用:
#include "myhead.h"
#include "kernel_list.h"
//定义一个结构体表示内核链表的节点
typedef struct kerlist
{
//数据域
int data;
//指针域
struct list_head mypoint;
}klist;
//初始化内核链表的表头
klist *init_list()
{
klist *head=malloc(sizeof(klist));
//初始化指针
INIT_LIST_HEAD(&(head->mypoint));
return head;
}
//初始化节点
klist *create_node(int newdata)
{
klist *newnode=malloc(sizeof(klist));
newnode->data=newdata;
//初始化指针
INIT_LIST_HEAD(&(newnode->mypoint));
return newnode;
}
int main()
{
//初始化头结点
klist *myhead=init_list();
/* //尾插几个数据 尾插的功能一
klist *new1=create_node(10);
list_add_tail(&(new1->mypoint),&(myhead->mypoint));
klist *new2=create_node(20);
list_add_tail(&(new2->mypoint),&(myhead->mypoint));
klist *new3=create_node(30);
list_add_tail(&(new3->mypoint),&(myhead->mypoint));
//尾插的功能二
klist *new4=create_node(40);
list_add_tail(&(new4->mypoint),&(new2->mypoint)); //把new4
插入到new2的前面
*/
klist *new1=create_node(10);
list_add(&(new1->mypoint),&(myhead->mypoint));
klist *new2=create_node(20);
list_add(&(new2->mypoint),&(myhead->mypoint));
klist *new3=create_node(30);
list_add(&(new3->mypoint),&(myhead->mypoint));
//功能二
klist *new4=create_node(40);
list_add(&(new4->mypoint),&(new2->mypoint)); /*把new4插入
到new2的后面*/
//删除功能
list_del(&(new3->mypoint));
//遍历
klist *p;
list_for_each_entry(p,&(myhead->mypoint),mypoint)
{
printf("当前我遍历的链表节点中数据是:%d\n",p->data);
}
}