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

用途

  • 在函數開始處檢驗傳入參數的合法性 。
  • 契約式編程。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章