c語言中assert斷言用法實(shí)例詳解
一、斷言的概念
assert.h 頭?件定義了宏 assert() ,用于在運(yùn)行時(shí)確保程序符合指定條件,如果不符合,就報(bào)錯(cuò)終止運(yùn)行。這個(gè)宏常常被稱為“斷言”。
二、assert斷言
assert(p != NULL);
上面代碼在程序運(yùn)行到這一行語句時(shí),驗(yàn)證變量 p 是否等于 NULL 。如果確實(shí)不等于 NULL ,程序繼續(xù)運(yùn)行,否則就會(huì)終止運(yùn)行,并且給出報(bào)錯(cuò)信息提升。assert() 宏接受?個(gè)表達(dá)式作為參數(shù)。如果該表達(dá)式為真(返回值非零),assert() 不會(huì)產(chǎn)?任何作用,程序繼續(xù)運(yùn)行。如果該表達(dá)式為假(返回值為零), assert() 就會(huì)報(bào)錯(cuò),在標(biāo)準(zhǔn)錯(cuò)誤流 stderr 中寫??條錯(cuò)誤信息,顯示沒有通過的表達(dá)式,以及包含這個(gè)表達(dá)式的文件名和行號(hào)。
2.1 代碼1
#include<stdio.h> int main() { int* p = NULL; assert(p != NULL); return 0; }
2.1.1運(yùn)行結(jié)果
這里顯示assert未定義,需要包含頭文件
#include<assert.h>
完整代碼:
#include<stdio.h> #include<assert.h> int main() { int* p = NULL; assert(p != NULL); return 0; }
再次運(yùn)行,運(yùn)行結(jié)果:
2.1.2分析
報(bào)錯(cuò)會(huì)告訴你在哪一行。
2.2代碼2
#include<stdio.h> #include<assert.h> int main() { int a = 10; int* p = &a; assert(p != NULL); printf("%d", *p); return 0; }
2.2.1運(yùn)行結(jié)果
2.2.2分析
assert不等于 NULL ,程序繼續(xù)運(yùn)行,結(jié)果沒有報(bào)錯(cuò)。
2.3代碼3
#include<stdio.h> #include<assert.h> int main() { int a = 0; scanf("%d", &a); assert(a>10); printf("%d", a); return 0; }
2.3.1運(yùn)行結(jié)果及其分析
三、優(yōu)點(diǎn)
assert() 的使用對(duì)程序員是非常友好的,使用 assert() 有幾個(gè)好處:它不僅能?動(dòng)標(biāo)識(shí)文件和出問題的行號(hào),還有?種?需更改代碼就能開啟或關(guān)閉 assert() 的機(jī)制。如果已經(jīng)確認(rèn)程序沒有問題,不需要再做斷言,就在 #include <assert.h> 語句的前面,定義?個(gè)宏 NDEBUG 。
#define NDEBUG #include <assert.h>
然后,重新編譯程序,編譯器就會(huì)禁用文件中所有的 assert() 語句。如果程序?出現(xiàn)問題,可以移除這條 #define NDBUG 指令(或者把它注釋掉),再次編譯,這樣就重新啟用了 assert() 語句。
代碼:
#include<stdio.h> #define NDEBUG #include<assert.h> int main() { int a = 0; scanf("%d", &a); assert(a>10); printf("%d", a); return 0; }
運(yùn)行結(jié)果及其分析:
四、缺點(diǎn)
因?yàn)橐?了額外的檢查,增加了程序的運(yùn)行的時(shí)間。
五、注意
一般我們可以在 Debug 中使用,在 Release 版本中選擇禁用 assert 就行,在 VS 這樣的集成開發(fā)環(huán)境中,在 Release 版本中,直接就是優(yōu)化掉了。這樣在debug版本寫有利于程序員排查問題,在 Release 版本不影響用戶使用時(shí)程序的效率。
附:用法總結(jié)與注意事項(xiàng)
1)在函數(shù)開始處檢驗(yàn)傳入?yún)?shù)的合法性,如:
int resetBufferSize(int nNewSize){undefined //功能:改變緩沖區(qū)大小, //參數(shù):nNewSize 緩沖區(qū)新長度 //返回值:緩沖區(qū)當(dāng)前長度 //說明:保持原信息內(nèi)容不變 nNewSize<=0表示清除緩沖區(qū) assert(nNewSize >= 0); assert(nNewSize <= MAX_BUFFER_SIZE); … }
2)每個(gè)assert只檢驗(yàn)一個(gè)條件,因?yàn)橥瑫r(shí)檢驗(yàn)多個(gè)條件時(shí),如果斷言失敗,無法直觀的判斷是哪個(gè)條件失敗
不好: assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);
好:
assert(nOffset >= 0); assert(nOffset+nSize <= m_nInfomationSize);
3)不能使用改變環(huán)境的語句,因?yàn)閍ssert只在DEBUG中生效,如果這么做,會(huì)使用程序在真正運(yùn)行時(shí)遇到問題
錯(cuò)誤: assert(i++ < 100)
這是因?yàn)槿绻鲥e(cuò),比如在執(zhí)行之前i=100,那么這條語句就不會(huì)執(zhí)行,那么i++這條命令就沒有執(zhí)行。
正確:
assert(i < 100) i++;
4)assert和后面的語句應(yīng)空一行,以形成邏輯和視覺上的一致感
總結(jié)
到此這篇關(guān)于c語言中assert斷言用法的文章就介紹到這了,更多相關(guān)c語言assert斷言詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)一個(gè)簡單的線程池的示例代碼
本文主要介紹了C++實(shí)現(xiàn)一個(gè)簡單的線程池的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05如何寫好C main函數(shù)的幾個(gè)注意事項(xiàng)
這篇文章主要介紹了如何寫好C main函數(shù)的幾個(gè)注意事項(xiàng),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06C語言中字符串和數(shù)字的相互轉(zhuǎn)換實(shí)現(xiàn)代碼
以下是對(duì)C語言中字符串和數(shù)字的相互轉(zhuǎn)換實(shí)現(xiàn)代碼進(jìn)行了分析介紹,需要的朋友可以參考下2013-07-07C++實(shí)現(xiàn)簡單版圖書管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡單版圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06C++11新特性中auto 和 decltype 區(qū)別和聯(lián)系
這篇文章主要介紹了C++11新特性中auto 和 decltype 區(qū)別和聯(lián)系的相關(guān)資料,需要的朋友可以參考下2017-01-01