c语言标准库详解(十):诊断函数assert.h

c语言标准库详解(十):诊断函数<assert.h>

概述

<assert.h>中只有一个assert宏。
assert宏用于为程序增加诊断功能,形式如下:

void assert(int expression)

如果执行语句

assert(expression)

时,表达式的值为0,则assert宏将在stderr中打印一条消息,比如:

Assertion failed:表达式,file 源文件名,line 行号

打印消息后,该宏将调用abort终止程序的执行。其中的源文件和行号来自于预处理器宏__FILE__以及__LINE__。
如果定义了宏NDEBUG,同时又包含了头文件<assert.h>,则assert宏将被忽略。

示例

代码

#include <assert.h>
#include <stdio.h>
int main()
{
   int a;
   char str[50];
   printf("请输入一个整数值: ");
   scanf("%d", &a);
   assert(a >= 10);
   printf("输入的整数是: %d\n", a);
   printf("请输入字符串: ");
   scanf("%s", str);
   assert(str != NULL);
   printf("输入的字符串是: %s\n", str);   
   return(0);
}

不同的输入与输出

PS G:\CSAPP>  & 'c:\Users\swy\.vscode\extensions\ms-vscode.cpptools-0.27.1\debugAdapters\bin\WindowsDebugLauncher.exe' '--stdin=Microsoft-MIEngine-In-ce44jt01.wkp' '--stdout=Microsoft-MIEngine-Out-z401vdid.zwc' '--stderr=Microsoft-MIEngine-Error-bzwjf2pm.eif' '--pid=Microsoft-MIEngine-Pid-ceq5e0lw.rgk' '--dbgExe=G:\x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0\mingw64\bin\gdb.exe' '--interpreter=mi'
请输入一个整数值: 9
Assertion failed!

Program: G:\CSAPP\exercise.exe
File: g:\CSAPP\languageC\exercise.c, Line 11

Expression: a >= 10
PS G:\CSAPP> 
PS G:\CSAPP>  & 'c:\Users\swy\.vscode\extensions\ms-vscode.cpptools-0.27.1\debugAdapters\bin\WindowsDebugLauncher.exe' '--stdin=Microsoft-MIEngine-In-bksgqqtk.pn1' '--stdout=Microsoft-MIEngine-Out-ifhvr50v.2wj' '--stderr=Microsoft-MIEngine-Error-jy0bmmwd.a2a' '--pid=Microsoft-MIEngine-Pid-2ihgcj2f.q4x' '--dbgExe=G:\x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0\mingw64\bin\gdb.exe' '--interpreter=mi' 
请输入一个整数值: 11
输入的整数是: 11
请输入字符串: long live open source
输入的字符串是: long
PS G:\CSAPP>

注意

  • ASSERT 只有在 Debug 版本中才有效,如果编译为 Release 版本则被忽略。
  • 频繁的调用会极大的影响程序的性能,增加额外的开销。
  • 每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败,如下:
assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);

改为:

assert(nOffset >= 0); 
assert(nOffset+nSize <= m_nInfomationSize);
  • 不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题,如下:
assert(i++ < 100);

改为:

assert(i < 100)
i++;
  • assert和后面的语句应空一行,以形成逻辑和视觉上的一致感。
  • 有的地方,assert不能代替条件过滤。
  • assert是一个宏,而非函数
  • 在调试结束后,可以通过在包含 #include 的语句之前插入 #define NDEBUG 来禁用 assert 调用,示例代码如下:
#include 
#define NDEBUG 
#include

用途

  • 在函数开始处检验传入参数的合法性 。
  • 契约式编程。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章