C語言的assert斷言巨集
大家在學習C語言的時候對於assert斷言巨集瞭解多少呢?今天小編要為大家帶來的是C語言的assert斷言巨集的相關知識,希望可以在大家學習C語言的時候有所幫助,一起來看看吧!
assert巨集的原型定義在中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義:
#include
void assert( int expression );
assert的作用是現計算表示式 expression ,如果其值為假(即為0),那麼它先向stderr列印一條出錯資訊,然後通過呼叫 abort 來終止程式執行。
如果assert()終止了程式,它首先會顯示失敗的測試、包含測試的檔名和行號。
示例:
12345678910111213141516171819202122232425262728293031323334353637 | /* assert.c -- use assert() */ #include #include #include 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" , sqrt(z)); puts( "Next pair of numbers: " ); } puts( "Done" ); return 0 ; } |
下面是該程式的執行示例:
1 | Enter a pair of numbers ( 0 0 to quit): |
4 3 [使用者輸入]
123 | answer is 2.645751 Next pair of numbers: |
5 3 [使用者輸入]
123 | answer is 4.000000 Next pair of numbers: |
3 5 [使用者輸入]
1 | assertion "z >= 0" failed: file "assert.c" , line 14 , function: main |
該程式在求平方根之前,該程式斷言z是否大於0或等於0。程式還錯誤地減去一個值而不是加上一個值,故意讓z得不到合適的值。
具體的錯誤提示音編譯器而異。這條訊息指明的是沒有滿足z>=0的條件。
用if語句也能完成類似的任務:
123456789 | if (z< 0 ) { puts( "z less than 0" ); abort(); } |
但是使用asset()有幾個好處:它不僅能自動標識檔案和出問題的行號,還有一種無需修改程式碼就能開啟或關閉assert()的機制。在除錯結束後,可以通過在包含#include 的語句之前插入#define NDEBUG來禁用assert呼叫,示例程式碼如下:
12345 | #include #define NDEBUG #include |
重新編譯程式,這樣編譯器就會禁用檔案中的所有assert()語句。如果程式又出現問題,可以移除這條#define NDEBUG指令,或者把它註釋掉,然後重新編譯,這樣就重新啟用了assert()語句了。
使用assert的'缺點是,頻繁的呼叫會極大的影響程式的效能,增加額外的開銷。
一些建議:
使用斷言捕捉不應該發生的非法情況。不要混淆非法情況與錯誤情況之間的區別,後者是必然存在的並且是一定要作出處理的。 在函式的入口處,使用斷言檢查引數的有效性(合法性)。 在編寫函式時,要進行反覆的考查,並且自問:“我打算做哪些假定?”一旦確定了的假定,就要使用斷言對假定進行檢查。 一般教科書都鼓勵程式設計師們進行防錯設計,但要記住這種程式設計風格可能會隱瞞錯誤。當進行防錯設計時,如果“不可能發生”的事情的確發生了,則要使用斷言進行報警。