内核链表
内核链表
 内核链表是纯粹的链表结构,只有向前向后的两个指针。将内核链表嵌套到我们自己所写的,有数据的结构体里面,这样便可以将我们所输入的数据连接起来。
 参考文件:/usr/include/btrfs/list.h

下面先来分析list.h的一些基本功能。
插入数据
内核链表有很多巧妙之处,比如这里无论是头插还是尾插都是调用函数__list_add来实现。
static inline void __list_add(struct list_head *xnew,
                  struct list_head *prev,
                  struct list_head *next)
{
    next->prev = xnew;
    xnew->next = next;
    xnew->prev = prev;
    prev->next = xnew;
}
头插数据

static inline void list_add(struct list_head *xnew, struct list_head *head)
{
    __list_add(xnew, head, head->next);
}
尾插数据

static inline void list_add_tail(struct list_head *xnew, struct list_head *head)
{
    __list_add(xnew, head->prev, head);
}
删除节点
 将链表中的某个节点删除。

static inline void list_del_init(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
	INIT_LIST_HEAD(entry);
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
	next->prev = prev;
	prev->next = next;
}
查找节点
 list_for_each将每个节点从链表中取出,list_entry将取出的节点进行运算,运算结果为用户定义的结构体地址(该节点)。通过遍历加list_entry运算,便可以访问链表中每一个数据的值,也可以将符合某个数据的值的节点地址返回。

#define list_for_each(pos, head) \
	for (pos = (head)->next; pos != (head); \
        	pos = pos->next)
#define list_entry(ptr, type, member) \
	((type*)((char * )(ptr) - (unsigned long)(&((type*)0)->member)))
内核链表的使用
创建一个.c文件,包含/usr/include/btrfs/list.h。通过以上功能的分析,已经可以实现链表的增,删,改,查的功能。
#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
typedef struct kernel_list{
    int data;
    struct list_head kernel_head;
}my_kernel_list, *p_kernel_list;
int input_msg(char * msg)
{
    // 让用户输入新的数据
    int num ;
    printf("%s:" , msg);
    scanf("%d" , &num);
    while(getchar() != '\n');
    return num;
}
p_kernel_list new_node()
{
    p_kernel_list new = calloc(1, sizeof(my_kernel_list));
 
    if(NULL == new)
    {
        printf("Node creation failed\n");
        return NULL;
    }
    INIT_LIST_HEAD(&new->kernel_head);
    return new;
}
void insert_node(p_kernel_list head)
{
    p_kernel_list new = new_node();
    new->data = input_msg("Please enter the data for the header node");
    list_add(&new->kernel_head, &head->kernel_head);
}
bool display_list(p_kernel_list head)
{
    if (list_empty(&head->kernel_head))
    {
        printf("The linked list is empty. Printing failed\n");
        return false;
    }
    struct list_head *pos;
    p_kernel_list tmp;
    list_for_each(pos, &head->kernel_head)
    {
        tmp = list_entry(pos, my_kernel_list, kernel_head);
        printf("data:%d\n", tmp->data);
    }
}
void add_tail_node(p_kernel_list head)
{
    p_kernel_list new = new_node();
    new->data = input_msg("Please enter the data for the tail node");
    list_add_tail(&new->kernel_head, &head->kernel_head);
}
p_kernel_list find_node(p_kernel_list head, int fdata)
{
    struct list_head *pos;
    p_kernel_list tmp;
    list_for_each(pos, &head->kernel_head)
    {
        tmp = list_entry(pos, my_kernel_list, kernel_head);
        if (tmp->data == fdata)
        {
            return tmp;
        }
    }
    return NULL;
}
bool del_node(p_kernel_list head)
{   
    int del_data = input_msg("Please enter the data you want to delete");
    p_kernel_list del_pos;
    del_pos = find_node(head, del_data); 
    if (NULL == del_pos)
    {
        printf("Failed to delete. No data available\n");
        return false;
    }   
    list_del_init(&del_pos->kernel_head);
}
bool replace_node(p_kernel_list head)
{
 
    p_kernel_list new = new_node();
    p_kernel_list old_node;
    int del_data = input_msg("Please enter the data that needs to be replaced");
    old_node = find_node(head, del_data);
    if (NULL == old_node)
    {
        printf("Replacement failed. No data available\n");   
        return false;
    }
    int new_data = input_msg("Please enter new data");
    new->data = new_data;
    list_replace_init(&old_node->kernel_head, &new->kernel_head);
  
}
int main(int argc, char const *argv[])
{
    p_kernel_list head = new_node();
    insert_node(head);
    insert_node(head);
    add_tail_node(head);
    add_tail_node(head);
    display_list(head);
    del_node(head);   
    display_list(head);
    replace_node(head);
    display_list(head);
    return 0;
}

                
            
        
浙公网安备 33010602011771号