文档章节

第16章 C预处理器和C库 16.11 诊断库

idreamo
 idreamo
发布于 2017/07/30 08:16
字数 632
阅读 8
收藏 1

头文件assert.h支持的诊断库是设计用于辅助调试程序的小型库。它由宏assert()构成。该宏接受整数表达式作为参数。如果表达式值为假(非零),宏assert()向标准错误流(stderr)写一条错误消息并调用abort()函数以终止程序(在头文件stdlib.h中定义了abort()函数的原型)。assert()宏的作用为:标识出程序中某个条件应为真的关键位置,并在条件为假时用assert()语句终止该程序。 通常,assert()的参数为关系或逻辑表达式。如果assert()终止程序,那么它首先显式失败的判断、包含该判断的文件名和行号。

程序清单16.16是一个简短的示例程序。在对z求平方根前,程序诊断z的值是否大于或等于0。程序还错误地减去一个值而不是加上一个值,这样使z有可能获取不该使用的值。

程序清单16.16  assert.c程序

/*assert.c --使用assert()*/
#include <stdio.h>
#include <math.h>
#include <assert.h>

int main()
{
    double x,y,z;
    puts("Enter a pair of numbers(0 0 to quit): ");
    while(scanf("%lf%lf",&x,&y) == 2
          && (x!=0 || y!=0))
    {
        z=x*x - y*y; /*should be +*/
        assert(z>=0);
        printf("answer is %f\n",sqrt(z));
        puts("Next pair of numbers: ");
    }
    puts("Done");

    return 0;
}

下面是一个运行示例

Enter a pair of numbers(0 0 to quit):
4 3
answer is 2.645751
Next pair of numbers:
5 3
answer is 4.000000
Next pair of numbers:
3 5
Assertion failed: z>=0, file C:\Documents and Settings\Administrator\My Document
s\C\13.6\main.c, line 14

具体提示可能因为编译器的不同而不同。一个可能会使人困惑的问题是这个消息并不是声称z>=0,而是声称z>=0这个条件没有得到满足。

使用if语句也可以完成类似的工作:

if(z<0)
{
    puts("z less than 0");
    abort();
}

但是assert()方式有几个好处。它能自动识别文件,并自动识别发生问题的行号。另外还有一种无需改变代码就能开启或禁用assert()宏的机制如果您认为已经排除了程序的漏洞,那么可以把宏定义

#define NDEBUG

放在assert.h包含语句所在位置前并重新编译该程序。编译器将禁用文件中的呢的assert()语句。如果程序又出现问题,可以去除这个#define 指令(或把它注释掉)并重新编译,这样就重新启用了assert()语句。

© 著作权归作者所有

idreamo
粉丝 18
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
C Primer Plus 第11章 11.7 ctype.h字符函数和字符串

第7章“C控制语句 分支和跳转”介绍了ctype.h系列字符相关的函数。这些函数不能被 应用于整个字符串,但是可以被应用于字符串中的个别字符。程序清单11.26定义了一个函数,它把toupper( )函数...

idreamo
2016/08/27
29
0
[编程语言]C陷阱与缺陷

内容摘要 作者以自己1985年在Bell实验室时发表的一篇论文为基础,结合自己的工作经验扩展成为这本对C程序员具有珍贵价值的经典著作。写作本书的出发点不是要批判C语言,而是要帮助C程序员绕过...

21gprs
2014/05/23
0
0
#define 中的“ # 运算符”和“ ## 运算符”

利用宏参数创建字符串:# 运算符 在类函数宏(function-like macro)的替换部分中,“#”符号用作一个预处理运算符,它可以把语言符号(token)转化为字符串。例如,如果 x 是一个宏参量,那...

TMDJoJo
2012/07/07
0
0
Objective-C中的预处理器指令与宏

引 什么是预处理器,跟我有什么关系? 预处理器是在OC源文件编译过程中的一个部分,而且是第一个处理部分,预处理器的预也由此可见。 整个编译过程可以大致分为:预处理器进行词法分析 -> 语...

cloudox_
2017/04/26
0
0
简单而小型的单通道 C 编译器--SmallerC

SmallerC 是一个简单而小型的单程 C 编译器,目前支持 C89/ANSI C 和 C99 之间的大部分 C 语言(去掉了一些 C89 功能,加上一些 C99 功能) 目前,它为 NASM 生成 16 位和 32 位 80386+ 汇编...

匿名
2017/10/15
81
0

没有更多内容

加载失败,请刷新页面

加载更多

优雅的关闭Spring Boot

优雅的关闭Spring Boot 1、实现 TomcatConnectorCustomizer 接口拿到Tomcat的连接获取 Tomcat连接池 2、实现 ApplicationListener<ContextClosedEvent> 监听服务器关闭事件,注册JVM钩子函数...

sowhat
今天
2
0
Python3-Web开发

简介 Web开发框架 什么是Web框架? Web应用程序框架或简单的Web框架表示一组库和模块,使Web应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低级细节。 virtualenv是一个虚拟...

wuxinshui
今天
3
0
使用技媒体实践编写发布博客

技媒体实践博客 CSDN OSChina 知乎 简书 思否 掘金 51CTO

晨猫
今天
2
0
Lucene

1、什么是全文检索 数据分类 我们生活中的数据总体分为两种:结构化数据和非结构化数据。 结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。 非结构化数据:指不定长或无固...

榴莲黑芝麻糊
昨天
5
0
python到setuptools、pip工具的安装

python安装 基础开发库   apt-get install gcc  apt-get install openssl libssl-dev 安装数据库和开发库   apt-get install mysql-server libmysqld-dev python环境   下载地址...

问题终结者
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部