当前位置:   article > 正文

内核双链表篇:list.h——获取链表结点数据:list_entry、list_first_entry、list_last_entry

list_first_entry

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  

1.功能简介:

  list_entry:获取链表结点p的数据。
  list_first_entry:获取链表结点p的下一个结点的数据。
  list_last_entry:获取链表结点p的上一个结点的数据。

2.源码及注释:

/****** 获取含有链表的结构体的指针 ******/
#define list_entry(ptr, type, field) container_of(ptr, type, field)             /* 从链表指针ptr中获得包含该链表的结构体指针 */
#define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) /* 从链表指针ptr的下一指针中获得包含该链表的结构体指针 */
#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field)  /* 从链表指针ptr的上一指针中获得包含该链表的结构体指针 */
/*
    ptr:   表示和member同为相同类型的链表,此处ptr表示指向链表中的一个节点(list_head指针)
    type: 表示需要寻找的结构体类型(包含ptr的结构体类型)
    field:表示type类型的结构体里面的成员(结构体中链表字段的名字)
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.源文件测试理解步骤

main.c
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "dlist_test.h"

/* 链表节点 */
typedef struct _TestStruct
{
    struct list_head list;
    int num;
    bool pending;
    char name;
    void *pointer;
}struct_node;

static struct list_head dlist = LIST_HEAD_INIT(dlist);  /* 初始化链表: */

int main(int argc, char *argv[])
{
    struct_node *tmp,*tmp_1, *tmp_2, *tmp_3;          /* 暂存链表节点结构体 */
    struct list_head *head = &dlist;                    /* 链表表头 */
    struct list_head *p;
    int i = 0;

    //插入5个数据,使用头插法,类似于栈
    for (i = 0; i < 5; i++)
    {
        tmp = (struct_node *)malloc(sizeof(struct_node));
        tmp->num = i;
        list_add_tail(&tmp->list, head);                /* 插入链表尾部 */
    }

    /*
        功能:遍历链表
        参数:
            p :指向下一个节点的链表指针
            head:头指针
    */
    list_for_each(p,head)
    {
        tmp_1 = list_entry(p, struct_node, list); // container_of(p, struct_node, list)
        tmp_2 = list_first_entry(p, struct_node, list);
        tmp_3 = list_last_entry(p, struct_node, list);

        printf("list_entry: %d.\nlist_first_entry: %d.\nlist_last_entry: %d.\n",
               tmp_1->num, tmp_2->num, tmp_3->num);
        
        printf("------------------------------\n");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
Makefile
TARGET:=test
SRCS:=main.c
OBJS:=$(SRCS:.c=.o)#变量替换函数,将所有*.c文件替换为*.o文件,与OBJS=$(patsubst %.c,%.o,$(SRCS))等效

CC:=gcc#编译器
CFLAGS:=-Wall -std=gnu99#gcc选项

$(TARGET):$(OBJS)
	$(CC) -o $@ $^

clean:
	rm -rf $(TARGET) $(OBJS)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.结果:

xsndz@Linux:~/Desktop/list$ ./test 
list_entry: 0.
list_first_entry: 1.
list_last_entry: 0.
------------------------------
list_entry: 1.
list_first_entry: 2.
list_last_entry: 0.
------------------------------
list_entry: 2.
list_first_entry: 3.
list_last_entry: 1.
------------------------------
list_entry: 3.
list_first_entry: 4.
list_last_entry: 2.
------------------------------
list_entry: 4.
list_first_entry: 0.
list_last_entry: 3.
------------------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/128080
推荐阅读
相关标签
  

闽ICP备14008679号