我所理解的内核链表

本文探讨了内核链表的特性,包括其作为双向循环链表的结构,指针域的定义以及如何初始化、插入、遍历和删除节点。重点介绍了内核链表头文件`kernel_list.h`中的相关宏和函数,如`INIT_LIST_HEAD`、`list_add`系列、`list_entry`及遍历宏`list_for_each`等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内核链表

内核链表与传统链表不一样,传统链表数据域与指针域都是用户自定义的,而是内核链表数据域是用户定义,但是指针域是内核链表头文件中已经定义好的了。

内核链表 :头节点无效,双向循环链表

指针域结构体的结构

内核链表头文件:kernel_list.h

struct list_head {
   
	struct list_head *next;  -> 后继指针   -> 指向下一个节点指针域的结构体的地址
	struct list_head *prev;  -> 前驱指针   -> 指向上一个节点指针域的结构体的地址
};
设计节点模型
struct list_node{
   
	//数据域
	int a;
	//指针域
	struct list_head list;  -> 里面已经包含了两个指针。
};
学习内核链表的增删改查
  1. 初始化空链表?
    1)为头节点申请堆空间
    head = (struct list_node *)malloc(sizeof(struct list_node));

2)为头节点指针域赋值
INIT_LIST_HEAD(&(head->list));

解析:
kernel_list.h ->49行:

#define INIT_LIST_HEAD(ptr) 
do{
   
	(ptr)->next = (ptr);  -> 头节点指针域的后继指针指向头节点的指针域结构体 
	(ptr)->prev = (ptr);  -> 头节点指针域的前驱指针指向头节点的指针域结构体
}while(0)
  1. 插入数据到链表中
    1)为新的节点申请空间
  struct list_node *Node = NULL;
  Node = (struct list_node *)malloc(sizeof(struct list_node));

2)为数据域赋值
Node->a = num

3)调用尾插/头插的函数
尾插:list_add_tail(&(Node->list),&(head->list));
头插:list_add(&(Node->list),&(head->list));

分析插入数据函数接口:

函数一: 将一个节点new插入两个节点next与prev之间。

static inline void __list_add(struct list_head *new,   -> 新节点的指针域结构体的地址
			      struct list_head *prev,  -> 新节点前一个节点的指针域结构体的地址
			      struct list_head *next)  -> 新节点后一个节点的指针域结构体的地址
{
   
	next->prev = new;
	new->next = next;
	new->prev = prev;
	prev->next = new;
}

函数二: 尾插


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值