插个眼 , 给自己一个备份
//=文件 :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.
}