LINUX链表学习

本文详细介绍了Linux内核中的链表数据结构及其初始化和操作方法,包括双向循环链表的初始化过程,以及如何通过list_add和list_add_tail函数进行链表元素的头部和尾部插入,展示了链表在实际应用中的实现细节。

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

      使用前需要初始化,内核链表的结构是个双向循环链表,只有指针域,数据域根据使用链表的人的具体需求而定。

        两种初始化方法

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

static inline void INIT_LIST_HEAD(struct list_head *list)

{

     list->next = list;

     list->prev = list;

}

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

定义一个链表

struct list_head RTPbuf_head;

然后初始化。

第一种:INIT_LIST_HEAD(&RTPbuf_head);

这个是调用函数,让其头尾指向一个地址。

第二种:struct list_head RTPbuf_head = LIST_HEAD_INIT(RTPbuf_head);

展开后就是:

struct list_head RTPbuf_head = {&(RTPbuf_head),&(RTPbuf_head)};

就是初始化结构体。list头指向尾。双向链表

添加链表成员两种方法

1.

static HPT_INLINE void list_add(struct list_head *_new, struct list_head *head)
       {
            __list_add(_new, head, head->next);
       }
     static HPT_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;
    }
list_add函数,可以在链中增加节点,该函数为头插法,即每次插入的节点都位于上一个节点之前,
比如上一个节点是head->1->next,本次使用头插法插入之后,链表结构变成了 head->2->1->next。

这种就是先进后出。

2.

static HPT_INLINE void list_add_tail(struct list_head *_new, struct list_head *head)
      {
           __list_add(_new, head->prev, head);
      }    
      该函数向尾部添加。prev-->>head prev-->1-->head       prev-->1-->2-->head

这种是先进先出模式。

 

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "include/linux/list.h"
struct list_head RTPbuf_head;

typedef struct _rtpbuf
{
	
	int  len;
	char * buf;
	struct list_head list;
}RTPbuf_s;

int main(int argc,char **argv)
{
	int i=0;
	RTPbuf_s *p;

	INIT_LIST_HEAD(&RTPbuf_head);
	for(i=0;i<10;i++)
	{
		 	p= (RTPbuf_s *)malloc(sizeof(RTPbuf_s));
			p->buf = (char *)malloc(10+i);
			p->len=10+i;
			memset(p->buf,10+i,p->len);
			list_add_tail(&(p->list),&RTPbuf_head);
	}

	while(1)
	{
        /***********************************************************************
            static HPT_INLINE int list_empty(struct list_head *head)
            {
	            return head->next == head;
            }
            头等于尾说明链表为空。
        ************************************************************************/
		if(!list_empty(&RTPbuf_head))
		{
            /***************************************************************************
	        #define get_first_item(attached, type, member) \	
	        ((type *)((char *)((attached)->next)-(HPT_UPTR)(&((type *)0)->member)))
	        由结构体成员list地址找到该结构体的地址
            ***************************************************************************/
			p=get_first_item(&RTPbuf_head,RTPbuf_s,list);
			for(i=0;i<p->len;i++)
			{
				printf("%d-",p->buf[i]);
			}
			printf("\n");	
			list_del(&(p->list));
			free(p->buf);
			free(p);
			p = NULL;
		
		}
		else
		{
			break;
		}
		sleep(1);
	}
	
	return	0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值