void assert(int expression);
assert宏的原型定義在<assert.h>中,其作用是先計算表達式expression的值為假(即為0),那麼它就先向stderr列印一條出錯信息,然後通過條用abort來終止程序;
使用assert的缺點是,頻繁的調用會極大的影響程序的性能,增加額外的開銷。
在調試結束後,可以通過在包含#include 的語句之前插入 #define NDEBUG 來禁用assert調用,示例代碼如下:
1 #include
2 #define NDEBUG
3 #include
斷言assert使用規則#include <stdio.h>
#include <assert.h>
int main(void)
{
int i;
i = 1;
assert(i++);
printf(「%d\n」,i);
return 0;
}看運行結果,如果給定的i初始值為1,所以其運行結果不會為錯,如下圖所示
很顯然是2,不會出錯如果將i初始值改成0,那麼就會出現如下錯誤:
出現異常
上面這個錯誤是很典型異常,可以考慮用assert排查。
根據提示我們很快就能定位到錯誤點,就在assert(i++)處;既然assert這麼便於定位出錯點,在工程中使用它就顯得很有必要;但其也有一定的使用規則;
斷言語句不會永遠被執行,可以屏蔽也可以啟用,這就要求assert不管是在屏蔽還是啟用狀態下都不能對我們本身代碼有所影響,這樣剛才我們在代碼中使用的assert(i++)就不行,因為如果禁用了assert,那i++就不能執行;正確的做法應該是:assert(i);i++;那麼我們一般在什麼情況下使用斷言呢?
主要體現在以下幾個方面:
1. 可以在預計正常情況下程序不會到達的地方放置斷言。(如assert(0);)3. 使用斷言檢測類的不變狀態,確保任何情況下,某個變量的狀態或範圍必須滿足。斷言assert使用規則當然我們在使用斷言的過程中會有一些我們應該注意的事項和養成一些良好的習慣,如:
1. 每個assert只檢驗一個條件,因為同時檢驗多個條件時,如果斷言失敗,我們就無法直觀的判斷哪個條件失敗;無法直觀的判斷哪個條件失敗:
assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);只檢驗一個條件,比較直觀:
assert(nOffset >= 0);
assert(nOffset+nSize <= m_nInfomationSize);2. 不能使用改變環境的語句,就像我們上面的代碼改變了i變量,在實際編寫代碼的過程中是不能這樣做的;例如:
assert(i++ < 100)不好:這是因為如果出錯,比如在執行之前i=100,那麼這條語句就不會執行,那麼i++這條命令就沒有執行。
assert(i < 100)
i++;正確。
3. assert和後面的語句應該空一行,以形成邏輯和視覺上的一致性,也算是一種良好的編程習慣,讓編寫的代碼有一種視覺上的美感;程序一般分為Debug 版本和Release 版本,Debug 版本用於內部調試,Release 版本發行給用戶使用。斷言assert 是僅在Debug 版本起作用的宏,它用於檢查"不應該"發生的情況。
int resetBufferSize(int nNewSize)
{
//功能:改變緩衝區大小,
//參數:nNewSize 緩衝區新長度
//返回值:緩衝區當前長度
//說明:保持原信息內容不變 nNewSize<=0表示清除緩衝區
assert(nNewSize >= 0);
assert(nNewSize <= MAX_BUFFER_SIZE);
...
}在我們使用C語言/C++做工程項目時,如果我們能在代碼中合理的使用assert,能使我們創建更穩定、質量更好且不易於出錯的代碼;當需要在一個值為FALSE時中斷當前操作的話就可以使用斷言。
單元測試必須使用斷言;另外除了類型檢查和單元測試外,斷言還提供了一種確定各種特性是否在程序中得到維護的極好的方法;
最近原創推薦:
字符串操作的全面總結
代碼防禦性編程的十條技巧
九種查找算法
十大經典排序算法(動態演示+代碼)
C語言與C++面試知識總結
數據結構之堆棧
一文輕鬆理解內存對齊
點【在看】是最大的支持
讚賞誠可貴,在看轉發價更高