有备无患:自写的linux内核通用链表

插个眼 , 给自己一个备份

//=文件 :linux_list.h=//

#ifndef LIST_H
#define LIST_H

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

//双向循环链表
//以(大结构体)包含(链表节点小结构体)的方式
//实现链表模板的通用
//此包含应为实际包含,而不是包含链表指针!!!!
typedef struct node 
{
		struct node * prev;
		struct node * next;
}Node,*ListNode;


//凡涉及到大结构体的相关的函数,因大结构体的不确定性,要设为宏函数//

/*
	1.内核链表模板实现链表的通用功能
	2.增、查、删、改(“删”和“改”可在“查”的基础上仅进行链表操作)
	3.遍历(得到表头从第一到尾的的各个指针||仅for循环||)、排序
*/

//宏函数连接符 '\'的下一行开头不能有空格
 
//===================================替换功能=============================================//
/* 定义成 宏函数,,利用宏的替换性,避免函数参数类型限制,实现复用性 */
//PtrChange()将指向节点小结构体的指针转换成指向大结构体的指针

#define PtrChange(SmallPtr,BigStruct,SmallStructName)    \
((BigStruct *)((char *)SmallPtr - ((unsigned long) &((BigStruct*)0)->SmallStructName) ))	

//===================================遍历功能=============================================//
//小结构体遍历函数 小结构体指针为Pos 
#define SmallEachList(Pos,Head)   \
for(Pos=Head->next;Pos!=Head;Pos=Pos->next)

//大结构体遍历函数 小结构体指针Pos,大结构体指针BigPtr(初始要设为NULL)
#define BigEachList(Pos,Head,BigPtr,BigStruct,SmallStructName)  \
for(Pos=Head->next;Pos!=Head;BigPtr = PtrChange(Pos,BigStruct,SmallStructName),Pos =Pos->next) 
					

//===================================查询功能=============================================//

//查询功能方式的实现 //QueryNode
/*
	*实现查询的Data应该具备唯一可识别性,即主键性质
	
	一个个的去比较大结构体的数据值
	要有大结构体的数据名、要查的数据值、一个个大结构体指针、表头
	
	1.表头后链表指针的跳转      	(遍历函数)
	{
		2.链表指针转换成大结构体指针	(指针转换函数)
		3.比较大结构体内数据值    	(值比较)
	}
	4.返回的是对应大结构体指针
	参数说明:
	Pos,      		 			->自定义的小结构体变量指针
	NodeHead,  		 			->链表的头节点,表头
	BigPtr,   		 			->自定义的小结构体变量指针
	BigStruct,					->大结构体的名字  例:BigStruct ->struct bignode
	SmallStructName, 			->大结构体中定义小结构体节点的变量名
	BigStructDataName,			->大结构体中定义数据的变量名
	BigStructDataValue			->比较数据的值
	执行结果:
	*查询到对应的节点,返回对应的大、小结构体指针,存放在Pos、BigPtr中 
	*不存在则Pos、BigPtr为空
*/

//查询数据(数值)
#define QueryNode(Pos,NodeHead,BigPtr,BigStruct,SmallStructName,BigStructDataName,BigStructDataValue)  \
SmallEachList(Pos,Head)  									\
{  															\
BigPtr = PtrChange(Pos,BigStruct,SmallStructName);  		\
if(BigPtr->BigStructDataName==BigStructDataValue)   		\
break;														\
} 															\
if(BigPtr->BigStructDataName!=BigStructDataValue )    		\
{Pos=NULL;             										\
BigPtr=NULL;    											\
}
//查询字符串
#define QueryNodeStr(Pos,NodeHead,BigPtr,BigStruct,SmallStructName,BigStructDataName,BigStructDataValue)  \
SmallEachList(Pos,Head)  									\
{  															\
BigPtr = PtrChange(Pos,BigStruct,SmallStructName);  		\
if(strcmp(BigPtr->BigStructDataName,BigStructDataValue)==0) \
break;														\
} 															\
if(strcmp(BigPtr->BigStructDataName,BigStructDataValue)!=0) \
{Pos=NULL;             										\
BigPtr=NULL;    											\
}

	
//==================================删除功能==============================================//
  //删除节点
#define DeleteNode(Pos,BigPtr)   	\
\
Pos->prev->next = Pos->next;	\
Pos->next->perv = Pos->prev;	\
Pos->next = NULL;				\
Pos->prev = NULL:				\
free(BigPtr);					\
BigPtr = NULL;					
		
//==================================修改数据功能==============================================//

//BigPtr的获得通过查询函数获得
#define ModifyData(BigPtr,DataName,NewDataValue)  \
BigPtr->DataName =NewDataValue;

#define ModifyDataStr(BigPtr,DataName,NewDataValue)  \
strcpy(BigPtr->DataName, NewDataValue);





//=========================================================================================//



ListNode ListInit(ListNode Head)
{
		Head->prev = Head;
		Head->next = Head;
		return Head;
}

//头插连接
void InsertTopNode(ListNode new,ListNode Head)
{
	/*在Head和Head->next 之间插入*/
	
	//使新节点连接
	new->next =Head->next;
	new->prev =Head;
	//原节点连接新节点
	Head->next = new;
	new->next->prev=new;
	
}
//尾插连接
void InsertTailNode(ListNode new,ListNode Head)
{
	/*在Head和Head->prev 之间插入*/
	
	//使新节点连接
	new->next =Head;
	new->prev =Head->prev;
	//原节点连接新节点
	Head->prev = new;
	new->prev->next=new;
	
}

#endif

测试代码.


#include	<stdio.h>
#include	<stdlib.h>
#include	<errno.h>
#include	<string.h>
#include	<strings.h>
#include  "Kernel_list.h"
typedef struct drink{
	char name[20];
	float price;
	int num;
	Node DrinkNode;	
}Drink;

Drink * newDrink(ListNode Head,char*str,float price,int num)
{

	Drink* newDrink = malloc(sizeof(Drink) );
	strcpy(newDrink->name ,str);
	newDrink->price =price;
	newDrink->num =num;
	InsertTopNode(&newDrink->DrinkNode,Head);
}
int main(void)
{
	//1.链表初始化
	ListNode Head  = malloc(sizeof(Node) );
	Head = ListInit(Head);

	printf("=========[%d]======\n",__LINE__);
	//2.新建节点,并插入队列
	newDrink(Head,"malk",4.5,1);
	printf("=========[%d]======\n",__LINE__);
	newDrink(Head,"jkll",5,2);
	newDrink(Head,"YiLi",4,3);
	newDrink(Head,"Hong Kong",4.2,4);
	newDrink(Head,"AnMuXi",4.1,5);
	//查询节点
	ListNode Pos;
	Drink * BigPtr;
	QueryNode(Pos,Head,BigPtr,Drink,DrinkNode,num,5);
	printf("=========[%d]======\n",__LINE__);
	if(BigPtr!=NULL)
	printf("Drink:%s price:%.1lf\n",BigPtr->name,BigPtr->price);
	else
		printf("BigPtr is NULL\n");

	QueryNodeStr(Pos,Head,BigPtr,Drink,DrinkNode,name,"jkll");
	printf("=========[%d]======\n",__LINE__);
	if(BigPtr!=NULL)
	printf("Drink:%s price:%.1lf\n",BigPtr->name,BigPtr->price);
	else
		printf("BigPtr is NULL\n");

	//3.
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值