我試試能不能講半個(gè)小時(shí):)
斷言是什么?
assert()是一個(gè)定義在<assert.h>的宏,接受一個(gè)布爾值,若為真(非0)則繼續(xù)執(zhí)行;為假(即為0),那么它先向stderr打印一條出錯(cuò)信息,然后通過調(diào)用 abort 來終止程序運(yùn)行。我們知道程序的正確執(zhí)行需要滿足一定的條件(或規(guī)避一些條件),而斷言就是確保我們的程序能按我們期望的條件向下執(zhí)行。
| 假 | 真 |
|---|---|
| 中斷 | 繼續(xù) |
為什么用斷言?
使用斷言可以創(chuàng)建更穩(wěn)定,品質(zhì)更好且不易于出錯(cuò)的代碼。因?yàn)?code>assert()用來判斷條件是否滿足,因此使用斷言使我們向按契約式設(shè)計(jì)更近了一步。
如何使用斷言:
#include<assert.h>
assert(Expression)
其中Expression的結(jié)果是一個(gè)布爾值
1.可以在預(yù)計(jì)正常情況下程序不會(huì)到達(dá)的地方放置斷言 :assert false
2.斷言可以用于檢查傳遞給私有方法的參數(shù)。(對(duì)于公有方法,因?yàn)槭翘峁┙o外部的接口,所以必須在方法中有相應(yīng)的參數(shù)檢驗(yàn)才能保證代碼的健壯性)
3.使用斷言測(cè)試方法執(zhí)行的前置條件和后置條件
4.使用斷言檢查類的不變狀態(tài),確保任何情況下,某個(gè)變量的狀態(tài)必須滿足。(如age屬性應(yīng)大于0小于某個(gè)合適值)
不用斷言
斷言語句不是永遠(yuǎn)會(huì)執(zhí)行,可以屏蔽也可以啟用
因此:
1.不要使用斷言作為公共方法的參數(shù)檢查,公共方法的參數(shù)永遠(yuǎn)都要執(zhí)行
2.斷言語句不可以有任何邊界效應(yīng),不要使用斷言語句去修改變量和改變方法的返回值.
缺點(diǎn)
頻繁的調(diào)用會(huì)極大的影響程序的性能,增加額外的開銷。在調(diào)試結(jié)束后,可以通過在包含#include <assert.h>的語句之前插入 #define NDEBUG 來禁用assert調(diào)用,示例代碼如下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>
程序一般分為Debug 版本和Release 版本,Debug 版本用于內(nèi)部調(diào)試,Release 版本發(fā)行給用戶使用。
斷言assert 是僅在Debug 版本起作用的宏,它用于檢查“不應(yīng)該”發(fā)生的情況。assert 不是一個(gè)倉促拼湊起來的宏。為了不在程序的Debug 版本和Release 版本引起差別,assert 不應(yīng)該產(chǎn)生任何副作用。所以assert 不是函數(shù),而是宏。
為什么要區(qū)分Debug和Release?
在我看來主要是針對(duì)其面向的目標(biāo)不同的而進(jìn)行區(qū)分的。Debug通常稱為調(diào)試版本,通過一系列編譯選項(xiàng)的配合,編譯的結(jié)果通常包含調(diào)試信息,而且不做任何優(yōu)化,以為開發(fā)人員提供強(qiáng)大的應(yīng)用程序調(diào)試能力。而Release通常稱為發(fā)布版本,是為用戶使用的,一般客戶不允許在發(fā)布版本上進(jìn)行調(diào)試。所以不保存調(diào)試信息,同時(shí),它往往進(jìn)行了各種優(yōu)化,以期達(dá)到代碼最小和速度最優(yōu)。為用戶的使用提供便利。