我试试能不能讲半个小时:)
断言是什么?
assert()
是一个定义在<assert.h>
的宏,接受一个布尔值,若为真(非0)则继续执行;为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。我们知道程序的正确执行需要满足一定的条件(或规避一些条件),而断言就是确保我们的程序能按我们期望的条件向下执行。
假 | 真 |
---|---|
中断 | 继续 |
为什么用断言?
使用断言可以创建更稳定,品质更好且不易于出错的代码。因为assert()
用来判断条件是否满足,因此使用断言使我们向按契约式设计更近了一步。
如何使用断言:
#include<assert.h>
assert(Expression)
其中Expression的结果是一个布尔值
1.可以在预计正常情况下程序不会到达的地方放置断言 :assert false
2.断言可以用于检查传递给私有方法的参数。(对于公有方法,因为是提供给外部的接口,所以必须在方法中有相应的参数检验才能保证代码的健壮性)
3.使用断言测试方法执行的前置条件和后置条件
4.使用断言检查类的不变状态,确保任何情况下,某个变量的状态必须满足。(如age属性应大于0小于某个合适值)
不用断言
断言语句不是永远会执行,可以屏蔽也可以启用
因此:
1.不要使用断言作为公共方法的参数检查,公共方法的参数永远都要执行
2.断言语句不可以有任何边界效应,不要使用断言语句去修改变量和改变方法的返回值.
缺点
频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>
程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。
断言assert 是仅在Debug 版本起作用的宏,它用于检查“不应该”发生的情况。assert 不是一个仓促拼凑起来的宏。为了不在程序的Debug 版本和Release 版本引起差别,assert 不应该产生任何副作用。所以assert 不是函数,而是宏。
为什么要区分Debug和Release?
在我看来主要是针对其面向的目标不同的而进行区分的。Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能力。而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。所以不保存调试信息,同时,它往往进行了各种优化,以期达到代码最小和速度最优。为用户的使用提供便利。