| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1064 人关注过本帖
标题:仿list.h写个简易版的测试文件(完善中)~
只看楼主 加入收藏
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
结帖率:99.25%
收藏
 问题点数:0 回复次数:4 
仿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编辑过]

搜索更多相关主题的帖子: list NULL void char next 
2017-06-20 02:59
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
static void List_Add(list_head* p_new,list_head* next,list_head* prev)//为什么不增加参数,用这个参数来决定是有序插入,还是无序插入,无序插入是尾插还是首插。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-06-20 05:58
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 2楼 renkejun1942
那个是参考list.h的~是一个间接调用函数~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-06-20 09:08
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
参考了linux内核的list.h更新了很多宏定义和函数~只声明了还没有进行定义~有时间再把那些函数补充完整~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-06-25 08:22
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
一楼有个最新版本,这贴还是可以好好利用的~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-01-06 02:10
快速回复:仿list.h写个简易版的测试文件(完善中)~
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024545 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved