五、錯誤處理:
1、錯誤報告處理。
編程中要求考慮函數的各種執行情況,盡可能處理所有的流程情況。將函數分為兩類:
一類為與屏幕的顯示無關,(不與用戶交換信息的函數)
一類為與屏幕的顯示相關。(與用戶交換信息的函數)
對於與屏幕顯示無關的函數,函數通過返回值來報告錯誤。
對於與屏幕顯示有關的函數,函數要負責向用戶發出警告,並進行錯誤處理。
錯誤處理代碼一般單獨建立通用處理函數。如下:
void cmDeal_With_Error(long ErrCode)
{
switch(ErrCode)
{
case 1://注釋
......
case 2://注釋
......
default://注釋
......
}
}
2、盡早發現程序中的錯誤:
①、重視編譯器中的警告信息。
對於編譯器產生的警告信息,我們應該引起足夠的重視,實際上許多警告信息指示了程序中潛在的錯誤危險。所以我們要認真檢查每一個警告信息,查看是否有某種隱患。盡量消除警告信息。
②、利用斷言來檢查錯誤
對於程序中的某種假設,或防止某些參數的非法值,利用斷言來幫助查錯是一種好的辦法。
例如下面的函數:
long cmMemCpy(void * pvToMem, void* pvFromMem, size_t wSize)
{
……
if(pvToMem==NULL||pvFromMem==NULL)
{
lResult=CM _POINT_IS_NULL;
goto: END;
}
while(wSize-- >0)
{
*pvToMem++=pvFromMem++;
}
END:
return lResult;
}
采用判斷可以檢查傳入的指針錯誤,但是這樣的判斷是程序最終的編譯代碼變大,同時降低了最終發布的程序的執行效率。由於傳入空指針明顯是調用這函數的程序的錯誤,而不是這個函數的錯誤,我們可以考慮采用斷言來代替指針檢查,即用
ASSERT( pvToMem!=NULL&&pvFromMem!=NULL)
代替
if(pvToMem==NULL||pvFromMem==NULL)
{
lResult=CM_POINT_IS_NULL;
goto: END;
}
這樣只會在debug版中才會產生檢查代碼,而在正式發布版中不會帶有這些代碼。並且可以方便我們在程序調試中和測試時發現錯誤,同時又不影響程序的效率。
在下面的一些情況中必須加斷言:
a、數的參數,特別是指針參數必須利用斷言來進行確認。
b、利用斷言檢查程序中的各種假設的正確性。
c、在程序設計中不要輕易認為某種情況不可能發生,對你認為不可能發生的情況必須用斷言來證實。
為了使程序中的斷言發揮作用,所有用於在開發內部進行測試或調試的動態庫、執行程序、組件必須采用debug版。
說明:
在程序效率要求較高、或者調用比較頻繁的函數,對入口參數的錯誤檢查,使用斷言方式,其優點如上所敘,但其健壯性不強,所以在其他情況下,仍要求使用傳統的檢查方式,以增強程序的健壯性,當然,為了調試方便,可同時使用斷言方式。
③、嚴格的測試:
對每一段代碼都要求進行嚴格的測試,特別對一些功能函數要對其各種臨界點(比如零值、無窮大的值等)進行測試。盡量做到每一段代碼零錯誤。