LINUX内核链表

链表简介

链表是一种常用的数据结构,它通过指针将一系列数据节点连接成一条数据链。相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入或删除数据。链表的开销主要是访问的顺序性和组织链的空间损失。

链表的种类有很多:
单向链表、双向链表、循环链表等等。

Linux内核链表属于双向循环链表。

传统链表与Linux内核链表的区别:
传统链表一个节点包含数据域和指针域,指针域指向的位置往往时下一个或上一个节点的开始位置。传统链表的一个缺陷就是每个节点的数据域的数据类型是相同的,用户无法给每个节点安排不同的数据类型。

Linux内核链表解决了上述缺陷,它的指针域的指针指向的位置时下一个或上一个节点指针域的开始位置,这样用户可以任意指定数据域的数据类型。指针域的类型时统一的。

内核链表

结构:

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

list_ head 结构包含两个指向 list_head 结构的指针prev和next,由此可见,内核的链表具备双链表功能,实际上,通常它都组织成双向循环链表。

函数:
1、 INIT_ LIST_HEAD:创建链表
2、 list_ add:在链表头插入节点
3、 list_ add_tail:在链表尾插入节点
4、 list_ del:删除节点
5、 list_ entry:取出节点
6、 list_ for_ each:遍历链表

代码编写

mylist.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/list.h> //使用内核链表需要的头文件

struct score//自定义结构体,学生的学号和成绩
{
    int number;//数据域
    int english;
    int math;
    struct list_head list;//指针域
};

struct list_head score_head;//定义链表头结点
struct score stu1, stu2, stu3, *tmp; 
struct list_head *pos; //用于遍历链表的指针

static int mylist_list()
{
    //创建链表
    INIT_LIST_HEAD(&score_head); //创建链表,参数是头结点指针域的地址

    stu1.number  = 1;
    stu1.english = 1;
    stu1.math    = 1;

    stu2.number  = 2;
    stu2.english = 2;
    stu2.math    = 2;

    stu3.number  = 3;
    stu3.english = 3;
    stu3.math    = 3;

    //插入节点
    list_add_tail(&(stu1.list), &score_head);//在链表尾插入节点,
    list_add_tail(&(stu2.list), &score_head);//参数1节点指针域地址
    list_add_tail(&(stu3.list), &score_head);//参数2头结点指针域地址

    //遍历链表
    list_for_each(pos, &score_head)
    //第一个参数是list_head指针,第二个参数是头结点地址,要使用大括号,是for循环
    //随着遍历的进行,pos指针分别指向每一个节点
    {
        //取出节点,注意:返回值是节点指针
        tmp = list_entry(pos, struct score, list);
        //参数1:光标指针,参数2:节点类型,参数3:节点指针域名字

        printk("第 %d 号学生\n", tmp->number);
        printk("英语成绩:%d\n", tmp->english);
        printk("数学成绩:%d\n", tmp->math);
        printk("\n");
    }
    return 0;
}

static void mylist_exit()
{
    //删除节点,参数为节点的指针域地址
    list_del(&(stu1.list));
    list_del(&(stu2.list));
    list_del(&(stu3.list));
}

module_init(mylist_list);
module_exit(mylist_exit);

makefile 文件:

obj-m := mylist.o

KDIR := /home/ARM_Linux/system2/season4/First/part3/linux-ok6410 

all:
    make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm

clean:
    rm -f *.o *.ko *.order *.symvers *.bak *.mod.c
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值