内核通用链表-双向循环链表

参考文档:https://blog.csdn.net/liebao_han/article/details/53956609?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1 (整体讲解通俗易懂,但这个文档中尾添加应该不对劲,自己参考分析)

 

1,链表头文件

#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H

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

static inline void INIT_LIST_HEAD(struct list_head *list)
{
	list->next = list;
	list->prev = list;
}

static inline void list_add(struct list_head *node, struct list_head *head)
{
	node->next        = head->next;
	node->prev        = head;
	head->next->prev  = node;
	head->next        = node;
}

static inline void list_add_tail(struct list_head *node, struct list_head *head)
{
	node->next        = head;
	node->prev        = head->prev;
	head->prev->next  = node;
	head->prev        = node;
}

static inline void list_del(struct list_head *node)
{	
	node->next->prev = node->prev;
	node->prev->next = node->next;
}

static inline int list_empty(const struct list_head *head)
{
	return head->next == head;
}

#define __list_for_each(pos, head) \
	for (pos = (head)->next; pos != (head); pos = pos->next)

#define __list_for_each_prev(pos, head) \
	for (pos = (head)->prev; pos != (head); pos = pos->prev)

#define __offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define __container_of(ptr, type, member) ({                      \
	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
	(type *)( (char *)__mptr - __offsetof(type,member) );})

#define container_of(ptr,type,member)\
    (type *)( (size_t)ptr - (size_t)(&((type *)0)->member) )
	
#endif

2,链表测试代码

#include <stdio.h>
#include <stdlib.h>
#include "list.h"

typedef struct _STU{
    int  id;
    char name[8];
    int  score;
    struct list_head list;
}STU;

int main(int argc, const char *argv[])
{
    struct list_head stu_list_head;

    INIT_LIST_HEAD(&stu_list_head);
	
    for(int i=0;i<5;i++)
    {
		STU* stu=(STU*)malloc(sizeof(STU));
        stu->id=i;
        sprintf(stu->name,"stu%d",i);
        stu->score=10*i;
        list_add(&stu->list,&stu_list_head);
    }

    for(int i=5;i<10;i++)
    {
		STU* stu=(STU*)malloc(sizeof(STU));
        stu->id=i;
        sprintf(stu->name,"stu%d",i);
        stu->score=10*i;
        list_add_tail(&stu->list,&stu_list_head);
    }

	struct list_head* pos = NULL;
    __list_for_each(pos,&stu_list_head)
    {
        STU* stup = __container_of(pos,STU,list);
        printf("for stu:id=%d,name=%s,score=%d\n", stup->id,stup->name,stup->score);	
		
    }

	struct list_head* pos1 = NULL;
    __list_for_each(pos1,&stu_list_head)
    {
        STU* stup = __container_of(pos1,STU,list);
        if (stup->id == 2)
        {
            list_del(pos1);
            printf("del stu:id=%d,name=%s,score=%d\n", stup->id,stup->name,stup->score);	
            free(stup);
            stup=NULL;
        }	
    }
	
    struct list_head* pos2 = NULL;
	__list_for_each_prev(pos2,&stu_list_head)
    {
        STU* stup = __container_of(pos2,STU,list);
        printf("for stu:id=%d,name=%s,score=%d\n", stup->id,stup->name,stup->score);
    }

    return 0;
}

3,测试结果

PS E:\Project\beer\struct> g++ -o list .\list.cpp
PS E:\Project\beer\struct> .\list.exe
for stu:id=4,name=stu4,score=40
for stu:id=3,name=stu3,score=30
for stu:id=2,name=stu2,score=20
for stu:id=1,name=stu1,score=10
for stu:id=0,name=stu0,score=0
for stu:id=5,name=stu5,score=50
for stu:id=6,name=stu6,score=60
for stu:id=7,name=stu7,score=70
for stu:id=8,name=stu8,score=80
for stu:id=9,name=stu9,score=90
del stu:id=2,name=stu2,score=20
for stu:id=9,name=stu9,score=90
for stu:id=8,name=stu8,score=80
for stu:id=7,name=stu7,score=70
for stu:id=6,name=stu6,score=60
for stu:id=5,name=stu5,score=50
for stu:id=0,name=stu0,score=0
for stu:id=1,name=stu1,score=10
for stu:id=3,name=stu3,score=30
for stu:id=4,name=stu4,score=40
PS E:\Project\beer\struct> .\list.exe

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值