,,C语言断言函数assert()的学习笔记

,,C语言断言函数assert()的学习笔记

在C语言的库函数中,提供了一个辅助调试程序的小库,由assert()宏组成。本文详细介绍了如何使用,有兴趣的可以看看。

在C语言库函数中,提供了一个辅助调试程序的小库,由assert()宏组成,接受一个整形表达式作为参数。如果表达式的值为false(非零),assert()宏将在标准错误流(stderr)中写入一条错误消息,并调用abort()函数来终止程序。

让我们通过一个简单的例子来看看assert()的用法。

int main()

{

int n=1;

断言(n=0);

printf('%d \r\n ',n);

系统(“暂停”);

返回0;

}

在assert()中,表达式判断的条件是n ^ 0,所以当整形变量n的值小于0时,表示表达式为假,断言函数就会起作用。这里先试试正常情况,将n的值设为1,输出结果如下:

接下来,将n的值改为-1,继续测试。

此时,程序异常终止。下面详细分析一下这个函数的执行过程。

在assert.h的头文件中可以看到assert()的原型,这里有两个原型。一个是定义了_UNICODE或者UNICODE时调用第一个assert(),没有定义时调用第二个assert()。因为头文件中没有定义_UNICODE或UNICODE,所以这里调用了第二个assert。我们来分析一下这个宏定义语句。

# define assert(_ Expression)(void)((!(_ Expression))| |(_ assert(# _ Expression,__FILE__,__LINE__),0))

void _ _ cdecl _ assert(const char * _ Message,const char *_File,unsigned _ Line);

首先,将一个parameter _Expression传入assert,然后是一个由OR运算符连接的两部分组成的语句。对于or运算符||,当第一个条件为真时,不会执行第二个条件,只有当第一个条件为假时,才会执行第二条语句。

((!(_ Expression))| |(_ assert(# _ Expression,__FILE__,__LINE__),0))

首先看第一个判断条件(!!(_Expression))。传入的参数被求反两次,相当于变量本身。当_Expression为true时,不会执行第二个条件。只有当_Expression为false时,才会执行第二个条件。在程序中,当n 0成立时,不会执行第二个条件,当n 0不成立时,会执行第二条语句。所以在上面的测试中,当n=-1时程序会异常终止。

接下来看第二个条件(_assert(#_Expression,FILELINE),0)这是一个函数,它的原型是:

void _ _ cdecl _ assert(const char * _ Message,const char *_File,unsigned _ Line);

这个函数有三个参数。根据这三个参数的名称,可以推断出第一个参数用来存储信息内容,第二个参数用来表示当前文件的细节,第三个参数表示代码中哪一行错了。

这三个参数与控制台打印的内容一致。Program后面是当前运行的可执行文件的路径,File后面是错误报告文件的路径,Line后面是错误的具体位置,这表明test6.c文件中第16行的程序有错误。最后一行表示错误表达式为n=0,表示变量n大于等于0的条件不成立,即当前变量n的值小于0,从而引起程序异常。

从上面的分析可以看出,assert()对于调试程序是很有帮助的。编译程序时,编译器无法检测出像这样隐藏在代码中的错误,只能在程序执行时发现。所以通过assert()检测表达式可以快速定位程序的bug。

我不想用assert()来检测。我不需要修改代码。我只需要在assert.h中定义NDEBUG

在assert.h中添加宏定义,继续运行程序。

此时n的值为-1,但程序正常打印出-1,没有报错。解释assert()不检测错误。这一点从头文件中也可以看出来。

定义NDEBUG时,**assert(_Expression)**执行的具体函数变成((void)0),也就是什么都不做。所以在头文件中定义NDEBUG时,assert()的检测函数会自动失效。这样,在调试程序时,只需要一条语句就可以打开或关闭调试信息输出。

关于C语言断言函数assert()的学习笔记这篇文章到此为止。有关C语言中断言函数assert()的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • 详解c语言中的字符串数组是什么,详解c语言中的字符串数组结构,详解C语言中的字符串数组
  • 表达式求值c++实现,c语言实现表达式求值
  • 看懂c语言基本语法,C语言详解,C语言的基本语法详解
  • 用c语言实现快速排序算法,排序算法设计与实现快速排序C语言,C语言实现快速排序算法实例
  • 深入解析c语言中函数指针的定义与使用方法,深入解析c语言中函数指针的定义与使用情况,深入解析C语言中函数指针的定义与使用
  • 描述E-R图,E-R图举例,关于C语言中E-R图的详解
  • 折半查找法C语言,折半查找算法(算法设计题)
  • 折半查找法C语言,c语言折半法查找数据,C语言实现折半查找法(二分法)
  • 扫雷小游戏c++代码设计,c语言扫雷游戏源代码,C语言实现扫雷小游戏详细代码
  • 怎样统计程序代码行数,C语言统计行数,C#程序员统计自己的代码行数
  • 基于c语言的贪吃蛇游戏程序设计,用c语言编写贪吃蛇游戏程序,C语言实现简单的贪吃蛇游戏
  • 图的两种遍历算法,图的遍历算法代码c语言,Python算法之图的遍历
  • 留言与评论(共有 条评论)
       
    验证码: