美文网首页
c语言函数接口设计的一些问题

c语言函数接口设计的一些问题

作者: qianlihu | 来源:发表于2017-11-24 19:33 被阅读131次

    在这里不记录模块功能划分等问题,假定函数接口功能已有明确的定义。这样的话就把讨论局限在了函数名,传入,传出参数的设计上了。

    传出参数(不一定指返回值)

    1. 通常情况下,返回值都是int类型的数据,返回0代表函数执行成功,负数代表失败。
    #define         SUCCESS                      0
    #define         TIMEOUT                      1
    #define         PARAM_VALID                  2
    
    int do_something()
    {
            if()
                return TIMEOUT;
           if()
               return  PARAM_VALID;
          return SUCCESS;
    }
    
    1. 返回值尽量不要是指针类型
    //返回值该不该,能不能释放?很难从接口看出来
    struct fan  *get_fan_info(int id)
    {
        static struct fan  fan;
         fan.xx = xx;
         ....
         return &fan    //此时不用释放返回值,函数不可重入
    
        struct fan *fan = malloc(sizeof(*fan));
        fan->xx = xx;
        ....
        return fan  //需要释放返回值,函数可重入。
    }
    
    void fan_list()
    {
        int i;
        struct fan *f;
        for(i=0;i<MAX;i++){
                f = get_fan_info(i);
                printf(...about fan..);
                free(f) ;   //到底要不要执行这句。????
        }
    
        get_fan_info(i);// 只是单纯的调一下这个函数,可是会不会内存泄漏???
    }
    

    此时我们可以把接口设计成这样

    //返回值该不该,能不能释放?很难从接口看出来
    int get_fan_info(struct fan *fan,int id) 
    {
        fan->xx = xx;
        ...
       return SUCCESS;
    }
    
    void fan_list()
    {
        int i;
        struct fan fan;  //参数在栈空间上
        for(i=0;i<MAX;i++){
                get_fan_info(&fan,i); 
                printf(...about fan..);
        }
      
       get_fan_info(&fan,1) ;//只是单纯的调一下这个函数,会不会内存泄漏??
    }
    

    上面的实现,其实很好的贯彻了 谁申请,谁释放的标准。

    1. 有些情况下,返回值为指针效果很好
    struct student *student_new(int id,const char *name);  //从函数名便可以看出,此返回值为malloc出来的。
    
    //另外一些明确知道返回的指针所引用的变量,生命周期较长的。
    struct student *student_find_by_name(const char *name);//从内存查找一个student.
    //此类接口有风险,需要程序员明确内存关系,最好有良好的注释。
    
    1. 返回值不应该为结构体。这里就不做具体讨论了。

    传入参数

    在函数内部最好不要破坏传入参数的内存结构,传入参数的排列顺序最好要有逻辑性。

    1. 不要破坏传入参数的内存结构
    int send_request(const char *method,cJSON *param)
    {
            ....
            free(param);
    }
    
    int do_something()
    {
         cJSON *param = cJSON_CreateObject();
         cJSON_AddNumberToObject(param,"speed",123);
         send_request("set_fan_speed",param);
         cJSON_Delete(param);    //此时会段错误
    }
    

    其实上面代码主要问题是破坏了谁申请谁释放的原则。

    1. 传入参数的顺序要有一定的逻辑性
    //注意都是dest在钱,src在后
    void* memcpy(void *desc,const void  *src,size_t n);
    char *strcpy(char *desc,const char *src);
    //思考此时为什么返回值设计为指针类型??
    //第一个参数为struct student *
    int student_set_id(struct student *s,int id);
    int student_set_name(struct student *s,const char *name);
    
    1. 传入参数的变量名,一定要表意清晰,尽量不用缩写,内部变量可使用缩写。
    int student_set_name_by_id(struct student *student,const char *name)
    {
           struct student *s = student_find_by_name(name); //内部采用缩写,参数不用缩写。
           if
              ...
          return SUCCESS;
    }
    

    函数名

    函数名要表意清晰,遵守命名规范。几个典型示例如下:

    struct student *student_new();
    void student_destroy(struct student *student);
    
    struct student *student_find_by_id(int id);
    struct student *student_find_by_name(const char *name);
    
    

    相关文章

      网友评论

          本文标题:c语言函数接口设计的一些问题

          本文链接:https://www.haomeiwen.com/subject/uevfbxtx.html