Chinaunix首页 | 论坛 | 博客
  • 博客访问: 229381
  • 博文数量: 39
  • 博客积分: 1130
  • 博客等级: 少尉
  • 技术积分: 453
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-26 15:54
文章分类

全部博文(39)

文章存档

2012年(1)

2011年(31)

2010年(7)

分类: C/C++

2011-03-14 15:49:45

    自打小学开始,人们就被告知,做题之前应该先审题。这道理虽然很浅显,但却无比重要。
    然而正是由于这道理过于浅显,所以总免不了被轻视——甚至被遗忘。人类历史上发生过无数次因为轻视简单浅显的道理而招致失
败或走弯路的事情。轻视看起来简单的真理,最后总是要受到惩罚的。在缺乏常识的时代更应该重视常识。
    编程也是如此。人们往往以为编写程序代码才是最有难度的工作,而编程要解决的问题本身是否成立或合理却常常被忽视,认为那
是显而易见的事。在软件工程中,需求分析在很长的历史阶段里都被错误地认为是最简单的一个步骤。直到近些年来,有研究指出,软件50%以上的缺陷是由于需求分析的错误造成的,编码错误引起的软件缺陷基本上只占全部缺陷的1/4左右。这时不少人才恍然大悟地发现:正确地提出问题比解决问题重要的多;因为如果没能正确地提出问题,就根本谈不上正确地解决问题。
    道理容易懂,但要真正做到认真地对待需求分析,却是另一回事。因为这还需要训练有素的职业修养和职业习惯。绝对不是仅仅在
思想上认识到需求分析的重要性,就能养成好的职业习惯;良好习惯的培养需要大量的自觉的自我训练。只有经过不断反复的练习才能形成良好的习惯。
    这种训练越早越好。一旦开始学习编程,就应该开始主动地进行良好编程习惯的培养和训练,而不是等到学习软件工程时才开始培
养这种意识。
    在学习编程时,养成良好编程习惯方法之一就是通过抄题来主动地训练自己。在抄题的过程中注意审查问题是否明确、合理。这样
做的另一个好处是,阅读你代码的人能够清楚地了解这段程序要解决的是什么问题。
    下面通过一个例子,来初步地看一下应如何审题:
    “输入两个数,求其最大公约数”
    在这里,问题要求输入的两个数是什么样的数就不明确。是整数?分数?实数?复数?这样的问题其实是无法解决的。因为问题本
身就不周密、不严格。
    抄题时还可以思考对程序的具体要求,明确程序的功能。如果需要也可以自己进一步明确写出。网上流传的一套所谓的“C语言经典一百例”,其中的第一题就是一个很好的反例:
    【程序1】
    题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
    1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去掉不满足条件的排列。 
    2.程序源代码:
  1. main()
  2.     {
  3.      int i,j,k;
  4.      printf("\n");
  5.      for(i=1;i<5;i++)    /*以下为三重循环*/
  6.        for(j=1;j<5;j++) 
  7.          for (k=1;k<5;k++)
  8.           {
  9.            if (i!=k&&i!=j&&j!=k)    /*确保i、j、k三位互不相同*/
  10.            printf("%d,%d,%d\n",i,j,k);
  11.           }
  12.      }
    抛开这段代码存在的许多其他问题不谈,问题中的“能组成多少个互不相同且无重复数字的三位数”显然被编程者所忽视了。这样的代码没有什么价值。   
    因此强烈建议在写代码之前先抄一遍题目。
    可能有人觉得题目无法被编译,没关系,这可以成为极好的注释。从某种意义上来说,写注释比写代码更重要。注释虽然不能解决问题,却极其有助于正确地解决问题或更容易地找出及改正错误。
    以下给出第一章习题7(21页)的完整编程过程:
0.描述程序功能
/*
  Description: 输出下面图案
 
        /\     
       /  \    
      /    \  
     /      \  
    /________\  
*/
1.写出main()
 
/*
  Description: 输出下面图案
 
        /\     
       /  \    
      /    \  
     /      \  
    /________\  
*/

#include
#include
int main( void )
{
 
  system("PAUSE"); 
  return 0;
}
    很多初学者从头到尾一个字一个字地写代码,这种写代码的方式非常糟糕。
    就如同盖房子要先搭好脚手架一样,写代码也应该先搭建好必要的框架。通常,这种框架就是main()。这个道理所有的建筑工人都懂得,但许多程序员却不懂得。
    应当把写代码看成是按照不同的方式填充、完善、完成main()的过程——每一个程序都是如此,就如同装修房屋一样。房屋总是先建好再装修的。还不至于有人愚蠢到边建房子边装修的吧?
    至此,应该编译一下。如果代码有错误,越早发现越好。不少初学者急于事功,喜欢带“病”前行,在全部代码完成后再试图排除BUG。这种做法很傻。因为增加了调试难度,工作量可能增加几百倍甚至更多。      
    应该养成每写一两代码就立刻编译一下的好习惯,这种习惯越是初学者意义越大。就像攀岩一样,要始终保持立足于坚实正确的基点之上,这样才能从胜利走向更大的胜利。试图通过匆忙的、一蹴而就的方式完成程序是不切实际的幻觉。
2.填充main()
    编译通过后,开始考虑逐步添充main()。
    程序的的功能是在标准输出设备上输出5行字符,输出字符序列的功能可通过调用printf()函数实现。
/*
  Description: 输出下面图案
 
        /\     
       /  \    
      /    \  
     /      \  
    /________\  
*/

#include
#include
int main( void )
{
  printf("\n");       //依然是先写出必要的部分
  printf("\n");       //通过复制粘贴完成
  printf("\n");       //通过复制粘贴完成
  printf("\n");       //通过复制粘贴完成
  printf("\n");       //通过复制粘贴完成
  system("PAUSE"); 
  return 0;
}
    编译通过后再进入下一步骤。
3.逐步细化
    现在,最初抄写的题目部分有了更多的用处。把相应的部分复制粘贴到printf()函数调用的""之内。
    不少初学者不注意使用“编辑”功能,这很不专业。应尽量使用编辑器中的“编辑”功能,来提高编程效率。
/*
   Description: 输出下面图案
 
         /\     
        /  \    
       /    \  
      /      \  
     /________\  
*/

#include
#include
int main( void )
{
  printf("         /\      \n");       //依然是先写出必要的部分
  printf("        /  \     \n");       //通过复制粘贴完成
  printf("       /    \    \n");       //通过复制粘贴完成
  printf("      /      \   \n");       //通过复制粘贴完成
  printf("     /________\  \n");       //通过复制粘贴完成
  system("PAUSE"); 
  return 0;
}
    编译。这时编译器可能会给出警告。
4.完善
    由于""内的“\”是转义字符,无法直接写出。应将""内的“\”改写成“\\”。这应该通过“查找”“替换”来完成。替换过程中应注意有些“\”替换而有些“\”不替换。
    熟练应用IDE的编辑功能,可以提高写代码的效率和正确性。
/*
   Description: 输出下面图案
 
         /\     
        /  \    
       /    \  
      /      \  
     /________\  
*/

#include
#include
int main( void )
{
  printf("         /\\      \n");       //依然是先写出必要的部分
  printf("        /  \\     \n");       //通过复制粘贴完成
  printf("       /    \\    \n");       //通过复制粘贴完成
  printf("      /      \\   \n");       //通过复制粘贴完成
  printf("     /________\\  \n");       //通过复制粘贴完成
  system("PAUSE"); 
  return 0;
}
    至此,代码完成。编译,运行程序并检查运行结果是否正确。
忠告:   
    程序员不但应当完成正确的代码,而且更应当用正确地方式完成代码。遵循良好的工序是代码质量的重要保证,程序员的聪明才智则不是。
阅读(2156) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~