1 異常終止
標準c庫提供了abort()和exit()兩個函式,它們可以強行終止程式的執行,其宣告處於
標頭檔案中。這兩個函式本身不能檢測異常,但在c程式發生異常後經常使用這兩個函式進行程式終止。下面的這個例子描述了exit()的行為:
code:#include在這個例子中,main函式一開始就執行了exit函式(此函式原型為void exit(int)),因此,程式不會輸出"程式不會執行到這裡"。程式中的exit(exit_success)表示程式正常結束,與之對應的exit(exit_failure)表示程式執行錯誤,只能強行終止。exit_success、exit_failure分別定義為0和1。#include
int main(void)
對於exit函式,我們可以利用atexit函式為exit事件"掛接"另外的函式,這種"掛接"有點類似windows程式設計中的"鉤子"(hook)。譬如:
code:#include程式輸出"atexit掛接的函式"後即終止。來看下面的程式,我們不呼叫exit函式,看看atexit掛接的函式會否執行:#include
static void atexitfunc(void)
int main(void)
code:#include程式輸出:#include
static void atexitfunc(void)
int main(void)
不呼叫exit函式
atexit掛接的函式
這說明,即便是我們不呼叫exit函式,當程式本身退出時,atexit掛接的函式仍然會被執行。
atexit可以被多次執行,並掛接多個函式,這些函式的執行順序為後掛接的先執行,例如:
code:#include在visual c++中,如果以abort函式(此函式不帶引數,原型為void abort(void))終止程式,則會在debug模式執行時彈警告對話方塊。#include
static void atexitfunc1(void)
static void atexitfunc2(void)
static void atexitfunc3(void)
int main(void)
輸出的結果是:
atexit掛接的函式3
atexit掛接的函式2
atexit掛接的函式1
2 斷言(assert)
assert巨集在c語言程式的除錯中發揮著重要的作用,它用於檢測不會發生的情況,表明一旦發生了這樣的情況,程式就實際上執行錯誤了,例如strcpy函式:
code:char *strcpy(char *strdest, const char *strsrc)其中包含斷言assert( (strdest != null) && (strsrc != null) ),它的意思是源和目的字串的位址都不能為空,一旦為空,程式實際上就執行錯誤了,會引發乙個abort。
assert巨集的定義為:
code:#ifdef ndebug如果程式不在debug模式下,assert巨集實際上什麼都不做;而在debug模式下,實際上是對_assert()函式的呼叫,此函式將輸出發生錯誤的檔名、**行、條件表示式。例如下列程式:#define assert(exp) ((void)0)
#else
#ifdef __cplusplus
extern "c"
#endif
#define assert(exp) (void)( (exp) || (_assert(#exp, __file__, __line__), 0) )
#endif /* ndebug */
code:#include在此程式中,為了避免我們的strcpy與c庫中的strcpy重名,將其改為mystrcpy。#include
#include
char * mystrcpy( char *strdest, const char *strsrc )
int main(void)
失敗的斷言也會彈出對話方塊,這是因為_assert()函式中也呼叫了abort()函式。
一定要記住的是assert本質上是乙個巨集,而不是乙個函式,因而不能把帶有***的表示式放入assert的"引數"中。
3 errno
errno在c程式中是乙個全域性變數,這個變數由c執行時庫函式設定,使用者程式需要在程式發生異常時檢測之。c執行庫中主要在math.h和stdio.h標頭檔案宣告的函式中使用了errno,前者用於檢測數**算的合法性,後者用於檢測i/o操作中(主要是檔案)的錯誤,例如:
code:#include在此程式中,如果檔案開啟失敗(fopen返回null),證明發生了異常。我們讀取error可以獲知錯誤的原因,如果d盤根目錄下不存在"1.txt"檔案,將輸出2,表示檔案不存在;在檔案存在並正確開啟的情況下,將執行到else語句,輸出0,證明errno沒有被設定。#include
#include
int main(void)
else
return 0;
}
visual c++提供了兩種版本的c執行時庫。-個版本供單執行緒應用程式呼叫,另乙個版本供多執行緒應用程式呼叫。多執行緒執行時庫與單執行緒執行時庫的乙個重大差別就是對於類似errno的全域性變數,每個執行緒單獨設定了乙個。因此,對於多執行緒的程式,我們應該使用多執行緒c執行時庫,才能獲得正確的error值。
另外,在使用errno之前,我們最好將其設定為0,即執行errno = 0的賦值語句。
4 其它
除了上述異常處理方式外,在c語言中還支援非區域性跳轉(使用setjmp和longjmp)、訊號(使用signal、raise)、返回錯誤值或回傳錯誤值給引數等方式進行一定能力的異常處理,但是其使用不如上面所介紹方式常用,我們不必過細研究。
從以上分析可知,c語言的異常處理是簡單而不全面的。與c++的異常處理比起來,c語言異常處理相形見絀,它就像乙個新生的雛嬰。
異常處理(三 C 語言異常處理)
1 c 異常處理語法 c 語言的後期改造者們,他們在標準c 語言中專門整合了異常處理的相關語法 與之不同的是,所有的c 標準庫異常體系都需要執行庫的支援,它不是語言核心支援的 當然,異常處理被加到程式語言中,也是程式語言發展和逐步完善的必然結果。我們看到,c 不是唯一整合異常處理的語言。c 的異常處...
C 異常處理(二)
1.標準異常 c 標準庫中定義一組類,用於報告在標準庫中的函式遇到的問題。程式設計師以在自己編寫的程式中使用這些標準異常類。標準庫異常類定義在四個標頭檔案中 exception標頭檔案中定義了最常見的異常類,類名是exception,這個類只通知異常的產生,不會提供更多的資訊 stdexcept標頭...
的異常處理 C 異常處理總結
做開發不僅僅要考慮到業務邏輯更要在寫 時將各種可能考慮周全,但是這又是很難的事情,畢竟開發就是個人的事,而使用者可能上萬甚至百萬級別。這時,程式的穩定性就極為重要,我們不能讓程式因為某一處執行出問題而就直接導致程式或者產生其他更嚴重的後果,比如 做除法時當除數為零時,陣列訪問越界時,容器capaci...