list.h

本文介绍了Linux内核中的list.h头文件中的链表数据结构和操作,包括structlist_head定义、初始化、节点添加、删除、遍历等关键函数及其用法示例。

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

#ifndef LIST_H
#define LIST_H

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

//双链表的头初始化,next, prev指向自己
#define LIST_HEAD_INIT(name) { &(name), &(name) }

//通过函数初始化头
static inline void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}

//添加一个新的结点
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;
}

//头插法
static inline void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}

//尾插法
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
    __list_add(new, head->prev, head);
}

//删除某个结点
static inline void __list_del(struct list_head *prev, struct list_head *next)//将要删除的结点从链表中释放出来
{
    next->prev = prev;
    prev->next = next;
}
static inline void list_del(struct list_head *entry) //这个函数才是最后的删除函数
{
    __list_del(entry->prev, entry->next);
    entry->next = (void *)0;
    entry->prev = (void *)0;
}

//判断结点是否为空
static inline int list_empty(const struct list_head *head)
{
    return head->next == head;
}

//已知结构体中的某个成员的地址ptr,得到结构体的地址
#define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

//遍历链表, pos为链表结点, head为链表头, member为链表中的成员, type为结点类型
#define list_for_each_entry(pos, head, member, type)        \
    for (pos = list_entry((head)->next, type, member);      \
            &pos->member != (head);                         \
            pos = list_entry(pos->member.next, type, member))
#endif

本代码是从linux的list.h中搬过来的.与普通的链表的区别在与他可以挂各种链表.他是以将struct list_head和其他成员组成一个全新的结点,

typedef struct {
    struct list_head node;
    int data;
} example_t;

struct list_head example_head = LIST_HEAD_INIT(example_head );

//添加结点
example_t example1 = {
    .data = 1;
}
list_add(&example1.node, &example_head);

example_t example2 = {
    .data = 2;
}
list_add(&example2.node, &example_head);

example_t example3 = {
    .data = 3;
}
list_add(&example3.node, &example_head);

//遍历结点
example_t* pos;
list_for_each_entry(pos, example_head, node, example_t) {
    printf("%d", pos->data);
}

注意这个写法在vs中是无法编译过的, keil和iar可以编译得过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

入门->放弃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值