1. 程式人生 > >【 C 】assert.h 簡明介紹

【 C 】assert.h 簡明介紹

標頭檔案<assert.h>唯一的目的就是提供assert巨集定義,可以在程式中關鍵的地方使用這個巨集來進行斷言。如果一處斷言被證明非真,希望程式在標準錯誤流輸出一條適當的提示資訊,並使執行異常終止。

它的原型如下:

void assert( int expression );

當它被執行時,這個巨集對錶達式引數進行測試。如果它的值為假(0),它就向標準錯誤列印一條診斷資訊並終止程式。這條資訊的格式是由編譯器定義的,但它將包含這個表示式和原始檔的名字以及斷言所在的行號。(後面會給出具有案例) 如果表示式為真,它將不列印任何東西,程式繼續執行。

注:由於assert()不是一個函式而是一個巨集,所以assert實際上並不具有原型,但是,這個原型可以形象的說明assert的用法。

這個巨集提供了一個方便的方法,對應該是真的東西進行檢查。例如,一個函式必須用一個不能為 NULL 的指標引數進行呼叫,那麼函式可以用assert驗證這個值:

assert( value != NULL );

如果函式錯誤的接受了一個 NULL 引數,程式將會列印一條類似下面的資訊:

Assertion failed: value != NULL, file.c line 274

提示:用這種方法使用assert使除錯變得更容易,因為一旦出現錯誤,程式就會停止。而且,這條資訊準確地提示了症狀出現的地點。如果沒有斷言,程式可能繼續執行,並在以後失敗,這就很難除錯了。

注意 assert 只適用於驗證必須為真的表示式。由於它會終止程式,所以你無法用它檢查那些你試圖進行處理的情況,例如檢查非法的輸入並要求使用者重新輸入一個值。

當程式被完整地測試完畢之後,你可以在編譯時通過定義 NDEBUG 消除所有的 assert. 你可以在原始檔的標頭檔案中 assert.h 被包含之前增加下面這個定義:

#define NDEBUG

當NDEBUG 被定義之後,前處理器將丟棄所有的 assert,這樣就消除了這方面的開銷,而不必在原始檔中把所有的assert實際刪除!

(可以通過在程式的某些地方定義巨集NDEBUG來改變assert的展開方式

如果程式某個包含assert的地方沒有定義NDEBUG,該標頭檔案就會將巨集assert定義為活動形式,它就可以展開為一個表示式,測試斷言並在斷言為假的時候輸出一條錯誤資訊,然後程式終止。反之,如果定義了NDEBUG,標頭檔案就會把這個巨集定義為不執行任何操作的靜止形式。)

參考:《c與指標》