Constructed and traversed based on the linked list of the Linux kernel

program:


#include "stdio.h"
#include "stdlib.h"

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

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)
#define offsetof(TYPE, MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({				\
    void *__mptr = (void *)(ptr);					\
    ((type *)(__mptr - offsetof(type, member))); })

#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

#define list_first_entry(ptr, type, member) \
	list_entry((ptr)->next, type, member)

#define list_next_entry(pos, member) \
	list_entry((pos)->member.next, typeof(*(pos)), member)

#define list_for_each_entry(pos, head, member)				\
	for (pos = list_first_entry(head, typeof(*pos), member);	\
	     &pos->member != (head);					\
	     pos = list_next_entry(pos, member))

#define list_last_entry(ptr, type, member) \
	list_entry((ptr)->prev, type, member)

#define list_prev_entry(pos, member) \
	list_entry((pos)->member.prev, typeof(*(pos)), member)

#define list_for_each_entry_reverse(pos, head, member)			\
	for (pos = list_last_entry(head, typeof(*pos), member);		\
	     &pos->member != (head); 					\
	     pos = list_prev_entry(pos, member))


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

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);
}

#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 list_prepare_entry(pos, head, member) \
	((pos) ? : list_entry(head, typeof(*pos), member))

#define list_for_each_entry_continue(pos, head, member) 		\
	for (pos = list_next_entry(pos, member);			\
	     &pos->member != (head);					\
	     pos = list_next_entry(pos, member))

#define list_for_each_entry_continue_reverse(pos, head, member)		\
	for (pos = list_prev_entry(pos, member);			\
	     &pos->member != (head);					\
	     pos = list_prev_entry(pos, member))

typedef struct test_str
{
    int index;
    int value;
    struct list_head list;
}TEST_ST;

void main(void)
{
    LIST_HEAD(head);
    _Bool isEmpty=list_empty(&head);
    if(isEmpty)  { printf("list empty\n");}
    printf("\n");
    
    TEST_ST *node=(TEST_ST *)malloc(sizeof(TEST_ST));
    node->index=1;
    node->value=0;
    list_add(&node->list,&head);

    node=(TEST_ST *)malloc(sizeof(TEST_ST));
    node->index=2;
    node->value=0;
    list_add(&node->list,&head);

    node=(TEST_ST *)malloc(sizeof(TEST_ST));
    node->index=3;
    node->value=0;
    list_add(&node->list,&head);
    
    struct list_head *cur;
    list_for_each(cur, &head) {
	TEST_ST *test = list_entry(cur, TEST_ST, list);
	printf("index=%d,value=%d\n",test->index,test->value);
    }
    printf("\n");

    list_for_each_prev(cur, &head) {
	TEST_ST *test = list_entry(cur, TEST_ST, list);
	printf("index=%d,value=%d\n",test->index,test->value);
    }
    printf("\n");
    
    TEST_ST *test_cur;

    list_for_each_entry(test_cur, &head, list) {
	printf("index=%d,value=%d\n",test_cur->index,test_cur->value);
    }
    printf("\n");

    list_for_each_entry_reverse(test_cur, &head, list) {
	printf("index=%d,value=%d\n",test_cur->index,test_cur->value);
    }
    printf("\n");
    
    test_cur=NULL;
    /*如果test_cur有值,则从test_cur开始遍历,如果没有,则从链表头开始*/
    test_cur = list_prepare_entry(test_cur, &head, list);
    list_for_each_entry_continue(test_cur, &head, list) {
	printf("index=%d,value=%d\n",test_cur->index,test_cur->value);
    }
    printf("\n");
    list_for_each_entry_continue_reverse(test_cur, &head, list) {
	printf("index=%d,value=%d\n",test_cur->index,test_cur->value);
    }
    printf("\n");

}

result:

list empty

index=3,value=0
index=2,value=0
index=1,value=0

index=1,value=0
index=2,value=0
index=3,value=0

index=3,value=0
index=2,value=0
index=1,value=0

index=1,value=0
index=2,value=0
index=3,value=0

index=3,value=0
index=2,value=0
index=1,value=0

index=1,value=0
index=2,value=0
index=3,value=0

The test source file for this article: https://download.csdn.net/download/eidolon_foot/14926572

 

reference:

https://blog.csdn.net/wanshilun/article/details/79747710

https://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html

Guess you like

Origin blog.csdn.net/eidolon_foot/article/details/112998927