C/C++ 编码过程中防错的必要性及其方法

1.1  防错及其意义
防错
就是预防错误的发生。
这里讨论的问题基本上代码防错。
这里讨论的防错实施者是编程人员,非测试人员;
防错意义
提高产品质量
减少Bug的数量
•增加程序健壮性
提高开发效率
•通过防止错误的发生,检查排错的时间;一般来讲防错投入的价值要远远大于排错的投入
•一个错误不仅仅会给(产生这个问题的)开发者的工作增加阻碍,而且往往会导致整个团队工作的停滞;因此,错误的及早避免和发现(尽可能在开发时就避免),会对提高团队的开发效率产生积极意义;
降低开发风险
•避免因质量问题带来的工期延期;
•避免项目成本超出预算;
1.2 把防错作为工作习惯
避免自己的编码产生错误
你代码有容错处理吗?
如下面的例子:
int  AAA( char *p)
       {      
  char c;
  ….
 *p  =c;
            …..
       }
如果参数p传入是空指针,程序运行结果会怎样?程序会崩溃。。
正确处理应该:
int  AAA( char *p)
{    char c;
     ASSERT( NULL != p);
if (NULL != p)
return ERR_NULL;
                      ….
    *p  =c;
      }

你的代码存在内存泄漏?
 char*    AllocStrFromHeap(int len) 

 char *pstr; 
 if ( len <= 0 )
 return NULL; 
 return ( char* ) malloc( len ); 
这只是一个内存分配的过程;如果在程序退出前不释放,就会造成内存泄漏。
不要忽略warning
常见的warning包括
•声明了未使用的变量
•使用了隐晦声明的函数。(也许这个函数在别的C文件中,编译时会出现这种警告,你应该这使用之前使用extern关键字声明这个函数)
•没有转换一个指针。(例如malloc返回的指针是void的,你没有把之转成你实际类型而报警,还是手动的在之前明显的转换一下吧)
•类型向下转换。(例如:float f = 2.0; 这种语句是会报警告的,编译会告诉你正试图把一个double转成float,你正在阉割一个变量,你真的要这样做吗?还是在2.0后面加个f吧,不然,2.0就是一个double,而不是float了)
•。。。
不管怎么说,编译器的Warning不要小视,其中可能有错误的线索。

避免别人使用自己的代码产生错误
你的程序有注释?
   养成写程序注释的习惯,这是每个程序员所必须要做的工作。有一个几千行的程序,却居然没有一行注释的程序。这就如同在公路上驾车却没有路标一样。
      为了方便自己和别人的阅读,请清晰的为代码写上注释。
程序对外接口函数有详细的说明?
为了方便别人调用你的函数,避免产生错误,说明应该包括:
•函数功能的说明
•调用函数的时序:如有时序图最好,至少应该描述是同步还是异步
•函数的参数说明:是输入还是输出、有效输入范围等
•返回值的详细说明
•相关函数的说明
避免自己使用别人的代码产生错误
调用函数,判断返回数值了?
请看下面的代码
  FILE * fp;
  fp = fopen("BMP3.SD","r+b");
  i=fread(a, 100, 1, fp);
 如果fopen不成功,程序的运行结果会如何?
 正确的处理应该:
FILE * fp;
  fp = fopen("BMP3.SD","r+b");
if (fp == NULL) {
    return ERR;
}
i=fread(a, 100, 1, fp);
修改别人程序的修养
•当你维护别人的程序时,请不要非常主观臆断的把已有的程序删除或是修改。
•修改别人的程序时,请不要删除别人的程序,如果你觉得别人的程序有所不妥,请注释掉,然后添加自己的处理程序,必竟,你不可能100%的知道别人的意图,所以为了可以恢复,请不依赖于CVS或是SourceSafe这种版本控制软件,还是要在源码上给别人看到你修改程序的意图和步骤。这是程序维护时,一个有修养的程序员所应该做的。
下面代码是一个比较好的修改方法
        /* 
     * ----- commented by haoel 2003/04/12 ------ 
     * 
     *   char* p = ( char* ) malloc( 10 ); 
     *   memset( p, 0, 10 ); 
     */ 
     
    /* ------ Added by haoel   2003/04/12 ----- */ 
     char* p = ( char* )calloc( 10, sizeof char ); 
    /* ---------------------------------------- */ 
    ... 
1.3 防错常识
预防错误应考虑的事项--在写代码时
变量初始化了吗(auto型变量)?(全局变量和静态变量在定义时不必赋初始值【从ROM大小的角度考虑】
•变量一定要被初始化再使用。C/C++编译器在这个方面不会像JAVA一样帮你初始化,这一切都需要你自己来,如果你使用了没有初始化的变量,结果未知。好的程序员从来都会在使用变量前初始化变量的。
–定义、使用变量时,考虑它的类型吗?考虑它的存储空间的位置吗?
•合理选择变量的类型,可以减少额外的消耗;如类型强制转换等;
–字符串的长度考虑‘\0’了?
–程序中的移位、赋值、加减乘运算会造成变量(数据)溢出吗?
–数据类型转换正确吗?存在隐性的数据类型转换吗?
–条件表示式中存在‘==’被误写成‘=’问题吗?
–条件表示式存在类型不一致的变量相互比较,考虑出错的风险吗?
–If语句都有else分支吗?有出错的风险吗?
–Switch语句的每个Case都用Break吗?有Default处理吗?
–For/while控制体内有没有死循环的可能?
–For控制体内修改循环变量的情况?
–For/while表达式有没有“多1”或“少1”的可能?
–数组下标有可能越界吗?
–使用的指针指向“有效的”地址空间吗?
–指针的操作会导致访问非法地址?
–程序中动态申请的资源(包括内存等),在退出后都正确释放了吗?
–使用递规方法,能够知道递规最大的次数吗?系统的资源能够满足吗?
–调用某个函数后,有容错处理吗?
–可重入函数的全局变量有(信号量或其它)保护吗?
–Lock/Unlock相互匹配?有没有死锁的可能?
–不仅要考虑正常情况的处理,还要考虑异常情况的处理;
预防错误可以采用措施--编程完成之后,调试中
–在编写的程序中对所有可能出错的地方,多加断言;
–对重点代码进行CodingReview
–借助工具预防错误的发生
可以利用的工具包括C++ Test/QAC/Insure++等
•C++ Test, 可以帮我们贯彻编码规范,详细参照《C++ Test的使用指南》
•QAC,可以帮我们静态检查C代码,详细参照《QAC的使用指南》
•Insure++ ,可以帮我们动态检查代码中内存错误,详细参照《Insure++的使用指南》

 






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值