assert的初步認識
assert宏指令是用來診斷程序是否有誤的,函數原型如下
void assert(int expression)
那為什么我們要使用assert而不用printf呢?因為assert可以幫我們監測出是哪個條件不滿足了,而且可以直觀地顯示出是代碼中的哪一行出問題了,並且,當我們不打算用assert來診斷程序的時候,可以很方便地通過宏定義#define NDEBUG 取消assert的診斷。相比於自己寫一個一個printf,自己判斷程序哪一行出錯,顯然assert更有優勢。
其實assert的時候很簡單,因為他的使用就跟if一樣,assert(expression);expression其實就相當於if里面的表達式。來一段代碼
#include <assert.h> int main(){ int i=0; assert(i>0); //這里我們故意讓assert不成立看看結果 printf("打印出i的值是:%d\n",i); //看看是否能執行到這一步 return 0; }
運行結果:
圖1 運行結果
從程序里面看出,我們可以直觀地看出哪一行出錯了,並且是條件’i>0’不成立出錯的;並且當assert診斷出錯后,程序就退出了。這在調試的時候很有用,但是當實際投入使用的時候,我們就要把assert(expression)診斷函數禁用掉,畢竟穩定性很重要。我們可以很方便地在文件頭加上宏定義#define NDEBUG 取消assert的診斷。
#define NDEBUG #include <assert.h>
注意:#define NDEBUG要在#include <assert.h>之前,不然禁用assert不會成功。運行結果如圖2.
圖2 禁用assert之后
可以看出,即使條件不成立,也不會再有assert的診斷信息了。並且很執行到printf那行。
assert的進一步討論
當assert診斷失敗后,assert會向stderr打印消息。從圖1可以看出,assert診斷信息的表達形式是:Assertion failed: 表達式(expression),程序(file) 出錯的文件名(file name), 行號(line nnn)。然后,asset會調用abort中斷函數的執行,源代碼的文件名(The Source filename)和行號(line number)定義在預處理宏(preprocessor macros)__FILE__ 和 __LINE__中。
關於assert的用法總結與注意事項,點此。
參考
《The C Programming Language》