C語言解讀assert函式
- 在 C 語言中,斷言被定義為巨集的形式(assert(expression)),而不是函式,其原型定義在<assert.h>檔案中。其中,assert 將通過檢查表示式 expression 的值來決定是否需要終止執行程式。也就是說,如果表示式 expression 的值為假(即為 0),那麼它將首先向標準錯誤流 stderr 列印一條出錯資訊,然後再通過呼叫 abort 函式終止程式執行;否則,assert 無任何作用。
#include <assert.h>
void assert( int expression );
- 預設情況下,assert 巨集只有在 Debug 版本(內部除錯版本)中才能夠起作用,而在 Release 版本(發行版本)中將被忽略。當然,也可以通過定義巨集或設定編譯器引數等形式來在任何時候啟用或者禁用斷言檢查(不建議這麼做)。同樣,在程式投入執行後,終端使用者在遇到問題時也可以重新起用斷言。這樣可以快速發現並定位軟體問題,同時對系統錯誤進行自動報警。對於在系統中隱藏很深,用其他手段極難發現的問題也可以通過斷言進行定位,從而縮短軟體問題定位時間,提高系統的可測性。
- 已放棄使用assert()的缺點是,頻繁的呼叫會極大的影響程式的效能,增加額外的開銷。在除錯結束後,可以通過在包含#include <assert.h>的語句之前插入 #define NDEBUG 來禁用assert呼叫,示例程式碼如下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>
-
儘量在函式中使用斷言來檢查引數的合法性
在函式中使用斷言來檢查引數的合法性是斷言最主要的應用場景之一,它主要體現在如下 3 個方面:- 在程式碼執行之前或者在函式的入口處,使用斷言來檢查引數的合法性,這稱為前置條件斷言。
- 在程式碼執行之後或者在函式的出口處,使用斷言來檢查引數是否被正確地執行,這稱為後置條件斷言。
- 在程式碼執行前後或者在函式的入出口處,使用斷言來檢查引數是否發生了變化,這稱為前後不變斷言。
-
Memcpy 函式中,除了可以通過“assert(dest !=NULL&&src!=NULL);”語句在函式的入口處檢查 dest 與 src 引數是否傳入 NULL 指標之外,還可以通過“assert(tmp_dest>=tmp_src+len||tmp_src>=tmp_dest+len);”語句檢查兩個記憶體塊是否發生重疊。如下面的示例程式碼所示:
void *Memcpy(void *dest, const void *src, size_t len)
{
assert(dest!=NULL && src!=NULL);
char *tmp_dest = (char *)dest;
char *tmp_src = (char *)src;
/*檢查記憶體塊是否重疊*/
assert(tmp_dest>=tmp_src+len||tmp_src>=tmp_dest+len);
while(len --)
*tmp_dest ++ = *tmp_src ++;
return dest;
}
- 除此之外,建議每一個 assert 巨集只檢驗一個條件,這樣做的好處就是當斷言失敗時,便於程式排錯。試想一下,如果在一個斷言中同時檢驗多個條件,當斷言失敗時,我們將很難直觀地判斷哪個條件失敗。因此,下面的斷言程式碼應該更好一些,儘管這樣顯得有些多此一舉:
assert(dest!=NULL);
assert(src!=NULL);
- 最後,建議 assert 巨集後面的語句應該空一行,以形成邏輯和視覺上的一致感,讓程式碼有一種視覺上的美感。同時為複雜的斷言新增必要的註釋,可澄清斷言含義並減少不必要的誤用。
相關文章
- C 語言回撥函式詳解函式
- Python assert斷言函式及用法Python函式
- C語言的函式C語言函式
- C語言 execve()函式C語言函式
- C語言常用函式C語言函式
- C語言 函式指標C語言函式指標
- C語言基礎函式C語言函式
- 08. C語言函式C語言函式
- C語言函式呼叫棧C語言函式
- C語言qsort函式的使用C語言函式
- C語言庫函式及示例C語言函式
- C語言函式sscanf()的用法C語言函式
- C#語言函式遞迴C#函式遞迴
- C語言函式指標與回撥用函式C語言函式指標
- c語言快速排序(庫函式使用)C語言排序函式
- C語言有關函式淺析C語言函式
- c語言學習筆記===函式C語言筆記函式
- C語言巨集和函式淺析C語言函式
- C 語言實現泛型 swap 函式泛型函式
- c語言函式指標的定義C語言函式指標
- C語言函式指標與回撥函式使用方法C語言函式指標
- Go 語言函式Go函式
- 瞭解 JavaScript 函數語言程式設計 - 宣告式函式JavaScript函數程式設計函式
- c語言是如何處理函式呼叫的?C語言函式
- C語言相關的基礎字串函式C語言字串函式
- 【C語言】函式的概念和函式的呼叫(引數傳遞)C語言函式
- C語言函式傳遞指標引數的問題詳解C語言函式指標
- c/c++語言函式 stat, fstat, lstat, fstatat - get file statusC++函式
- 【C語言】常用的字串函式及相關函式的自我實現C語言字串函式
- C語言_輸入輸出函式_PAGE5C語言函式
- 包含min函式的棧(劍指offer)---C語言函式C語言
- c語言獲取陣列長度的函式C語言陣列函式
- C語言-字串函式的實現(五)之strstrC語言字串函式
- C語言-字串函式的實現(一)之strlenC語言字串函式
- Go 語言 -make函式Go函式
- R語言函式-tolowerR語言函式
- GO語言————6.1 函式Go函式
- python是函式式語言嗎Python函式