Assert(斷言實現(xiàn)機制深入剖析)
斷言(assert)的作用是用來判斷程序運行的正確性,確保程序運行的行為與我們理解的一致。其調(diào)用形式為assert(logic expression),如果邏輯表達式為假,則調(diào)用abort()終止程序的運行。
查看MSDN幫助文檔,可以得到assert的解釋信息如下:
The ANSI assert macro is typically used to identify logic errors during program development, by implementing the expression argument to evaluate to false only when the program is operating incorrectly. After debugging is complete, assertion checking can be turned off without modifying the source file by defining the identifier NDEBUG. NDEBUG can be defined with a /D command-line option or with a #define directive. If NDEBUG is defined with #define, the directive must appear before ASSERT.H is included.
翻譯過來大概意思就是assert是通過判斷其參數(shù)的 來標識程序的邏輯錯誤,調(diào)試結(jié)束后可以通過定義NDEBUG來關(guān)閉assert斷言。
查看include/assert.h頭文件可以得到assert相關(guān)的宏寫義如下:
#ifdef NDEBUG
#define assert(exp) ((void)0)
#else
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _assert(void *, void *, unsigned);
#ifdef __cplusplus
}
#endif
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
#endif /* NDEBUG */
解釋:
#ifdef NDEBUG
#define assert(_Expression) ((void)0)//當調(diào)試完成后,如果定義了NDEBUG,關(guān)閉斷言,優(yōu)化生成的代碼
接下來的代碼意思是定義如下函數(shù)(此函數(shù)用于打印出出錯信息):
_wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);
有興趣的可以在assert.c中看到其實現(xiàn),函數(shù)先要把錯誤的報告模式以及程序的類型(控制臺程序還是GUI程序)決定assert是向標準錯誤輸出打印還是以消息框形式出現(xiàn),最后調(diào)用了abort()函數(shù)來終止程序的運行。 對于extern “C” 有時間再解釋
好了,到最后,終于看到了assert的宏定義了
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
解釋_Expresssion若為false,則!false=true,!true=false,此時繼續(xù)執(zhí)行||以后的語句,故會打印出出錯信息,終止程序,若_Expression為true,則!true=false,!false=true,此時不再執(zhí)行||以后的語句,故不會打印出信息。
值得注意的是,里面有一個逗號表達式,有興趣的可以研究一下,逗號表達式如下
(_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0)
asset斷言后返回的結(jié)果始終是void(1)/void(0),原因就在于逗號表達式。
Assert斷言在程序的作用
Assert的例子:
解釋:因為tmp=0,tmp==1為false,故程序運行的時候傳給assert宏的參數(shù)為false,因此調(diào)用的結(jié)果是先向stderr打印一條出錯信息,然后通過調(diào)用 abort 來終止程序運行。如果改成tmp=1,則程序完全正常運行。 如里在程序中想關(guān)閉assert宏斷言,可以如下defnie NDEBUG
你會發(fā)現(xiàn)即出tmp=0,也不會再出現(xiàn)斷言信息,解釋請看頂部
作用:
1:斷言可以用來檢查傳給函數(shù)參數(shù)的合法性
void max(int *a, int n)
{
assert(a!=null)//利用斷言確保傳給函數(shù)的參數(shù)不是一個空指針
}
2:一個斷言一般只用來檢查一個條件,便于分析程序【大師寫的<<編程珠璣>>斷言的藝術(shù)一個斷言可以&&與||好幾個條件,在我們不是大師之前,還最好不要這樣做~~~】
3: 斷言前后最好空一格[編程風格的問題,按你自已的喜好,適合自已就最好]
4:斷言只是用來檢查程序的邏輯正確性,不能代替條件替換
5:斷言比printf語句這種形式的打印好使~~~~
6:斷言參數(shù)可以是函數(shù)調(diào)用,但是函數(shù)返回值要是 ,如assert(sort()),解釋看上面源碼分析
欄 目:C語言
下一篇:全面解析C++中的new,operator new與placement new
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/4160.html
您可能感興趣的文章
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設計-用棧實現(xiàn)表達式求值的方法詳解
- 01-10使用OpenGL實現(xiàn)3D立體顯示的程序代碼
- 01-10求斐波那契(Fibonacci)數(shù)列通項的七種實現(xiàn)方法
- 01-10C語言 解決不用+、-、&#215;、&#247;數(shù)字運算符做加法
- 01-10使用C++實現(xiàn)全排列算法的方法詳解
- 01-10用C++實現(xiàn)DBSCAN聚類算法
- 01-10深入全排列算法及其實現(xiàn)方法
- 01-10全排列算法的非遞歸實現(xiàn)與遞歸實現(xiàn)的方法(C++)
- 01-10用C語言實現(xiàn)單鏈表的各種操作(一)
- 01-10用C語言實現(xiàn)單鏈表的各種操作(二)


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10delphi制作wav文件的方法