編寫**時,我們總是會做出一些假設,斷言就是用於在**中捕捉這些假設,可以將斷言看作是異常處理的一種高階形式。斷言表示為一些布林表示式,程式設計師相信在程式中的某個特定點該表示式值為真。可以在任何時候啟用和禁用斷言驗證,因此可以在測試時啟用斷言,而在部署時禁用斷言。同樣,程式投入執行後,終端使用者在遇到問題時可以重新起用斷言。
前置條件斷言:**執行之前必須具備的特性
c裡面的巨集巨集名: assert
後置條件斷言:**執行之後必須具備的特性
前後不變斷言:**執行前後不能變化的特性
功 能: 測試乙個條件並可能使程式終止
用 法: void assert(int test);
程式例:
#include >
#include
#include
struct item {
int key;
int value;
/* add item to list, make sure list is not null */
void additem(struct item *itemptr) {
assert(itemptr != null);
/* add item to list */
int main(void)
additem(null);
return 0;
assert() 巨集用法
assert巨集的原型定義在中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義:
#include
void assert( int expression );
assert的作用是先計算表示式 expression ,如果其值為假(即為0),那麼它先向stderr列印一條出錯資訊,
然後通過呼叫 abort 來終止程式執行。
請看下面的程式清單badptr.c:
#include
#include
#include
int main( void )
file *fp;
fp = fopen( "test.txt", "w" );//以可寫的方式開啟乙個檔案,如果不存在就建立乙個同名檔案
assert( fp ); //所以這裡不會出錯
fclose( fp );
fp = fopen( "noexitfile.txt", "r" );//以唯讀的方式開啟乙個檔案,如果不存在就開啟檔案失敗
assert( fp ); //所以這裡出錯
fclose( fp ); //程式永遠都執行不到這裡來
return 0;
[root@localhost error_process]# gcc badptr.c
[root@localhost error_process]# ./a.out
a.out: badptr.c:14: main: assertion `fp' failed.
已放棄
使用assert的缺點是,頻繁的呼叫會極大的影響程式的效能,增加額外的開銷。
在除錯結束後,可以通過在包含#include 的語句之前插入 #define ndebug 來禁用assert呼叫,示例**如下:
#include
#define ndebug
#include
用法總結與注意事項:
1)在函式開始處檢驗傳入引數的合法性
如: int resetbuffersize(int nnewsize)
//功能:改變緩衝區
大小,
//引數:nnewsize 緩衝區新長度
//返回值:緩衝區當前長度
//說明:保持原資訊內容不變 nnewsize<=0表示清除緩衝區
assert(nnewsize >= 0);
assert(nnewsize <= max_buffer_size);
2)每個assert只檢驗乙個條件,因為同時檢驗多個條件時,如果斷言失敗,無法直觀的判斷是哪個條件失敗
不好: assert(noffset>=0 && noffset+nsize<=m_ninfomationsize);
好: assert(noffset >= 0);
assert(noffset+nsize <= m_ninfomationsize);
3)不能使用改變環境的語句,因為assert只在debug個生效,如果這麼做,會使用程式在真正執行時遇到問題
錯誤: assert(i++ < 100)
這是因為如果出錯,比如在執行之前i=100,那麼這條語句就不會執行,那麼i++這條命令就沒有執行。
正確: assert(i < 100)
i++;
4)assert和後面的語句應空一行,以形成邏輯和視覺上的一致感
5)有的地方,assert不能代替條件過濾
注意:當對於浮點數:
#include
// float pi=3.14;
// assert(pi=3.14); //
float pi=3.14f;
assert (pi=3.14f);
在switch語句中總是要有default子句來顯示資訊(assert)。
int number = somemethod();
switch(number)
case 1:
trace.writeline("case 1:");
break;
case 2:
trace.writeline("case 2:");
break;
default :
debug.assert(false);
break;
assert 斷言函式
void assert int expression 斷言函式,用於在除錯過程中捕捉程式的錯誤。斷言 在語文中的意思是 斷定 十分肯定地說 在程式設計中是指對某種假設條件進行檢測,如果條件成立就不進行任何操作,如果條件不成立就捕捉到這種錯誤,並列印出錯誤資訊,終止程式執行。assert 會對表示式e...
斷言assert是乙個巨集
斷言assert是乙個巨集,該巨集在 assert 中,當使用assert時候,給他個引數,即乙個判讀為真的表示式。預處理器產生測試該斷言的 如果斷言不為真,則發出乙個錯誤資訊告訴斷言是什麼以及它失敗一會,程式會終止。我們一般可以用在判斷某件操作是否成功上。以下是乙個記憶體複製程式,在執行過程中,如...
C C 中的assert 巨集 斷言機制
assert 是乙個除錯程式時經常使用的巨集,在程式執行時它計算括號內的表示式,如果表示式為false 0 程式將報告錯誤,並終止執行。如果表示式不為0,則繼續執行後面的語句。這個巨集通常原來判斷程式中是否出現了明顯非法的資料,如果出現了終止程式以免導致嚴重後果,同時也便於查詢錯誤。原型定義 inc...