首页 > 代码库 > 让你提前认识软件开发(46):首先是为人编写程序,其次才是计算机

让你提前认识软件开发(46):首先是为人编写程序,其次才是计算机

第3部分 软件研发工作总结

首先是为人编写程序,其次才是计算机

 

       “首先是为人编写程序,其次才是计算机”,这是软件开发的基本要点,软件的生命周期贯穿于产品的开发、测试、生产、发布、用户使用、版本升级和后期维护等长期过程中,只有易读、易维护的软件代码才具有生命力。

        在实际的软件开发过程中,可能是由于工作很忙的原因,很多开发人员只注重实现程序的基本功能,而忘记了编程规范,因此写出来的代码只能让计算机看懂,人要看懂很不容易。更有甚者,有些项目组为了赶进度,明确要求组员以实现产品功能为主,代码能够运行起来就可以了。低要求产生低质量的代码,既然“上头”都这样要求了,那还有必要写出“让人能够读懂”的代码吗?

        进度是赶上了,产品也交付出去了,一切看来是OK的,但问题也就来了。前方频发产品故障的消息,后方开发人员不停地扑火。这个时候,他们才发现之前别人写的代码很难读懂,甚至连阅读自己写的代码都十分的困难,真是悔不当初。如果当时能够将代码写规范一点,文档配备齐全一点,何至于此?

       大家先来看下面这段代码:

#include <stdio.h>

void main()

{

   float fun(int n);

   int n;

   float y;

   printf("input an integer number: ");

   scanf("%d", &n);

   y = fun(n);

   printf("%d!=%10.0f\n", n, y);

}

 

float fun(int n)

{

   float y;

 

   if(n<0)

     {

   printf("n<0, dataerror!");

}

       else

             if(n == 0 || n == 1)

             f=1;

       else

             f= fun(n-1)*n;

       return(f);

}

 

        大家发现了哪几处问题?

        对于以上程序,至少存在以下问题:

        第一,变量命令不规范,而且没有初始化。对于该程序,main函数里的变量nyfun函数里面的变量f的命名均不规范,不能让人一眼就看出它是什么意思、要做什么操作。这对于一小段程序来说,影响还不是很大,但如果代码行数达到数千行,那么阅读起来就比较的费力。另外,以上说的三个变量只是定义了,并没有初始化,这在实际项目中也是不允许的。

        第二,函数的命名不规范,且没有在主函数开始之前进行声明。本程序中的fun函数表示什么意思?如果你没有看程序开始之前的文字,那么只有通过阅读函数里面的代码才能知道。在实际项目中,函数命名非常的重要,因为一般涉及到函数个数较多,如果不能通过函数名称来了解其作用,而必须通过阅读代码才能获悉,那么工作效率是很低的(而且让你有打人的冲动)。此外,我们一般不在调用该函数的函数的内部来对被调函数进行声明,而是应该将声明放在外部,最好新建一个头文件来对程序里面出现的函数进行声明。

        第三,程序代码排版不工整,“ifelse”语句书写不规范。在fac函数中,存在排版不工整的情况。第一个if语句下面的大括号应该与“if”的“i”保持在同一列上,第二个“else”应该与第二个“if”保持在同一列上,“f=1;”和“f=fac(n-1)*n;”应该再缩进4个空格。另外,“if”和“else”下面的执行语句不管有多少行,都应该用“{}”括起来,以方便阅读。

第四,程序注释过少,函数开头没有注释。一般说来,在程序的关键语句的前面或右边,都应该添加适当的注释,这对程序的理解有辅助的作用。函数fac的前面应该加注释,说明此函数的功能、输入/输出参数、返回值、修改记录等。在整个程序的开头处,也要添加版本信息、修改记录等注释信息,以方便日后查阅。

        第五,“main”函数的返回值类型不规范且无输入参数。在《C陷阱与缺陷》一书中,作者建议为main函数提供返回值。因此,最好将“void”修改为“int”,以提供返回值,满足编程规范的要求。此外,对于无输入参数的函数,尽量用“void”来表示输入参数。

        第六,程序中出现了“printf”、“scanf”和“main”函数。这是大家都习以为常的,但在实际的项目中,几乎不可能出现这三个函数。因为公司都有自己的开发平台,而且代码都达到数千行,甚至上万行,很多都不是基于VC开发的,你在哪里去输入,又在哪里去看输出呢?我一进公司,最开始看到程序,就想去找“printf”、“scanf”和“main”,但这是徒劳无功的,因为根本就没有。关于输入/输出,开发中会有专门的消息处理流程来处理,大家需要知道的就是一个完整的程序不一定非要有上面的三个函数。

 

        短短几十行代码,就有如此多的问题。如此书写代码,只能让计算机看懂,“人”是很难看懂的。

 

        那么,我们如何写出让“人”能够看懂的代码呢?这个过程不能一蹴而就,要循序渐进,要从我做起,从身边做起,不断地提升个人编程的境界。

        可以考虑从以下几个方面入手:

        第一,对新入职的员工进行软件编程规范的培训,在刚开始工作中的时候,让他们严格参照编程规范来编写代码。越是早地开展编程规范的训练,越是能够早地养成编写规范代码的习惯,写出的代码也就越清晰。顺便说句题外话,很多IT公司没有这方面的意识,只顾对企业文化进行培训,以为这样就能够让员工的忠诚度增加。实际上,这只是个异想天开的做法。

        第二,定期在项目组开展编程规范方面的主题讨论,强化大家的意识。老员工写出的代码对新员工有示范的作用,如果老员工写出的程序都是可读性很差的,那么新员工会怎么想呢?他们又会怎么做呢?很多开发人员每天只顾埋头苦干,却忽略了一些最基本的东西,因此能力很难再次得到提升。在编写完代码之后,不要就以为事情做完了,还要编写一些项目文档,如版本详细设计文档等。在这些文档里面,把自己的思路写清楚,方便以后自己或他人查阅起来能够很快理解程序思路。

        第三,开发人员严格按照公司制定的编程规范来书写代码。变量如何命名?函数如何命名?注释如何写?代码如何排版?这些都有严格的要求,作为一个合格的软件开发工程师,编写规范的代码是基本的要求。当我们阅读到书写优美的代码的时候,是不是心里面会觉得很爽?从某种程度上来说,代码编写的规范程度可以体现一个程序员的态度和专业素养。

        第四,项目组要严格执行同行评审流程。大部分IT公司为了提高产品的质量,都有一个叫做“同行评审”的流程,也就是让项目组成员相互检查各自的成果,大家相互学习、取长补短、共同提高。但是,可能是中国文化的影响,大家都比较顾及面子,因此不愿意将对他人真实的想法表达出来,也使得“同行评审”流于形式。当然,也许你对别人的程序确实没有意见,那就另当别论了。对他人开诚布公地提意见并不是冒犯,而是大家相互学习的一种很好的方式。

        第五,最重要的是,个人要有编写规范代码的意识,要不断地学习各种提高编程能力的技术。不管别人对你怎么说,如果你本人不想把程序写好,那么纵使万般外力,又如何?程序员虽然工作很忙,但也要抽时间来学习新的技术,这样才不会被新技术淘汰掉。“活到老,学到老”,这句话尤其适用于现在这个大数据时代。

 

       “长风破浪会有时,直挂云帆济沧海”,对于很多人来说,编写出能够让计算机读懂的程序就已经足够了,但如果想要成为一位优秀的软件开发工程师,那么就要力求写出让“人”能够很容易看懂并领会的代码。这是一个长期的过程,大家要有“万里长征”的准备,要有“愚公移山”的精神。

 

        最后,附上之前代码规范化后的样式:

 

/***************************************************************

*版权所有 (C)2014, company name

*

*文件名称:example.c

*内容摘要:用于示范如何给变量和函数做规范的命名

*其它说明:无

*当前版本:V1.0

*    者:周兆熊

*完成日期:20140813

*

*修改记录1  // 修改历史记录,包括修改日期、版本号、修改人及修改内容等

*   修改日期:

*   版本号:

*   修改人:

*   修改内容:

***************************************************************/

 

#include <stdio.h>

 

typedef signed int INT32;                   // 重定义数据类型

 

float ProcessFactorial(INT32 iInputValue);     // 函数声明

 

/****************************************************************

*功能描述:主函数

*输入参数:无

*输出参数:无

*返 回 值:无

*其它说明:无

*修改日期            版本号          修改人         修改内容

* --------------------------------------------------------------------------------------------

* 20140813         V1.0            周兆熊           创建

***************************************************************/

INT32 main(void)

{

  INT32 iInputValue = http://www.mamicode.com/0;

   float  fResult    = 0.0;

 

   printf("input an integer number: ");

   scanf("%d", &iInputValue);

 

   fResult = ProcessFactorial(iInputValue);     // 调用求阶乘的函数

 

   printf("%d!=%10.0f\n", iInputValue, fResult);

 

   return 0;                      // 注意有返回值

}

 

 

/****************************************************************

*功能描述:求一个数的阶乘

*输入参数: iInputValue-输入值

*输出参数:无

*返  回 值:求阶乘后的结果

*其它说明:无

*修改日期            版本号           修改人         修改内容

* ---------------------------------------------------------------------------------------------

* 20140813         V1.0            周兆熊           创建

***************************************************************/

float ProcessFactorial(INT32 iInputValue)

{

   float  fResult     = 0.0;

 

  // 先判断输入值是否小于0

   if (iInputValue < 0)

   {

       printf("iInputValue < 0, dataerror!");

 

       return -1;

   }

   else

  {

       if (iInputValue =http://www.mamicode.com/= 0 || iInputValue == 1) // 0和1的阶乘是1

       {

           fResult = 1;

       }

       else

       {

           // 执行递归调用

           fResult = ProcessFactorial(iInputValue-1)*iInputValue;

       }

 

       return(fResult);

   }

}

 

 

(本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)