仿list.h写个简易版的测试文件(完善中)~
重新修改了个代码,目前最新以这个为基准(或者后面会跟帖,当然后面更新的话这里记得提醒更新就可以了)
~话说这次实现了Common.h和Common_List.h的分离(主要是减少头文件之间的依赖性)
当然把很多对空指针进行检查的弄掉了(嗯,其实我看到strcpy(NULL,NULL)这样直接报错,知道他们那些也没对空指针进行安检,或者通常没那个用户这样使用吧)~
还有有兴趣的看看Common_List.c函数的调用或者会get到很多神奇而有趣的东西,个人感觉这也是双向环链表的价值所在
~Common.h
程序代码:
#ifndef _COMMON_H_
#define _COMMON_H_
#include<stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
#define ERR_RET (RET) return RET;
#define IS_ERR(E,RET) \
do \
{ \
if (E) \
return RET; \
}while (0)
#define COMD_SUCCESS errno==0
#ifndef NDEBUG
#include<assert.h>
#define CHECK_COND(COMD,err,ISERROR) \
do \
{ \
assert(COMD); \
}while (0)
#else
void Common_ThrowErr(int err,const char* );
#define CHECK_COND(COMD,err,ISERROR) \
do \
{ \
if (!(COMD)) \
{ \
Common_ThrowErr(err,#COMD); \
ISERROR \
} \
}while(0)
#endif
#define IS_EFAULT_RET(E,RET) CHECK_COND(E,EFAULT,ERR_RET(RET))
/*****达夫设备*****/
#ifndef DUFF_DECIVE
#define DUFF_DECIVE(NUM,E) \
{ \
unsigned int _Duff_Decive_Time=NUM>>3; \
\
if (NUM>0) \
switch (NUM&7) \
{ \
do \
{ \
case 0: E; \
case 1: E; \
case 2: E; \
case 3: E; \
case 4: E; \
case 5: E; \
case 6: E; \
case 7: E; \
}while (--_Duff_Decive_Time>0); \
} \
}
#endif
/******COMMON_NODE****/
void Common_Node_Mal(void** ,int ch,size_t size );
void Common_Node_Rea(void** ,size_t);
void Common_Node_Free(void** );
typedef const struct FUN_NODE
{
void (*Mal)(void** ,int ch,size_t size );
void (*Rea)(void** ,size_t);
void (*Free)(void** );
}FUN_NODE;
extern FUN_NODE fun_node;
/******COMMON_STRING****/
char* Comon_String_Get(FILE* ,char** ,int );
void Common_Swap(void* ,void* ,size_t );
char* Common_StrstrByKMP(const char* ,const char* ,const int** );
typedef const struct FUN_STRING
{
char* (*Get)(FILE* ,char** ,int );
void (*Swap)(void* ,void* ,size_t );
char* (*StrstrByKmp)(const char* ,const char* ,const int** );
}FUN_STRING;
extern FUN_STRING fun_string;
#ifdef __cplusplus
}
#endif
#endif
Common.c
程序代码:
#include "Common.h"
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#ifdef NDEBUG
void Common_ThrowErr(int err,const char* comd)
{
printf("\n\nAssertion failed: %s file %s, line %d\n",comd,__FILE__,__LINE__);
printf("\a\a\a\nError: %s\n\n",strerror(err));
getchar();
}
#endif
FUN_NODE fun_node=
{
Common_Node_Mal,
Common_Node_Rea,
Common_Node_Free
};
FUN_STRING fun_string=
{
Comon_String_Get,
Common_Swap,
Common_StrstrByKMP
};
static int* _InitKMPNext(const char* );
void Common_Node_Mal(void** p,int ch,size_t size)
{
IS_EFAULT_RET(p,;);
*p=malloc(size);
CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));
memset(*p,ch,size);
}
void Common_Node_Rea(void** p,size_t size)
{
void* p_new=NULL;
IS_EFAULT_RET(p,;);
p_new=realloc(*p,size);
CHECK_COND(COMD_SUCCESS,errno,Common_Node_Free(p);ERR_RET(NULL));
*p=p_new;
}
void Common_Node_Free(void** node)
{
IS_EFAULT_RET(node,;);
free(*node);
*node=NULL;
return ;
}
char* Comon_String_Get(FILE* fp,char** p,int userEof)
{
int i=0;
int c=0;
int n=BUFSIZ;
char* q=NULL;
Common_Node_Mal((void**)&q,0,BUFSIZ);
for (;(c=fgetc(fp))!=userEof&&c!=EOF;q[i++]=c)
if (i+2>n)
{
Common_Node_Rea((void** )&q,n+=BUFSIZ);
if (q==NULL)
return NULL;
}
Common_Node_Rea((void** )&q,sizeof(char)*(i+1));
if (q==NULL)
return NULL;
q[i]='\0';
*p=q;
return q;
}
void Common_Swap(void* p1,void* p2,size_t size)
{
void* pt=NULL;
IS_EFAULT_RET(p1,;);
IS_EFAULT_RET(p2,;);
Common_Node_Mal((void** )&pt,0,size);
memcpy(pt,p1,size);
memcpy(p1,p2,size);
memcpy(p2,pt,size);
Common_Node_Free(&pt);
}
char* Common_StrstrByKMP(const char* str,const char* sub,const int** p_next)
{
int* next=NULL;
size_t i=0;
size_t j=0;
size_t len=0;
if (!sub)
return NULL;
if (p_next==NULL||*p_next==NULL)
{
next=(int* )_InitKMPNext(sub);
if (next==NULL)
return NULL;
}
else
next=(int* )*p_next;
len=next[0];
next[0]=-1;
while (str[i]!='\0'&&j!=len)
if (j==-1||str[i]==sub[j])
{
++i;
++j;
}
else
j=next[j];
if (p_next==NULL)
{
free(next);
next=NULL;
}
else
{
*p_next=next;
next[0]=len;
}
return j==len?(char* )&str[i-len]:NULL;
}
static int* _InitKMPNext(const char* sub)
{
size_t i=1;
size_t j=0;
size_t len=strlen(sub);
int* next=NULL;
Common_Node_Mal((void** )&next,0,sizeof (char )*(len+1));
if (next==NULL)
return NULL;
while (sub[i]!='\0')
if (sub[i]==sub[j])
next[++i]=next[++j];
else
{
next[i+1]=++j;
while ( (j=next[j])&&sub[i]!=sub[j-1]);
++i;
}
next[0]=len;
return next;
}
Common_List.h
程序代码:
#ifndef _COMMON_LIST_H_
#define _COMMON_LIST_H_
#include<stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef void* _List_Node[2];
typedef _List_Node* _List;
#define List_Node _List_Node
#define List _List
/*****达夫设备*****/
#ifndef DUFF_DECIVE
#define DUFF_DECIVE(NUM,E) \
{ \
unsigned int _Duff_Decive_Time=NUM>>3; \
\
if (NUM>0) \
switch (NUM&7) \
{ \
do \
{ \
case 0: E; \
case 1: E; \
case 2: E; \
case 3: E; \
case 4: E; \
case 5: E; \
case 6: E; \
case 7: E; \
}while (--_Duff_Decive_Time>0); \
} \
}
#endif
#ifndef LIST_HEAD_INIT
#define LIST_HEAD_INIT(name) \
{ \
&(name), \
&(name) \
}
#endif
#ifndef LIST_HEAD
#define LIST_HEAD(name)List_Node name = LIST_HEAD_INIT(name)
#endif
/*#define LIST_HEAD_INIT(name) { &(name), &(name); }
功能
初始化一个结点名字为name的双向循环链表的头结点
参数
name:结点名字
*/
#ifndef container_of
#define container_of(ptr, type, member) ((type* )((char*)ptr-offsetof(type,member)))
#endif
/*
#define container_of(ptr, type, member)
功能
已知某一个成员变量的名字、指针和结构体类型的情况下,计算结构体的指针,也就是计算结构体的起始地址。
参数
ptr:某一个成员的指针
type:结构体类型
member:成员变量名字
*/
#ifndef list_entry
#define list_entry(ptr, type, member) \
((type*)((char*)(ptr)-(char*)(&((type *)0)->member)))
#endif
/*list_entry
#define list_entry(ptr, type, member)
功能
获取type类型结构体的起始指针
参数
ptr:type类型的结构体中member成员的指针
type:结构体类型
member:结构体中成员
返回
结构体的起始指针
*/
#ifndef LIST_FOR_EACH
#define LIST_FOR_EACH(pos,head) \
for (pos=head;(pos=Common_List_GetNext(pos))!=head;)
#endif
#ifndef LIST_FOR_PREV
#define LIST_FOR_PREV(pos,head) \
for (pos=head;\
(pos=Common_List_GetPrev(pos))!=head;)
#endif
#ifndef LIST_FOR_EACH_SAVE
#define LIST_FOR_EACH_SAVE(pos,next,head) \
for (pos=next=Common_List_GetNext(head);\
(next!=head)&&(next=Common_List_GetNext(pos));\
pos=next)
#endif
#ifndef LIST_FOR_PREV_SAVE
#define LIST_FOR_PREV_SAVE(pos,next,head) \
for (pos=next=Common_List_GetPrev(head);\
(next!=head)&&(next=Common_List_GetPrev(pos));\
pos=next)
#endif
/******COMMON_LIST****/
void Common_List_Init(List);
List Common_List_Del(List,List);
List Common_List_Del_RetPrev(List);
List Common_List_Del_RetNext(List);
List Common_List_GetPrev(List);
List Common_List_GetNext(List);
void Common_List_Add(List,List);
void Common_List_Add_Tail(List,List);
void Common_List_Init_Add(List,List);
void Common_List_Init_Add_Tail(List,List);
List Common_List_Merge(List,List);
void Common_List_Cut_Position(List,List,List);
int Common_List_IsEmpty(List);
typedef const struct F_LIST
{
void (*Init)(List);
List (*Del)(List,List);
List (*Del_RetPrev)(List);
List (*Del_RetNext)(List);
List (*GetPrev)(List);
List (*GetNext)(List);
void (*Add)(List,List);
void (*Add_Tail)(List,List);
void (*Init_Add)(List,List);
void (*Init_Add_Tail)(List,List);
List (*Merge)(List,List);
void (*Cut_Position)(List,List,List);
int (*IsEmpty)(List);
}FUN_LIST;
extern FUN_LIST fun_list;
#ifdef __cplusplus
}
#endif
#endif
Common_List.c
程序代码:
#include"Common_List.h"
FUN_LIST fun_list=
{
Common_List_Init,
Common_List_Del,
Common_List_Del_RetPrev,
Common_List_Del_RetNext,
Common_List_GetPrev,
Common_List_GetNext,
Common_List_Add,
Common_List_Add_Tail,
Common_List_Init_Add,
Common_List_Init_Add_Tail,
Common_List_Merge,
Common_List_Cut_Position,
Common_List_IsEmpty,
};
typedef enum E_LIST
{
PREV,
NEXT,
LIST_SIZE
}E_LIST;
static void _Insert(List,List,List,List);
static void _Insert(List p_front,List p_rear,List q_front,List q_rear)
{
(*p_front)[PREV]=q_rear;
(*q_rear)[NEXT]=p_front;
(*q_front)[PREV]=p_rear;
(*p_rear)[NEXT]=q_front;
}
void Common_List_Init(List list)
{
(*list)[PREV]=list;
(*list)[NEXT]=list;
}
List Common_List_Del(List list,List t_list)
{
Common_List_Add_Tail(list,list);
return t_list;
}
List Common_List_Del_RetPrev(List list)
{
return Common_List_Del(list,(*list)[PREV]);
}
List Common_List_Del_RetNext(List list)
{
return Common_List_Del(list,(*list)[NEXT]);
}
List Common_List_GetPrev(List list)
{
return (*list)[PREV];
}
List Common_List_GetNext(List list)
{
return (*list)[NEXT];
}
void Common_List_Add(List p_front,List q_front)
{
_Insert(p_front,(*p_front)[PREV],q_front,(*q_front)[PREV]);
}
void Common_List_Add_Tail(List p_front,List q_front)
{
_Insert((*p_front)[NEXT],p_front,q_front,(*q_front)[PREV]);
}
void Common_List_Init_Add(List h_list,List list)
{
Common_List_Init(list);
Common_List_Add(h_list,list);
}
void Common_List_Init_Add_Tail(List h_list,List list)
{
Common_List_Init(list);
Common_List_Add_Tail(h_list,list);
}
List Common_List_Merge(List list,List t_list)
{
List next_list=Common_List_GetNext(t_list);
Common_List_Add(list,t_list);
Common_List_Add_Tail(t_list,t_list);
return next_list;
}
void Common_List_Cut_Position(List list,List t_list,List head)
{
Common_List_Add(list,t_list);
Common_List_Add(t_list,head);
}
int Common_List_IsEmpty(List list)
{
if (list==NULL)
return 1;
return ((*list)[PREV]==list)&&((*list)[NEXT]==list);
}
main.c
程序代码:
#include"Common.h"
#include"Common_List.h"
#include<string.h>
typedef struct Node
{
int num;
char name[10];
List_Node list_node;
}Node,*P_Node;
void Insert(List,int ,const char*);
void Print(List);
void Del(List);
int main(void )
{
List p_list=NULL;
LIST_HEAD(h_list_node);
LIST_HEAD(h_t_list_node);
puts("1号链表:\n");
Insert(&h_list_node,3,"abc");
Insert(&h_list_node,4,"def");
Insert(&h_list_node,5,"ghi");
Print(&h_list_node);
puts("2号链表:\n");
Insert(&h_t_list_node,-1,"xxx");
Insert(&h_t_list_node,-2,"yyy");
Insert(&h_t_list_node,-3,"zzz");
Print(&h_t_list_node);
puts("链表合并并去头节点:\n");
p_list=fun_list.Merge(&h_list_node,&h_t_list_node);
Print(&h_list_node);
puts("链表分割并加入头节点:\n");
fun_list.Cut_Position(&h_list_node,p_list,&h_t_list_node);
puts("分割后1号链表:\n");
Print(&h_list_node);
puts("\n分割后2号链表:\n");
Print(&h_t_list_node);
Del(&h_list_node);
Del(&h_t_list_node);
return 0;
}
void Insert(List h_list,int num,const char* name)
{
P_Node p_node=NULL;
fun_node.Mal((void** )&p_node,0,sizeof (Node));
IS_ERR(p_node==NULL,;);
p_node->num=num;
strcpy(p_node->name,name);
fun_list.Init_Add(h_list,&p_node->list_node);
}
void Print(List h_list)
{
List list=NULL;
List t_list=NULL;
LIST_FOR_EACH(list,h_list)
{
P_Node p_node=list_entry(list,Node,list_node);
printf("%d\n",p_node->num);
printf("%s\n\n",p_node->name);
}
}
void Del(List h_list)
{
List list=fun_list.GetNext(h_list);
while (!fun_list.IsEmpty(h_list))
{
P_Node p_node=list_entry(list,Node,list_node);
list=fun_list.Del_RetNext(list);
free(p_node);
}
}
[此贴子已经被作者于2018-1-6 02:28编辑过]




