仿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编辑过]