list 移植与基本使用

这篇博客介绍了如何移植Linux内核中的list.h文件,并展示了在用户空间中使用list链表进行增删查改的基本操作。

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

1. 概述:
该demo主要实现list链表的基本使用, 增删查改
list.h 移植 linux-4.9.37\include\linux\list.h

2. 测试:
在这里插入图片描述

/*
linux-4.9.37\include\linux\list.h
*/

/*
static inline
内联函数, 节省函数调用所需的栈空间, 执行效率高
*/

/*
双链表结构, 是一个双向循环链表, 或者说是双向环形链表
*/
struct list_head {
   
   
    struct list_head *next, *prev;
};

/*
初始化已经定义过的变量
*/
#define LIST_HEAD_INIT(name) {
     
      &(name), &(name) }

/*
定义struct list_head类型头指针, 并且初始化
*/
#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

/*
初始化链表头指针head, 将prev和next元素都指向list本身
*/
static inline void INIT_LIST_HEAD(struct list_head *list);

/*
添加new节点到head之后, head是链表头
*/
static inline void list_add(struct list_head *new, struct list_head *head);

/*
添加new节点到head之前, head是链表头
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head);

/*
删除链表节点entry
*/
static inline void list_del(struct list_head *entry);

/*
判断链表是否为空, 也可以判断链表中任意一个节点是否为空
*/
static inline int list_empty(const struct list_head *head);

/*
获取链表中某个节点的地址
*/
#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_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

/*
*/
#define list_for_each_safe(pos, n, head) \
    for (pos = (head)->next, n = pos->next; pos != (head); \
        pos = n, n = pos->next)

/*
遍历链表
*/
#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))

/*
list_for_each_entry的安全版, 当遍历过程中涉及到删除节点的时候, 使用该宏函数
*/
#define list_for_each_entry_safe(pos, n, head, member)            \
    for (pos = list_first_entry(head, typeof(*pos), member),    \
        n = list_next_entry(pos, member);            \
         &pos->member != (head);                     \
         pos = n, n = list_next_entry(n, 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))
/*
    From : https://github.com/paiminlin/PM
    From : https://blog.youkuaiyun.com/lpaim/article/details/114681720
    Author : PaiMin.lin
    Date : 2022.8.21
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define LPM
#include "list.h"

#ifdef __cplusplus
extern "C"{
   
   
#endif

#define Demolist_MAIN_DEBUG
#ifdef Demolist_MAIN_DEBUG

#define MAX_BUF         64

struct file_name_info
{
   
   
    int index;
    char name[MAX_BUF];
    struct list_head list;
};

int main(int argc, char *argv[]) {
   
   

    int i = 0;
    struct file_name_info * pfileinfo = NULL;
    struct file_name_info * ptmpfileinfo = NULL;

    LIST_HEAD(filehead);

    printf("*** insert the file list ***************************\n");
    pfileinfo = NULL;
    for(i = 0; i < 5; i++){
   
   
        pfileinfo = (struct file_name_info *)malloc(sizeof(struct file_name_info));
        pfileinfo->index = i + 1;
        snprintf(pfileinfo->name, sizeof(pfileinfo->name), "%d.txt", pfileinfo->index);
        list_add(&pfileinfo->list, &filehead);
    }

    printf("*** printf the file list ***************************\n");
    pfileinfo = NULL;
    list_for_each_entry(pfileinfo, &filehead, list){
   
   
        printf("file index : %d name : %s\n", pfileinfo->index, pfileinfo->name);
    }

    printf("*** change the 3 node ******************************\n");
    pfileinfo = NULL;
    list_for_each_entry(pfileinfo, &filehead, list){
   
   
        if(pfileinfo->index == 3){
   
   
            snprintf(pfileinfo->name, sizeof(pfileinfo->name), "%s.txt", "change");
            break;
        }
    }

    printf("*** printf the file list ***************************\n");
    pfileinfo = NULL;
    list_for_each_entry(pfileinfo, &filehead, list){
   
   
        printf("file index : %d name : %s\n", pfileinfo->index, pfileinfo->name);
    }

    printf("*** delete the 3 node ******************************\n");
    pfileinfo = NULL;
    ptmpfileinfo = NULL;
    list_for_each_entry_safe(pfileinfo, ptmpfileinfo, &filehead, list){
   
   
        if(pfileinfo->index == 3){
   
   
            list_del(&(pfileinfo->list));
            free(pfileinfo);
            break;
        }
    }

    printf("*** printf the file list ***************************\n");
    pfileinfo = NULL;
    list_for_each_entry(pfileinfo, &filehead, list){
   
   
        printf("file index : %d name : %s\n", pfileinfo->index, pfileinfo->name
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值