assert宏:
assert宏其实很重要,对于调试程序来说。
assert宏的原型定义在assert.h中
#include<assert.h>
void assert(int exp);
assert的作用是计算表达式exp,如果其值为假(即为0),那么它先打印一条出错信息,然后通过调用abort来终止程序运行。
assert就是为了确定一个条件为真,如果不为真,则给出出错信息,并终止程序。所以assert也叫断言。
例子:
#include<assert.h>
#include<stdio.h>
void main()
{
int i=100;
assert(i!=100);
}
这里assert(i!=100);就是确保i不等于100,程序才可以继续运行,否则程序终止,给出出错信息。
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,例如:
#include<stdio.h>
#define NDEBUG
#include<assert.h>
assert宏的实现:
#include<stdio.h>
#include<stdlib.h>
void _assert(void *exp,void *file,unsignedint line);
#define assert(exp)(void)((exp)||((_assert(#exp , __FILE__ , __LINE__),0)))
void _assert(void *exp,void *file,unsignedint line)
{
printf("Assertion failed: %s, file %s,line %d\n",exp,file,line);
abort();
}
void main()
{
inti=100;
assert(i!=100);
}
1.(void)((exp)||((_assert(#exp,__FILE__,__LINE__),0)))
这里利用了||的短路性质,就是条件为真,它就不执行后面的了,为假才执行。
#exp会在预处理产生一个字符串,也就是上面的i!=100.
__FILE__,__LINE__,分别表示文件位置和行数。
注意:__FILE__ FILE前后都是两个下划线
((_assert(#exp,__FILE__,__LINE__),0)) 为一个逗号表达式:
表达式1:_assert(#exp,__FILE__,__LINE__)
表达式2: 0
补充:逗号表达式
C语言提供一种特殊的运算符—逗号运算符。用它将两个表达式连接起来。如:
3+5,6+8
称为逗号表达式,逗号表达式的一般形式为:
表达式1,表达式2
逗号表达式的求解过程是:先求解表达式1,再求解表达式2,整个逗号表达式的值是表达式2的值。
“3+5,6+8”的值为14
2.abort();
这个函数是一个内部函数,它就是异常中止你运行的程序。图片中的红叉Debug Error!的出现,就是因为调
用了这个程序,把它去掉,就不会出现了。