assert断言函数简介

article/2025/10/3 14:40:03

目录

🎍1.整体介绍

🎍2.assert() 的用法和机制

🎍3.关于NDEBUG 宏

🎍4.使用assert()注意事项

🎍4.1使用 assert() 时,被检测的表达式最好不要太复杂

🎍4.2不要用会改变环境的语句作为断言的表达式

感谢观看,敬请期待更好的作品吧。🎍


🎍1.整体介绍

assert()断言函数,用于在调试过程中捕捉程序错误

所在头文件:<assert.h>

函数原型:void assert (int expression);

参数:expression即要检测的表达式

返回值:无返回值

        “断言”在语文中的意思是“断定”、“十分肯定地说”,在编程中是指对某种假设条件进行检测,如果条件成立就不进行任何操作,如果条件不成立就捕捉到这种错误,并打印出错误信息,终止程序执行。

assert() 会对表达式expression进行检测:

        如果expression的结果为 0(条件不成立),那么断言失败,表明程序出错,assert() 会向标准输出设备(一般是显示器)打印一条错误信息,并调用 abort() 函数终止程序的执行。

        如果expression的结果为非 0(条件成立),那么断言成功,表明程序正确,assert() 不进行任何操作。

大部分编译器的格式如下所示:

Assertion failed: expression, file filename, line number

        要打印的错误信息的格式和内容没有统一的规定,这和标准库的具体实现有关(也可以说和编译器有关),但是错误信息至少应该包含以下几个方面的信息:

1.断言失败的表达式,也即expression;

2.源文件名称;

3.断言失败的代码的行号。

 

🎍2.assert() 的用法和机制

        在大部分编译器下,assert() 是一个宏;在少数的编译器下,assert() 就是一个函数。我们无需关心这些差异,只管把 assert() 当做函数使用即可。

        assert() 的用法很简单,我们只要传入一个表达式,它会计算这个表达式的结果:如果表达式的结果为“假”,assert() 会打印出断言失败的信息,并调用 abort() 函数终止程序的执行;如果表达式的结果为“真”,assert() 就什么也不做,程序继续往后执行。

下面是一个具体的例子:

#include <stdio.h>
#include <assert.h>
int main()
{int m, n, result;scanf("%d %d", &m, &n);assert(n != 0);  //写作 assert(n) 更加简洁result = m / n;printf("result = %d\n", result);return 0;
}

        本例用来计算两个数相除的结果,由于被除数不能为 0,所以我们加入了 assert() 来检测错误。

        如果输入100 20,那么 n 的值为 20,n != 0这个条件成立,assert() 不进行任何操作,最终的输出结果为:

 

        如果输入100 0,那么 n 的值为 0,n != 0这个条件不成立,assert() 就会报告错误,并终止程序执行,最终的结果如下所示:

🎍3.关于NDEBUG 宏

如果查看 <assert.h> 头文件的源码,会发现 assert() 被定义为下面的样子:

#ifdef NDEBUG
#define assert(e) ((void)0)
#else
#define assert(e)  ((void) ((e) ? ((void)0) : __assert (#e, __FILE__, __LINE__)))
#endif

        这意味着,一旦定义了NDEBUG宏,assert() 就无效了。

        NDEBUG 是”No Debug“的意思,也即“非调试”。有的编译器(例如 Visual Studio)在发布(Release)模式下会定义 NDEBUG 宏,在调试(Debug)模式下不会定义定义这个宏;有的编译器(例如 Xcode)在发布模式和调试模式下都不会定义 NDEBUG 宏,这样当我们以发布模式编译程序时,就必须自己在编译参数中增加 NDEBUG 宏,或者在包含 <assert.h> 头文件之前定义 NDEBUG 宏。

        调试模式是程序员在测试代码期间使用的编译模式,发布模式是将程序提供给用户时使用的编译模式。在发布模式下,我们不应该再依赖 assert() 宏,因为程序一旦出错,assert() 会抛出一段用户看不懂的提示信息,并毫无预警地终止程序执行,这样会严重影响软件的用户体验,所以在发布模式下应该让 assert() 失效。

修改先前的代码,在包含 <assert.h> 之前定义 NDEBUG 宏:

#define NDEBUG
#include <stdio.h>
#include <assert.h>
int main()
{int m, n, result;scanf("%d %d", &m, &n);assert(n);result = m / n;printf("result = %d\n", result);return 0;
}

        当以发布模式编译这段代码时,assert() 就会失效。如果希望继续以调试模式编译这段代码,去掉 NDEBUG 宏即可。

🎍4.使用assert()注意事项

 

🎍4.1使用 assert() 时,被检测的表达式最好不要太复杂

以下面的代码为例:

assert( expression1 && expression2 && expression3);

        当发生错误时,assert() 只会告诉我们expression1 && expression2 && expression3整个表达式为不成立,但是这个大的表达式还包含了三个小的表达式,并且它们之间是&&运算,任何一个小表达式为不成立都会导致整个表达式为不成立,这样我们就无法推断到底是expression1有问题,还是expression2或者expression3有问题,从而给排错带来麻烦。

        这里我们应该遵循使用 assert() 的一个原则:每次断言只能检验一个表达式。

        根据这个原则,上面的代码应改为:

assert(expression1);
assert(expression2);
assert(expression3);

        如此,一旦程序出错,我们就知道是哪个小的表达式断言失败了,从而快速定位到有问题的代码。

🎍4.2不要用会改变环境的语句作为断言的表达式

请看下面的代码:

#include <stdio.h>
#include <assert.h>
int main()
{int i = 0;while(i <= 110){assert(++i <= 100);printf("我是第%d行\n",i);}return 0;
}

        在 Debug 模式下运行,程序循环到第 101 次时,i 的值为 100,++i <= 100不再成立,断言失败,程序终止运行。

        而在 Release 模式下运行,编译参数中设置了 NDEBUG 宏(如果编译器没有默认设置,那么需要你自己来设置),assert() 会失效,++i <= 100这个表达式也不起作用了,while() 无法终止,成为一个死循环。

        定义了 NDEBUG 宏后,assert(++i <= 100)会被替换为((void)0)。

        导致程序在 Debug 模式和 Release 模式下的运行结果大相径庭的罪魁祸首就是++运算,我们本来希望它改变 i 的值,逐渐达到 while 的终止条件,但是在 Release 模式下它失效了。

修改这段不规范的代码也很容易,将++i移出 assert() 即可:

#include <stdio.h>
#include <assert.h>
int main()
{int i = 0;while(i <= 110){++i;assert(i <= 100);printf("我是第%d行\n",i);}return 0;
}

        如此,不管是 Debug 模式还是 Release 模式,每次循环 i 的值都会增加,逐渐达到 while 的终止条件时,结束循环。


感谢观看,敬请期待更好的作品吧。🎍


http://chatgpt.dhexx.cn/article/nLJMc2Gg.shtml

相关文章

第十二章 C语言调试_assert断言函数

在我们的实际开发过程之中&#xff0c;常常会出现一些隐藏得很深的BUG&#xff0c;或者是一些概率性发生的BUG&#xff0c;通常这些BUG在我们调试的过程中不会出现很明显的问题&#xff0c;但是如果我们将其发布&#xff0c;在用户的各种运行环境下&#xff0c;这些程序可能就会…

c语言之assert()函数用法总结

1.assert宏的原型定义在<assert.h>中&#xff0c;其作用是如果它的条件返回错误&#xff0c;则终止程序执行。 库函数&#xff1a; assert.h 原型定义&#xff1a; void assert( int expression ); assert的作用是现计算表达式 expression &#xff0c;如果其值为假&…

接私活必备!国外5个顶级程序员接私活网站

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 人生交契无老少&#xff0c;论交何必先同调。 文章目录 PeoplePerHour&#xff1a;薪酬最高的专业自由职业者网站GuruFreeLancerUpworkFiverr 话说程序员这个职业有…

关于网上程序员接私活的问题

点击上方“程序人生”&#xff0c;选择“置顶公众号” 第一时间关注程序猿&#xff08;媛&#xff09;身边的故事 文丨eachfeel 很多人都谈网上接私活这件事&#xff0c;其实大家想法都差不多&#xff0c;现在做软件的那么多&#xff0c;工资也不是那么高了&#xff0c;不像以前…

程序员兼职可以从什么平台接私活?

之前有一项调查&#xff0c;结果显示&#xff1a;想通过副业赚钱的朋友&#xff0c;其中60%的人找不到门路。今天这篇文章就给大家一批可以接私活的平台。不过&#xff0c;再次强调一下&#xff0c;副业并不等于接私活儿。 私活类型与价格区间 程序员兼职的项目大致可分为三类…

10个程序员可以接私活的平台和一些建议!

来源&#xff1a;http://mrw.so/5isQLi 什么样的私活不能接 1、没有第三方担保的个人对个人的尽量不要接&#xff0c;双方都没保障&#xff0c;出了问题很大的可能撕破脸皮不了了之。 2、一上来就直接说给我开发一个什么软件&#xff0c;不说具体需求&#xff0c;没有需求文档的…

程序员接私活常用平台汇总

作者&#xff1a;镇上宝塔 素材来源&#xff1a;今日头条 今天分享一些接私活的常用平台。 ▍前 言 关于程序员接私活&#xff0c;社会各界说法不一。按照作者的观点来说如果你确实急用钱&#xff0c;价格又合适&#xff0c;那就去做。如果不怎么缺钱&#xff0c;那就接私活之前…

程序员接私活的几个平台和建议,避免掉坑!

大家对于程序员接私活这件事的看法&#xff0c;褒贬不一。但是你如果确实用钱&#xff0c;价格又合适&#xff0c;那就大胆去接。 如果不那么缺钱&#xff0c;那么接私活之前先考虑清楚&#xff0c;如果自己将空余时间用在接私活所产生的价值是不是大于提升自己。如果是的话&a…

程序员接私活月入2万?分享10个接私活的网站快收藏~

最近&#xff0c;在和身边的程序员聊天中&#xff0c;听不少朋友分享了自己接私活的经历&#xff0c;那收入真是让我“瞠目结舌” … 程序员A&#xff1a;我Java程序员&#xff0c;工作两年&#xff0c;月薪13K&#xff0c;私活20K。 程序员B&#xff1a;之前在单位上班&#…

推荐几个程序员接私活的网站

相信很多新手程序员&#xff0c;都希望能迅速提高自己的能力同时&#xff0c;又可以赚点外快增加下个人收入&#xff0c;那么&#xff0c;去接一些私活是一个不错的选择。但是接私活之前也要考虑清楚&#xff0c;因为私活一般都会占用自己大量的休息时间&#xff0c;而如果你把…

程序员接私活完整攻略

接私活对程序员这个圈子来说是一个既公开又隐私的话题&#xff0c;不说全部&#xff0c;应该大多数程序员都有过想要接私活的想法&#xff0c;当然&#xff0c;也有部分得道成仙的不主张接私活。但是很少有人在公开场合讨论私活的问题&#xff0c;似乎都在避嫌。就跟有人下班后…

【程序人生】程序员接私活常用平台汇总

00. 目录 文章目录 00. 目录01. 前言02. 程序员客栈03. 码市04. 猪八戒网05. 开源众包06. 智城外包网07. 实现网08. 猿急送09. 人人开发10. 开发邦11. 电鸭社区12. 快码13. 英选14. Upwork15. Freelancer16. Dribbble17. Remoteok18. Toptal19. AngelList20. Topcoder21. 附录 …

程序员们,千万不要接私活!

点击上方“程序员小灰”&#xff0c;选择“置顶公众号” 有趣有内涵的文章第一时间送达&#xff01; 本文转载自公众号 前端你别闹 这个话题很纠结 现在社会&#xff0c;有很多人都在利用个人时间兼职赚钱&#xff0c;程序员俗称“接私活”&#xff0c;其他行业称作兼职&#x…

盘点10个程序员可以接私活的平台和一些建议,赚麻了...

你们当程序员不会都拿着几千、万把块钱的死工资吧&#xff0c;今天为大家分享一些可以接私单的平台&#xff0c;我反正已经赚麻了。 如果你的工作相对没那么费时间&#xff0c;可以空闲的时候去接点私活。或者是还没有找工作之前&#xff0c;可以通过一些平台接一些兼职&#…

程序员一般通过什么途径接私活?怎样做兼职程序员接私活?

国内众包平台和国外众包平台差不多&#xff0c;只不过国外的工程师来自全球&#xff08;当然美欧印居多&#xff09;&#xff0c;业务范围比国内的多一点&#xff0c;具体可以看upwork、freelancer上的介绍&#xff0c;不过国外的合作方式多少有些水土不服&#xff0c;如果接单…

程序员第一次接私活?记住这三点让你事半功倍

不少程序员都有接私活的想法&#xff0c;但恰恰就如开发者之间的论调一样&#xff0c;接私活其实是有一定难度的&#xff0c;想找到合适的单子&#xff0c;顺利地做完并拿到薪水&#xff0c;需要注意的事儿很多&#xff0c;接下来和大家分享一下&#xff0c;程序员第一次接私活…

程序员接私活最最完整攻略

接私活对于程序员这个圈子来说是一个既公开又隐私的话题&#xff0c;当你竭尽全力想要去接私活的时候一定做过这样的事情&#xff0c;百度搜索“程序员如何接私活”、“程序员在哪里接外包”等等问题&#xff0c;今天就送大家最完整攻略&#xff0c;千万别错过了。 做私活挣钱吗…

前端程序员接私活,直呼赚麻了

总有一些前端程序员会想找私活&#xff0c;但是又不清楚具体的办法&#xff0c;或者是做了但没完全做&#xff0c;吃力又不讨好还赚不到钱。今天就给大家介绍一些可行性高的方法&#xff0c;让你快速找到合适的前端兼职。 干货满满&#xff0c;希望大家点赞收藏下&#xff0c;别…

程序员接私活月入2万?分享10个接私活的网站!

最近&#xff0c;播妞在和身边的程序员聊天中&#xff0c;听不少朋友分享了自己接私活的经历&#xff0c;那收入真是让我“瞠目结舌” ...... 程序员A&#xff1a;我Java程序员&#xff0c;工作两年&#xff0c;月薪13K&#xff0c;私活20K。 程序员B&#xff1a;之前在单位上班…

接私活必备的 10 个开源项目!

点击蓝色“GitHubDaily”关注我 加个“星标”&#xff0c;每天下午 18:35&#xff0c;带你逛 GitHub&#xff01; 作者 | SevDot 来源 | http://1t.click/VE8 Web 开发中几乎的平台都需要一个后台管理&#xff0c;但是从零开发一套后台控制面板并不容易&#xff0c;幸运的是有很…