论c语言代码的可重用性

  先说什么叫可重用性?顾名思义,可重用性就是指可以重复使用的特性.很多编程新手对这个概念理解不深刻.觉得代码写好了,要重复使用不就是复制再粘贴就行了吗.最多再改几个小地方.
然而这并不是代码可重用的体现!
  代码可重用的精髓,我认为可以用unix哲学的两个点来说明:

  • Write programs that do one thing and do it well. 写出来的代码只做一件事,并且把这件事作好。
  • Write programs to work together. 写出来的代码,相互之间要一起协作。

举个例子:
  比如现在有个需求,要求自己实现strlen函数,并求出一个字符串的长度,要求结果以:"the lenght of string is: ** “的形式打印出字符串的长度值.很多编程经验不多的人一看需求,心想这还不简单.信手拈来–以下是他们写的代码:

#include<stdio.h>

int main(int argc, char *argv[])  
{  
    int i = 0;  
    char *pstr = "hello";   
    //这个循环体意思是从字符串第一个字符起计数,只遇到字符串结束标志'\0’才停止计数 
        while((*pstr++)!='\0')  
        {   
            i++;  
        } 
        printf("the lenght of string is:%d\n",i);
    return 0;  
}  

  代码是实现了需求,但从设计思想的层面上看,这样写代码并不可取.这段代码有个最严重问题:
  代码并没有把'求字符串长度这件事'单独地放在一个函数中.而是全部放在main()函数中现实现.这给以后的调试带来了很多麻烦.代码简单点还勉强应付,要是在main()函数中写上几百上千行代码,调试的时候晕头转向是免不了的!
  解决的方法,可以参看一下unix的哲学-写出来的代码只做一件事,并且把这件事作好。这句话里"写出来的代码"在c语言中,可以理解为写出来的函数的意思.
  所以,改进的第一步是,先把作这一件事儿的代码作封装.即把这部分的代码单独写成一个函数,再由其他函数调用它.请看改进后的代码:

#include<stdio.h>

int mystrlen()
{
    char *pstr = "hello";   
    int i=0;
    //这个循环体意思是从字符串第一个字符起计数,只遇到字符串结束标志'\0’才停止计数 
        while((*pstr++)!='\0')  
        {   
            i++;  
        } 
        printf("the lenght of string is:%d\n",i);
}
int main(int argc, char *argv[])  
{  

    mystrlen();

    return 0;  
}  

  这个版本的代码把真正干活的代码封装成了一个函数.封装是使代码层次清晰,逻辑清楚的重要手段.我们在main()函数中只是调用了这个干活的函数,就实现了我们的需求.封装的便利性还体现在调试代码的时候,如果要分析具体干活的代码,可以跟进去看,如果不需要跟进可以一跃而过.
对于调试以及分析代码来说.封装手段必不可少!
  然而,这样写的代码还是离可重用有相当的差距.因为每次调用mystrlen()函数都是计算同一个字符串的长度.显然,我们在其他工程中不太可能都是计算"hello"这一个字符串.那可能有人要说,到时我改不就得了嘛,比如把”hello”改成"i love china”,不是也很方便吗?
  话虽如此,但要修改代码不符合可重用的基本原则.而且上面的代码逻辑简单还好,万一代码的算法比较复杂,还得程序员理清代码的思路才知道怎么修改.
  所以,代码还是有可以改进的地方的,我们再修改一个新的版本:

#include<stdio.h>

int mystrlen(const char *pstr)
{

    int i=0;
    //这个循环体意思是从字符串第一个字符起计数,只遇到字符串结束标志'\0’才停止计数 
        while((*pstr++)!='\0')  
        {   
            i++;  
        } 
        printf("the lenght of string is:%d\n",i);
}
int main(int argc, char *argv[])  
{  
    char *pch="hello";

    mystrlen(pch);

    return 0;  
}  

  这个版本中,我们把干活的函数封装起来,并且暴露出一个接口,即mystrlen(const char *pstr).只要任何函数调用这个函数接口,传入他想求长度的字符串的指针.mystrlen()函数都能完成工作.
  改到这里,好像已经趋于完善了,对吗?
  不!!!
  如果这时需求改了,变成了要求输出的长度的形式为:”+++++len is:5++++++”,即输出结果前后都有一串其他的字符来修饰.可能编程新手觉得那是不是再接着修改mystrlen()里面的代码?如果是这样的话,那和前一个版本的代码也没什么区别.可重用就是直接拿来就用.涉及到要修改代码的,统统不合适可重用原则.
  那应该怎么修改呢.我们看下unix的那两点哲学:
- Write programs that do one thing and do it well. 写出来的代码只做一件事,并且把这件事作好。
- Write programs to work together. 写出来的代码,相互之间要一起协作。

  只作一件事儿-在这个案例中,应该封装一个函数,这函数只作一件事儿,就是求长度.至于要显示成什么样,那再封装另一个函数来完成.这也是unix遵循的原则:简洁为美!
  ok,看我们怎么修改代码:

#include<stdio.h>


int mystrlen(const char *StrDest)  
{  
    int i = 0;  
    while((*StrDest++)!='\0')  
    {   
        i++;  
    }//这个循环体意思是从字符串第一个字符起计数,只遇到字符串结束标志'\0’才停止计数  
    return i;  
}  
int dowork1()
{
    char *str="hello,world";
    int len = mystrlen(str);
    printf("the lenght of string is:%d\n",len);
}
int dowork2()
{
    char *str="hello,world";
    int len = mystrlen(str);
    printf("++++len is:%d++++\n",len);
}

int main(int argc, char *argv[])  
{  

    dowork1();
    dowork2();
    return 0;  
}  

  在最终的版本中,我们把求字符串长度的逻辑代码封装成一个小函数.这个函数简单至极,而且只作一件事-即把字符串的长度作为结果返回给调用它的父函数.其他事儿一概不管!
  而在dowork1()中,调用mystrlen()函数求出相应字符串的长度后,再按照自己设想的形式输出结果.大家可以看到,dowork1()函数因此也变成很简洁.简洁的一大好处是,条理清晰,调试方便!如果要改变输出结果的形式,那再重新定义另一个函数dowork2(),这个函数里也同样调用了mystrlen()函数,并把结果按设想的作一个输出.通篇代码我们都没有对mystrlen()函数进行任何的修改.因为他只负责完成求长度的工作,工作越简单,就越能适配更多的场合.毫无疑问,mystrlen()作到了!
  而函数之间要配合工作,就能实现最终的需求.请看这条哲学:
- Write programs to work together. 写出来的代码,相互之间要一起协作。

  在main()函数中,需要实现什么功能,则调用相应的函数即可.main()函数在c语言中是一个统筹全局的函数,应该由它调配组合各种功能的函数实现不同的需求,而不应该把过多的逻辑代码入在其中.这样调试起来就会更得心应手!
  经过这几个版本的修改,我们明白了封装的重要性!如果以后在其他工程中需要求字符串的长度,上面的代码中,哪个函数可以直接移过去就能重复使用了.相信你应该明白了!

总结:要想代码可重复使用,就要学会封装.封装的原则是:相关的代码写成一个函数.其他逻辑封装成其他的若干函数.只要函数的功能切分得足够细,那么它们之间的各种调配组合就能足够灵活.也更能适应更多的场合.
  用玩积木来打个比方:一块块的积木堆叠成的一堵墙,这堵墙如果到了其他的小朋友的手中,不见得能直接就用上去.因为他们堆的城堡可能并不适合这堵墙.但如果这堵墙是拆分成足够细的单元.那其他小朋友才适合对它们进行"再创造".
所谓的代码可重复使用的思想,不过如此!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值