初步理解:
我一直以为assert只是一个报错函数,实际上,它居然是个宏,并且作用并不是报错;
在经过对其进行一定了解之后,对其作用和用法有了一定的了解,assert()的用法像是一种“契约式编程”,在我的理解中,其表达的意思是,程序在我假设的条件下能正常运行,说白了就相当于一个if语句:
if (条件成立)
{
程序正常运行;
}
else
{
报错&&终止程序!(避免由程序运行引起更大的错误)
}
假如这样写的话,就会有无数个if语句,甚至会出现,一个if语句的括号从头到尾,并且大多数情况下,我们要进行验证的假设,只是属于偶然事件,又或者我们仅仅想测试一下,一些最坏情况是否发生,所以这里有assert();
函数原型:
assert宏的原型定义在assert.h中,起作用是如果它的条件返回错误,则终止程序执行;
#include<assert.h>
void assert(int expression) //assert宏参数一定是一个整型表达式才行
函数作用:对于表达式(expression)而言,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用abort来终止程序运行;
函数缺点:频繁的调用会极大的影响程序的性能,增加额外的开销;
在调试结束之后,可以通过包含#include<assert.h>之前插入#define NDEBUG来禁用assert调用,示例代码如下:
#include<stdio.h>
#define NDEBUG
#include<assert.h>
用法总结与注意事项:
1)、在函数开始处检验传入参数的合法性;
int resetBufferSize(int nNewSize)
{
//功能:改变缓冲区大小
//参数:nNewSize缓冲区新长度
//返回:缓冲区当前长度
//说明:保持原信息内容不变
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不能代替条件过滤;
程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。断言assert 是仅在Debug 版本起作用的宏,它用于检查"不应该"发生的情况。以下是一个内存复制程序,在运行过程中,如果assert 的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。