| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3462 人关注过本帖, 1 人收藏
标题:重写常用函数头文件(初测版)~
只看楼主 加入收藏
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:50 
为什么你会觉得调用函数的开销比多一个if要小?而且被调用的函数里还多调用了一次memset。

相比较我的代码,你的代码里判断的次数并没有减少,我指的是循环里的判断,而且还多了两个函数的调用开销。

[此贴子已经被作者于2017-11-5 18:44编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-11-05 18:43
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 11楼 renkejun1942
嗯,照你这样说不调用函数直接把东东写在main里效率最高~效率这东东是相对而言的~好比如你那个程序通常0.0010s内完成而我那个0.0011s内完成小规模差别约等于0~
况且泛型模板实现处理数据类型需要消耗时间效率是会差一点的~要高效的话干脆不调用模板直接指明具体类型罢了~最高效不过感觉比较有喜感的是不用函数用宏或者直接把那些东东写进main里~

当然还有另一种思想就是像我一楼的为了节约一个if而多写很多编译开关,但感觉这样别扭太多了~

你看到的是调用函数要压栈的开销这些本质性的问题~我更关注的是能否用最简单的方法达到目的,然后再看效率问题~

当然C99支持内联函数关键字inline就不存在因函数调用而影响效率这个问题了~但inline有宏的特点~是直接展开代码的,所以解决方法就像你说的那样把realloc也放进那个函数里~看看可读性、可维护性和那些细节效率之间如何权衡吧~

[此贴子已经被作者于2017-11-5 19:33编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-11-05 19:29
像风像水
Rank: 2
等 级:论坛游民
帖 子:5
专家分:62
注 册:2017-11-4
收藏
得分:0 
以下是引用九转星河在2017-11-5 19:29:37的发言:
当然还有另一种思想就是像我一楼的为了节约一个if而多写很多编译开关,但感觉这样别扭太多了~

那样的代码直接让人觉得是刚学会全部语法的新手写的,抓不住影响程序性能的主次要因素。写得那么复杂,代码量大太多了,很容易引起一大堆bug,调试起来复杂度成倍的增加。工作量大了,程序的可维护性和可靠性降低,别人不愿意维护这样的代码,这是很危险的。更多的时候可靠性和稳定性比性能更重要。
后面的代码就比你开始的好很多。
收到的鲜花
  • 九转星河2017-11-05 23:04 送鲜花  10朵   附言:说得好~就是这样!~
2017-11-05 21:55
九转星河
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: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:87
专家分:154
注 册:2017-11-15
收藏
得分:0 
楼主厉害,我完全看不懂,哈哈哈啊,但是楼主这种态度很佩服。
2017-11-22 12:52
九转星河
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
快速回复:重写常用函数头文件(初测版)~
数据加载中...
 
   



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

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