| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3666 人关注过本帖, 1 人收藏
标题:重写常用函数头文件(初测版)~
取消只看楼主 加入收藏
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
继续重写:~

其实感觉如果追求效率的话不调用头文件散写这样反而还高,而调用函数整理的主要目的是为了封装和模块化管理~
当然,效率还是不要太低为好……个人因为效率问题折中处理相对于10楼而言还是感觉还是把malloc模块化和realloc函数模块化分开写比较好~
还有为啥要把原来的二级指针改写成一级指针加返回值的原因是因为读取指针内容需要时间资源,这里可以优化~还有感觉参数类型变得简单了~还可以减少一些不必要的条件判断~
至于free那个模块考虑过用参数void*,free后再由用户自己设置为空,不过这样追求高效还是散写比较好~所以这个倒是没啥改动按照原来的模块~
这次还改进了异常情况判断处理~

接着还新增了一个泛型交换函数(效率到底还是不咋的,高效还是直接多写几行代码好)主要也是为了方便使用~

最后上代码~

Common.h
程序代码:
#ifndef _COMMON_H_
#define _COMMON_H_

#include<stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif

void* Common_Node_Mal(size_t size);
void* Common_Node_Rea(void* p,size_t);

void Common_Node_Free(void** );

char* Comon_String_Get(FILE* ,char* ,int );

void Common_Swap(void* ,void* ,size_t );

#ifdef __cplusplus
}
#endif

#endif

Common.c
程序代码:
#include "Common.h"

#define NDEBUG

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

#define ERR_RET(RET) return RET;
#define COMD_SUCCESS errno==0  

#ifndef NDEBUG 
#include<assert.h>

#define CHECK_COND(COMD,err,ISERROR)    \
    do    \
    {   \
        assert(COMD);    \
    }while (0)

#else

#define CHECK_COND(COMD,err,ISERROR)    \
    do    \
    {    \
        if (!(COMD))    \
        {    \
            printf("\n\nAssertion failed: " #COMD ", file %s, line %d\n",__FILE__,__LINE__);    \
            printf("\a\a\a\nError: %s\n\n",strerror(err));    \
            getchar();    \
            ISERROR;    \
        }    \
    }while(0)

#endif

void* Common_Node_Mal(size_t size)
{
    void* p=malloc(size);

    CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

    return memset(p,0,size);
}

void* Common_Node_Rea(void* p,size_t size)
{
    void* q=NULL;

    q=realloc(p,size);

    CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

    return q;
}

void Common_Node_Free(void** node)
{
    CHECK_COND(node,EFAULT,ERR_RET(;));

    if (*node==NULL)
        return ;

    free(*node);

    return ;
}

char* Comon_String_Get(FILE* fp,char* p,int userEof)
{
    int i=0;
    int c=0;
    int n=BUFSIZ;

    char* q=(char* )Common_Node_Mal(BUFSIZ);

    CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

    for (;(c=fgetc(fp))!=userEof&&c!=EOF;q[i++]=c)
        if (i+2>n)
        {
            q=(char* )Common_Node_Rea(q,n+=BUFSIZ);

            CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

        }

    q=(char* )Common_Node_Rea(q,sizeof(char)*(i+1));

    CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

    q[i]='\0';
    p=q;

    return q;
}

void Common_Swap(void* p1,void* p2,size_t size)
{
    void* pt=NULL;

    CHECK_COND(p1&&p2,EFAULT,ERR_RET(;));

    pt=Common_Node_Mal(size);

    memcpy(pt,p1,size);
    memcpy(p1,p2,size);
    memcpy(p2,pt,size);

    Common_Node_Free(&pt);
}






main.c
程序代码:
#include"Common.h"

void Check_StringFoo( void );
void Check_SwapFoo( void );

int main( void )
{
    Check_StringFoo();
    Check_SwapFoo();

    return 0;
}


void Check_StringFoo( void )
{
    char* pch=NULL;
    int len=0;

    puts("请输入字符串:");

    pch=Comon_String_Get(stdin,pch,'\n');
    puts(pch);

    Common_Node_Free((void** )&pch);

}

void Check_SwapFoo( void )
{
    int na=2;
    int nb=3;

    double fa=2.0;
    double fb=3.0;

    puts("交换前:");
    printf("na=%d,nb=%d\n",na,nb);
    printf("fa=%.4f,fb=%.4f\n",fa,fb);

    Common_Swap(NULL,&nb,sizeof(na));
    Common_Swap(&fa,&fb,sizeof(fa));

    puts("交换后:");
    printf("na=%d,nb=%d\n",na,nb);
    printf("fa=%.4f,fb=%.4f\n",fa,fb);
}




[此贴子已经被作者于2017-11-7 03:36编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-11-07 02:50
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
鉴于网上资料strstr函数源代码是朴素匹配模式(不过字符串较短小的效率还是很高的)~打算整合一个KMP算法~具体通过调用next指针获取跳转表下次使用可以提高些许效率(不过如果用户调用跳转表和字符串不匹配那就是他的责任了)~

这次主要添加了一个KMP字符串匹配算法(调试了很久基本把bug修复完毕,但还有没有bug还要有待验证)~

而且把CHECK_COND定义宏的一部分改进为函数处理(主要原因是该代码片段某个if通常执行次数很少,用宏会造成代码膨胀,算不来)~

还有输入函数那里可以改用fgets代替fgetc(前不久就发了个关于fgets缓冲区溢出处理的帖子——这个暂时还没改)~

嗯,熟悉KMP算法后如果跳转表next无需后续利用的话其实可以把构造next和查找过程耦合在一段代码里处理反而方便(通常用户只管能否打到目的而不会过分关心具体算法过程,所以那样无需提示这是用到KMP算法)~

最后上代码~

Common.h

程序代码:
#ifndef _COMMON_H_
#define _COMMON_H_

#include<stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif


#define ERR_RET(RET) return RET;
#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* comd);

#define  CHECK_COND(COMD,err,ISERROR)    \
    do    \
    {    \
        if (!(COMD))    \
            {    \
                Common_ThrowErr(err,#COMD);    \
                ISERROR    \
            }    \
    }while(0)

#endif

void* Common_Node_Mal(size_t size);
void* Common_Node_Rea(void* p,size_t);

void Common_Node_Free(void** );

char* Comon_String_Get(FILE* ,char** ,int );

void Common_Swap(void* ,void* ,size_t );

char* Common_StrstrByKMP(const char* ,const char* ,const int** );

#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

static int* _Common_InitKMPNext(const char* );



void* Common_Node_Mal(size_t size)
{
    void* p=malloc(size);

    CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

    return memset(p,0,size);
}

void* Common_Node_Rea(void* p,size_t size)
{
    void* q=NULL;

    q=realloc(p,size);

    CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

    return q;
}

void Common_Node_Free(void** node)
{
    CHECK_COND(node,EFAULT,ERR_RET(;));

    if (*node==NULL)
        return ;

    free(*node);

    return ;
}

char* Comon_String_Get(FILE* fp,char** p,int userEof)
{
    int i=0;
    int c=0;
    int n=BUFSIZ;

    char* q=(char* )Common_Node_Mal(BUFSIZ);

    
        
    for (;(c=fgetc(fp))!=userEof&&c!=EOF;q[i++]=c)
        if (i+2>n)
        {
            q=(char* )Common_Node_Rea(q,n+=BUFSIZ);

            if (q==NULL)
                return NULL;
        }

    q=(char* )Common_Node_Rea(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;

    CHECK_COND(p1&&p2,EFAULT,ERR_RET(;));

    pt=Common_Node_Mal(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* )_Common_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* _Common_InitKMPNext(const char* sub)
{
    size_t i=1;
    size_t j=0;
    size_t len=strlen(sub);
    
    int* next=(int* )Common_Node_Mal(sizeof (char )*(len+1));
    
    if (next==NULL)
        return NULL;
   
   next[0]=0;
   
   if (len!=0)
      next[1]=0;
   
   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;
}


Main.c
程序代码:
#include"Common.h"
#include<math.h>
void Check_StringFoo( void );
void Check_SwapFoo( void );


int main( void )
{

    Check_StringFoo();
    Check_SwapFoo();

    return 0;
}


void Check_StringFoo( void )
{
    char* pch=NULL;
    char* findStr=NULL;
    char* test="abcabcabac";
     
     int* next=NULL;
     
     size_t i=0;

    puts("请输入字符串:");

    Comon_String_Get(stdin,&pch,'\n');
    
    puts("字符串输出结果为:");
    puts(pch);

    findStr=Common_StrstrByKMP(pch,test,&next);


    if (next!=NULL)               
    {
        printf("模式串\"%s\"的跳转表为:\n",test); 
                
         
        printf("%-4s","Len");
        for (i=0;i<next[0];++i)
            printf("%-4c",test[i]);
        
        puts("");
        for (i=0;i!=next[0]+1;++i)   
            printf("%-4d",next[i]);
        
        puts("");
    } 
    
    if (findStr!=NULL)
        printf("找到能与\"%s\"匹配的字符串\n第一个成功匹配的下标为:%d\n",test,findStr-pch);
    else
        printf("没有找到能与\"%s\"匹配的字符串!\n",test);
        
    Common_Node_Free((void** )&pch);
    Common_Node_Free((void** )&next);
    
}

void Check_SwapFoo( void )
{
    int na=2;
    int nb=3;

    double fa=2.0;
    double fb=3.0;

    puts("交换前:");
    printf("na=%d,nb=%d\n",na,nb);
    printf("fa=%.4f,fb=%.4f\n",fa,fb);

    Common_Swap(&na,&nb,sizeof(na));
    Common_Swap(&fa,&fb,sizeof(fa));

    puts("交换后:");
    printf("na=%d,nb=%d\n",na,nb);
    printf("fa=%.4f,fb=%.4f\n",fa,fb);
}



[此贴子已经被作者于2017-11-21 23:08编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-11-21 17:42
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 16楼 丘山君
嗯,我那手机也能正常运行,其实如果用心把这几个文件拿去编译一下并且能得出运行效果已经很好了,多文件编译是基本功,用bat+cl命令或者gcc是我现在在弄的~

[此贴子已经被作者于2017-11-22 14:37编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-11-22 14:34
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
话说,p=malloc(n);时,k=p;free(k);这样试过会出问题的~因此要把那个malloc函数改进一下~

干脆从新发代码吧~

Common.h

程序代码:
#ifndef _COMMON_H_
#define _COMMON_H_

#include<stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif


#define ERR_RET(RET) return RET;
#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

void Common_Node_Mal(void** ,int ch,size_t size );
void Common_Node_Rea(void** ,size_t);

void Common_Node_Free(void** );

char* Comon_String_Get(FILE* ,char** ,int );

void Common_Swap(void* ,void* ,size_t );

char* Common_StrstrByKMP(const char* ,const char* ,const int** );

#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

static int* _Common_InitKMPNext(const char* );



void Common_Node_Mal(void** p,int ch,size_t size)
{
    *p=malloc(size);

 CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));

    memset(*p,ch,size);
}

void Common_Node_Rea(void** p,size_t size)
{
    *p=realloc(*p,size);

 CHECK_COND(COMD_SUCCESS,errno,ERR_RET(NULL));
}

void Common_Node_Free(void** node)
{
    CHECK_COND(node,EFAULT,ERR_RET(;));

    free(*node);

    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;

    CHECK_COND(p1&&p2,EFAULT,ERR_RET(;));

    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* )_Common_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* _Common_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;
}


main.c

程序代码:
#include"Common.h"
#include<math.h>
void Check_StringFoo( void );
void Check_SwapFoo( void );


int main( void )
{

    Check_StringFoo();
    Check_SwapFoo();

    return 0;
}


void Check_StringFoo( void )
{
    char* pch=NULL;
    char* findStr=NULL;
    char* test="abcabcabac";
     
     int* next=NULL;
     
     size_t i=0;

    puts("请输入字符串:");

    Comon_String_Get(stdin,&pch,'\n');
    
    puts("字符串输出结果为:");
    puts(pch);

    findStr=Common_StrstrByKMP(pch,test,&next);

                printf("模式串\"%s\"的跳转表为:\n",test); 
                
         
    printf("%-4s","Len");
    for (i=0;i<next[0];++i)
        printf("%-4c",test[i]);
        
    puts("");
    for (i=0;i!=next[0]+1;++i)   
        printf("%-4d",next[i]);
        
    puts("");
    
    if (findStr!=NULL)
        printf("找到能与\"%s\"匹配的字符串\n第一个成功匹配的下标为:%d\n",test,findStr-pch);
    else
        printf("没有找到能与\"%s\"匹配的字符串!\n",test);
        
    Common_Node_Free((void** )&pch);
    Common_Node_Free((void** )&next);
    
}

void Check_SwapFoo( void )
{
    int na=2;
    int nb=3;

    double fa=2.0;
    double fb=3.0;

    puts("交换前:");
    printf("na=%d,nb=%d\n",na,nb);
    printf("fa=%.4f,fb=%.4f\n",fa,fb);

    Common_Swap(&na,&nb,sizeof(na));
    Common_Swap(&fa,&fb,sizeof(fa));

    puts("交换后:");
    printf("na=%d,nb=%d\n",na,nb);
    printf("fa=%.4f,fb=%.4f\n",fa,fb);
}


[此贴子已经被作者于2017-12-29 16:27编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-12-19 01:39
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
借楼,写了个链表基本操作函数,可以完成基本插入,删除,合并,分解,但还有很多功能没有完善~

再补充一下代码~

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 F_NODE   
{    
    void (*Mal)(void** ,int ch,size_t size );   
    void (*Rea)(void** ,size_t);    
    void (*Free)(void** );    
}F_NODE;

extern F_NODE f_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 F_STRING   
{    
    char* (*Get)(FILE* ,char** ,int );
    void (*Swap)(void* ,void* ,size_t );
    char* (*StrstrByKmp)(const char* ,const char* ,const int** );
}F_STRING;

extern F_STRING f_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

F_NODE f_node=     
{    
        Common_Node_Mal,    
        Common_Node_Rea,    
        Common_Node_Free    
};

F_STRING f_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;
}


[此贴子已经被作者于2018-1-4 21:37编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-01-03 12:09
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
这个是链表测试,仿照linux下的list.h文件,有兴趣的可以去搜搜list.h

Common_List.h
程序代码:
#ifndef _COMMON_LIST_H_
#define _COMMON_LIST_H_

#include"Common.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 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);
void Common_List_Del(List);
List Common_List_Del_Save(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);
List Common_List_Merge(List,List);

void Common_List_Cut_Position(List,List);
void Common_List_Cut_Position_InHead(List,List,List);

int Common_List_IsEmpty(List);

typedef const struct   F_LIST
{    
    void (*Init)(List);
    void (*Del)(List);
    List (*Del_Save)(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);
    List (*Merge)(List,List);
    
    void (*Cut_Position)(List,List);
    void (*Cut_Position_InHead)(List,List,List);
    
    int (*IsEmpty)(List);
}F_LIST;

extern F_LIST f_list;

#ifdef __cplusplus
}
#endif

#endif


Common_List.c
程序代码:
#include"Common_List.h"

#ifdef NDEBUG_LIST

    #undef IS_EFAULT_RET
    #define IS_EFAULT_RET(E,RET) 

    #undef ISERR
    #define IS_ERR(E,RET) 

#endif

F_LIST f_list=
{    
    Common_List_Init,
    Common_List_Del,
    Common_List_Del_Save,
    Common_List_Del_RetPrev,
    Common_List_Del_RetNext,
    
    Common_List_GetPrev,
    Common_List_GetNext,
    
    Common_List_Add,
    Common_List_Add_Tail,
    Common_List_Merge,
    
    Common_List_Cut_Position,
    Common_List_Cut_Position_InHead,
    
    Common_List_IsEmpty,
};
typedef enum E_LIST
{
    PREV,
    NEXT,
    
    LIST_SIZE
}E_LIST;

static void _Insert(List,List,List,List);
static List _Del_Save(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;
}


static List _Del_Save(List list,List t_list)
{
    _Insert((*list)[NEXT],list,list,(*list)[PREV]);
    
    return t_list;
}

void Common_List_Init(List list)
{
   (*list)[PREV]=list;
   (*list)[NEXT]=list; 
}

void Common_List_Del(List list)
{
   
     IS_EFAULT_RET(list,;);  
     IS_EFAULT_RET((*list)[NEXT],;);  
     IS_EFAULT_RET((*list)[PREV],;);
     _Insert((*list)[NEXT],list,list,(*list)[PREV]);
    
}

List Common_List_Del_Save(List list,List t_list)
{
    IS_EFAULT_RET(list,NULL);  
     
     return _Del_Save(list,t_list);
}

List Common_List_Del_RetPrev(List list)
{
    IS_EFAULT_RET(list,NULL);
    IS_EFAULT_RET((*list)[PREV],NULL);    
    
    return _Del_Save(list,(*list)[PREV]);
}

List Common_List_Del_RetNext(List list)
{
    IS_EFAULT_RET(list,NULL);  
    IS_EFAULT_RET((*list)[NEXT],NULL);
    
    return _Del_Save(list,(*list)[NEXT]);
}

List Common_List_GetPrev(List list)
{
    IS_ERR(*list==NULL,NULL);
    
    return (*list)[PREV];
}
List Common_List_GetNext(List list)
{
    IS_ERR(*list==NULL,NULL);
    
    return (*list)[NEXT];
}

void Common_List_Add(List p_front,List q_front)
{
   IS_EFAULT_RET(p_front,;);  
   IS_EFAULT_RET(q_front,;);  
   IS_EFAULT_RET((*p_front)[PREV],;);
   IS_EFAULT_RET((*q_front)[PREV],;);
    _Insert(p_front,(*p_front)[PREV],q_front,(*q_front)[PREV]);
}

void Common_List_Add_Tail(List p_front,List q_front)
{
   IS_EFAULT_RET(p_front,;);  
   IS_EFAULT_RET(q_front,;);  
   IS_EFAULT_RET((*p_front)[PREV],;);
   IS_EFAULT_RET((*q_front)[PREV],;);
    _Insert((*p_front)[NEXT],p_front,q_front,(*q_front)[PREV]);
}

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_Del(t_list);
    
    return  next_list;
}

void Common_List_Cut_Position(List list,List t_list)
{
    IS_EFAULT_RET(list,;);  
    IS_EFAULT_RET(t_list,;);  
    IS_EFAULT_RET((*t_list)[PREV],;);  
    IS_EFAULT_RET((*list)[PREV],;);  
    
    _Insert(t_list,(*t_list)[PREV],list,(*list)[PREV]);
}

void Common_List_Cut_Position_InHead(List list,List t_list,List head)
{
    Common_List_Cut_Position(list,t_list);
    
    Common_List_Add(t_list,head);
}

int Common_List_IsEmpty(List list)
{
    IS_EFAULT_RET(list,0);
    
    return ((*list)[PREV]==list)&&((*list)[NEXT]==list);
}



main.c
程序代码:
#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=f_list.Merge(&h_list_node,&h_t_list_node);
    
    Print(&h_list_node);
    
    puts("链表分割并加入头节点:\n"); 
    f_list.Cut_Position_InHead(&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;
    
    f_node.Mal((void** )&p_node,0,sizeof (Node));
    IS_ERR(p_node==NULL,;);
    
    p_node->num=num;
    strcpy(p_node->name,name);
    
    f_list.Init(&p_node->list_node);
    f_list.Add(&p_node->list_node,h_list);
}

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=f_list.GetNext(h_list);
    
    while (!f_list.IsEmpty(h_list))
    {
        
        P_Node p_node=list_entry(list,Node,list_node);
        
        list=f_list.Del_RetNext(list);
       
        free(p_node);
    }
}



感觉还有很多功能需要完善,初步通过测试~

[此贴子已经被作者于2018-1-4 21:39编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-01-03 12:13
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
19楼稍微更了一下~
感觉还有12个遍历宏要完善,还有一大堆细节要处理~
当然现在基本的链表操作已经没问题了~

这个链表结构和传统式结构的链表的最大用处就是实现链表和数据域分离~
这样有什么用处呢~
如果某个节点需要两个链表而不是一个例如十字链表的话直接申明两个链表域就可以了~
如果把链表节点和抽象数据域或者空指针和链表节点合在一起就没那么好弄了~还是感觉这个
~

PS:还有Common.h也稍微改了一下~就是改了extern那里~
用extren主要是方便调用函数封装,不然变量名太长也笑了
变量名过短的话也不好分类还有可能会产生冲突~
所以还是封装了比较方便~
其实嘛,关于处理变量名以及分类问题C++的类做得非常好,不过这是给C用的~

extren是获取一个变量入口地址而不是定义,定义只能一次但申明却可以有很多次,所以这个定放在在头文件里面也不用考虑到变量名重复的问题(当然其它实现文件是否也含有这个变量就不好说了,总之感觉这个可能性不大,注意使用一般情况下是完全可以的)~


[此贴子已经被作者于2018-1-4 18:27编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-01-04 17:53
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
有时间或者我要写写注释了~附带一张测试效果图(哇,最近弄到手机快没电了)~

图片附件: 游客没有浏览图片的权限,请 登录注册

图片附件: 游客没有浏览图片的权限,请 登录注册

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-01-04 22:21
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
话说,有没有发现链表的合并和分割其实是同一个函数?~一模一样的~刚刚发现调用两个节点不在同一个链表上表示合并,两个节点在同一个链表上的表示分割~
其实~说到底核心就一个_Insert函数~

[此贴子已经被作者于2018-1-6 00:13编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-01-06 00:12
快速回复:重写常用函数头文件(初测版)~
数据加载中...
 
   



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

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