ASSERT(断言)的作用

    程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。断言assert 是仅在Debug 版本起作用的宏,它用于检查“不应该”发生的情况。在运行过程中,如果assert 的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。

     assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:

#include <assert.h>
void assert( int expression );


       assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。请看下面的程序清单badptr.c:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main( void )
{
       FILE *fp;
    
       fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
       assert( fp );                           //所以这里不会出错
       fclose( fp );
    
       fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开文件失败
       assert( fp );                           //所以这里出错
       fclose( fp );                           //程序永远都执行不到这里来
       return 0;
}


[root@localhost error_process]# gcc badptr.c 
[root@localhost error_process]# ./a.out 
a.out: badptr.c:14: main: Assertion `fp' failed.

  已放弃使用assert()的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:

#include <stdio.h>
#define NDEBUG
#include <assert.h>


用法总结与注意事项:

  1)在函数开始处检验传入参数的合法性如:

int resetBufferSize(int nNewSize)
{
  //功能:改变缓冲区大小,
  //参数:nNewSize 缓冲区新长度
  //返回值:缓冲区当前长度 
  //说明:保持原信息内容不变     nNewSize<=0表示清除缓冲区
  assert(nNewSize >= 0);
  assert(nNewSize <= MAX_BUFFER_SIZE);
  ...
}


  

  2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败,如:

  不好:

assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);

  好:

assert(nOffset >= 0);
assert(nOffset+nSize <= m_nInfomationSize);

  3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题,如:

  错误:

assert(i++ < 100);

  这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。

  正确:

 assert(i < 100);
 i++;

  4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感。

  5)有的地方,assert不能代替条件过滤。


使用断言的几个原则: 
   
  (1)使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。 
   
  (2)使用断言对函数的参数进行确认。 
   
  (3)在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查。 
   
  (4)一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。 
  
  ASSERT ()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。


原文地址:http://www.cnblogs.com/ggzss/archive/2011/08/18/2145017.html

http://www.cnblogs.com/moondark/archive/2012/03/12/2392315.html

http://www.cnblogs.com/caihongsheng/p/3514523.html

<think>好的,用户想了解ASSERT断言在编程中的作用及用法。首先,我需要回忆一下自己掌握的知识。断言通常用于在代码中检查某些条件是否为真,如果条件不满足,程序会立即终止并报错。这有助于在开发阶段快速发现错误。 根据提供的引用,Java、Python和C/C++都有断言机制。比如在Java中使用assert关键字,可以带或不带错误信息。Python的assert语句如果表达式为假,会抛出AssertionError。C语言中需要包含assert.h头文件,使用assert宏。 接下来需要组织回答结构。先介绍断言的基本作用,比如防御式编程、调试辅助、文档说明。然后分语言说明具体用法,引用提供的例子。要注意用户可能关心不同语言的区别,所以需要分别说明Java、Python和C的用法。 还要注意用户提到的性能问题,比如断言在发布版本可能被禁用,影响性能时需要移除。此外,要强调断言不能替代错误处理,适用于内部检查而非用户输入验证。 可能用户是刚接触断言的开发者,需要明确使用场景和注意事项。需要给出例子,如检查参数有效性、假设验证等。同时,提醒用户不要滥用断言,尤其是在处理外部输入时。 最后生成相关问题,覆盖断言作用、不同语言用法、禁用情况、与错误处理的区别以及应用场景。确保问题能帮助用户进一步理解知识点。</think>### ASSERT断言作用及用法解析 #### 一、断言的核心作用 1. **防御式编程** 断言用于验证代码执行时的关键条件是否成立。例如检查函数参数有效性: ```python def divide(a, b): assert b != 0, "除数不能为零" return a / b ``` 当$b=0$时会触发`AssertionError`[^2]。 2. **调试辅助工具** 在C语言中,断言可检测内存越界: ```c int arr[10]; int index = 15; assert(index < 10 && "数组索引越界"); ``` 当索引越界时立即终止程序并输出错误信息[^3]。 3. **代码文档化** 断言可作为"可执行注释",明确标注开发者的预期条件,例如验证算法中间结果: $$ \text{计算结果} \in [0,100] \quad //\ 使用断言验证值域 $$ #### 二、具体语言实现 | 语言 | 语法示例 | 特性对比 | |--------|-------------------------------|--------------------------| | Java | `assert param != null;` | 需JVM启用`-ea`参数[^1] | | Python | `assert len(data) > 0` | 直接抛出AssertionError | | C/C++ | `assert(pointer != NULL);` | 依赖`NDEBUG`宏控制 | #### 三、使用规范与注意事项 1. **非替代错误处理** 适合验证内部逻辑(如算法前置条件),而非处理用户输入错误: ```java // 正确用法:验证内部状态 assert queue.isEmpty() == (size == 0); // 错误用法:应使用异常处理用户输入 if (input < 0) throw new IllegalArgumentException(); ``` 2. **性能优化建议** 生产环境通常禁用断言(如Java默认关闭),可通过编译选项控制: ```bash # Java启用断言 java -ea MyClass # C++禁用断言 g++ -DNDEBUG mycode.cpp ``` 3. **最佳实践场景** - 验证函数后置条件:`assert is_sorted(result)` - 检测不可达代码路径:`assert false : "不应进入此分支"` - 检查对象状态一致性:`assert balance >= 0`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值