您的位置:首页 > 其它

assert用法

2016-06-05 10:12 211 查看
我一直以为assert仅仅是个报错函数,事实上,它居然是个宏,并且作用并非“报错”。
  在经过对其进行一定了解之后,对其作用及用法有了一定的了解,assert()的用法像是一种“契约式编程”,在我的理解中,其表达的意思就是,程序在我的假设条件下,能够正常良好的运作,其实就相当于一个if语句:
if(假设成立)
{
     程序正常运行;
}
else
{
      报错&&终止程序!(避免由程序运行引起更大的错误)  
}
  但是这样写的话,就会有无数个if语句,甚至会出现,一个if语句的括号从文件头到文件尾,并且大多数情况下,我们要进行验证的假设,只是属于偶然性事件,又或者我们仅仅想测试一下,一些最坏情况是否发生,所以这里有了assert().
   assert宏的原型定义在assert.h中,其作用是如果它的条件返回错误,则终止程序执行. 

 #include "assert.h" 
 void assert( int expression );
  assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
 使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。 
  在调试结束后,可以通过在包含#include 的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下: 

 #include 
 #define NDEBUG 
 #include
   用法总结与注意事项: 
  1)在函数开始处检验传入参数的合法性 
  如: 
   
  int resetBufferSize(int nNewSize) 
 { 
  //功能:改变缓冲区大小, 
  //参数:nNewSize 缓冲区新长度 
  //返回值:缓冲区当前长度 
  //说明:保持原信息内容不变 nNewSize<=0表示清除缓冲区 
  assert(nNewSize >= 0); 
  assert(nNewSize <= MAX_BUFFER_SIZE); 
   
 ... 
 }
  2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败 
   
  不好: 
for (i = 0; i <= 100; ++i) assert (do_something () == 0);
然后,你可能会发现这样会使得性能大大降低,从而在创新编译使使用NDEGUG参数。这将移除整个assert宏,这就将do_something( )也被移除了,再也不被调用。为了纠正错误,你应该这样写:
for (i = 0; i <= 100; ++i) { int status = do_something (); assert (status == 0); }
另外应该铭记在心的是,不要用assert去检查无效的输入。用户可不喜欢自己在输入时程序直接退出,即便是输入错误,程序最好也有友好的响应。所以,你应该对无效输入进行检查,并输出一些有用的提示信息。只在程序运行中进行内部检查时使用断言。
在这里,我会给出一些比较好的在程序中使用assert的地方:
(1)空指针检查。例如,针对一个函数的参数进行空指针检查。你可以这样使用:
[code=cpp;toolbar:false">assert (pointer != NULL);产生的错误会像这样:Assertion ‘pointer != ((void *)0)’ failed这样,当出现空指针时,你的程序就会退出,并很好的给出错误信息。
(2)检查函数参数的值。例如,如果一个函数只能在它的一个参数foo为正值的时候被调用,你可以在函数开始时这样写:assert (foo > 0);,这将帮助你检测函数的错误使用,这也给源代码阅读者很清晰的印象,那就是在这里对函数的参数值有限制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: