1. 程式人生 > >assert函式用發總結

assert函式用發總結

assert巨集的原型定義在<assert.h>中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義:

#include <assert.h>void assert( int expression );

 assert的作用是現計算表示式 expression ,如果其值為假(即為0),那麼它先向stderr列印一條出錯資訊,然後通過呼叫 abort 來終止程式執行。

請看下面的程式清單badptr.c:

[cpp] view plain copy print?
  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <stdlib.h>
  4. int main( void )  
  5. {  
  6.        FILE *fp;  
  7.        fp = fopen( "test.txt""w" );//以可寫的方式開啟一個檔案,如果不存在就建立一個同名檔案
  8.        assert( fp );                           //所以這裡不會出錯
  9.        fclose( fp );  
  10.        fp = fopen( "noexitfile.txt""r" );//以只讀的方式開啟一個檔案,如果不存在就開啟檔案失敗
  11.        assert( fp );                           //所以這裡出錯
  12.        fclose( fp );                           //程式永遠都執行不到這裡來
  13.        return 0;  
  14. }  
save_snippets.png
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main( void )
{
       FILE *fp;
    
       fp = fopen( "test.txt", "w" );//以可寫的方式開啟一個檔案,如果不存在就建立一個同名檔案
       assert( fp );                           //所以這裡不會出錯
       fclose( fp );
    
       fp = fopen( "noexitfile.txt", "r" );//以只讀的方式開啟一個檔案,如果不存在就開啟檔案失敗
       assert( fp );                           //所以這裡出錯
       fclose( fp );                           //程式永遠都執行不到這裡來
       return 0;
}

[[email protected] error_process]# gcc badptr.c 
[[email protected] error_process]# ./a.out 
a.out: badptr.c:14: main: Assertion `fp' failed.

使用assert()的缺點是,頻繁的呼叫會極大的影響程式的效能,增加額外的開銷。在除錯結束後,可以通過在包含#include <assert.h>的語句之前插入 #define NDEBUG 來禁用assert呼叫,示例程式碼如下:

#include <stdio.h>#define NDEBUG
#include <assert.h>

用法總結與注意事項:

  1)在函式開始處檢驗傳入引數的合法性如:

[cpp] view plain copy print?
  1. int resetBufferSize(int nNewSize)  
  2. {  
  3.   //功能:改變緩衝區大小,
  4.   //引數:nNewSize 緩衝區新長度
  5.   //返回值:緩衝區當前長度 
  6.   //說明:保持原資訊內容不變     nNewSize<=0表示清除緩衝區
  7.   assert(nNewSize >= 0);  
  8.   assert(nNewSize <= MAX_BUFFER_SIZE);  
  9.   ...  
  10. }  
save_snippets.png
int resetBufferSize(int nNewSize)
{
  //功能:改變緩衝區大小,
  //引數:nNewSize 緩衝區新長度
  //返回值:緩衝區當前長度 
  //說明:保持原資訊內容不變     nNewSize<=0表示清除緩衝區
  assert(nNewSize >= 0);
  assert(nNewSize <= MAX_BUFFER_SIZE);
  ...
}

  2)每個assert只檢驗一個條件,因為同時檢驗多個條件時,如果斷言失敗,無法直觀的判斷是哪個條件失敗,如:

  不好:

assert(nOffset>=0&& nOffset+nSize<=m_nInfomationSize);

  好:

assert(nOffset >=0);
assert(nOffset+nSize <= m_nInfomationSize);

  3)不能使用改變環境的語句,因為assert只在DEBUG個生效,如果這麼做,會使用程式在真正執行時遇到問題,如:

  錯誤:

assert(i++<100);

  這是因為如果出錯,比如在執行之前i=100,那麼這條語句就不會執行,那麼i++這條命令就沒有執行。

  正確:

 assert(i <100);
 i++;

  4)assert和後面的語句應空一行,以形成邏輯和視覺上的一致感。

  5)有的地方,assert不能代替條件過濾。

以下是使用斷言的幾個原則: 

  (1)使用斷言捕捉不應該發生的非法情況。不要混淆非法情況與錯誤情況之間的區別,後者是必然存在的並且是一定要作出處理的。 

  (2)使用斷言對函式的引數進行確認。 

  (3)在編寫函式時,要進行反覆的考查,並且自問:“我打算做哪些假定?”一旦確定了的假定,就要使用斷言對假定進行檢查。 

  (4)一般教科書都鼓勵程式設計師們進行防錯性的程式設計,但要記住這種程式設計風格會隱瞞錯誤。當進行防錯性程式設計時,如果“不可能發生”的事情的確發生了,則要使用斷言進行報警。 

  ASSERT ()是一個除錯程式時經常使用的巨集,在程式執行時它計算括號內的表示式,如果表示式為FALSE (0), 程式將報告錯誤,並終止執行。如果表示式不為0,則繼續執行後面的語句。這個巨集通常原來判斷程式中是否出現了明顯非法的資料,如果出現了終止程式以免導致嚴重後果,同時也便於查詢錯誤。  

ASSERT只有在Debug版本中才有效,如果編譯為Release版本則被忽略。  

比較好的在程式中使用assert的地方:

(1)空指標檢查。例如,針對一個函式的引數進行空指標檢查。你可以這樣使用:assert (pointer != NULL);,產生的錯誤會像這樣:Assertion ‘pointer != ((void *)0)’ failed。這樣,當出現空指標時,你的程式就會退出,並很好的給出錯誤資訊。

(2)檢查函式引數的值。例如,如果一個函式只能在它的一個引數foo為正值的時候被呼叫,你可以在函式開始時這樣寫:assert (foo > 0);,這將幫助你檢測函式的錯誤使用,這也給原始碼閱讀者很清晰的印象,那就是在這裡對函式的引數值有限制。


相關推薦

assert函式總結

assert巨集的原型定義在<assert.h>中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義: #include <assert.h>void assert( int expression );  assert的作用是現計算表示式 expression ,如果

C/C++ assert()函式用法總結

轉自:https://www.cnblogs.com/lvchaoshun/p/7816288.html   assert巨集的原型定義在<assert.h>中,其作用是如果它的條件返回錯誤,則終止程式執行。 原型定義: #include <assert.

解決try except 捕獲assert函式產生的AssertionError異常時,導致斷言失敗的例在測試報告中通過的問題

  在使用Python3做自動化測試過程中可能會遇到,assert函式不加try  except,就可以正常在報告裡體現用例不通過,加上變成通過。 這是因為在使用try except 時,捕獲了assert函式產生的AssertionError異常,導致異常沒有上拋,這時只需要在後面加上 rais

assert()函式用法總結

assert巨集的原型定義在<assert.h>中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義: #include <assert.h> void assert( int expression );  assert的作用是現計算表示式

C語言:assert()函式用法總結

  assert巨集的原型定義在<assert.h>中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義: #include <assert.h>void assert( int expression );   assert的作用是現計算表示式 expression ,如果

三十四 assert()函式用法總結

 assert巨集的原型定義在<assert.h>中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義: #include <assert.h>void assert( int expression );   assert的作用是現計算表示式 

location.href的總結

信息 重新 更新 sel tar set 定義 .html 服務 *.location.href 用法:  top.location.href=”url” 在頂層頁面打開url(跳出框架)  self.location.href=”url”

【實踐】簡潔大方的summernote 富文本編輯器插件的——實例篇

user 路徑 z-index 寫上 eno error: 而已 tab size 實例化後的summernote 是這樣子的 很漂亮對吧,而我做成頁面效果是這樣的: 先說說實例化一個summernote 的方法把,其實也不難,jq 選擇器選擇一個要變成富文本編

Java多線程和並總結

避免 rec load 內存模型 es2017 ade book 返回 throws Java多線程和高並發總結 wait/notify必須存在於synchronized塊中。 volatile多線程的內存模型:main memory(

assert()函數用法總結

abort blog archive 表達 buffers 緩沖 log ... 出錯 cited from: http://www.cnblogs.com/ggzss/archive/2011/08/18/2145017.html assert宏的原型定義在<a

數據庫各種改表sql寫總結

更新 template tab code uniq 負責 刪除表 sage drop //修改已存在的表的字段屬性ALTER TABLE region_info MODIFY code_name varchar(20) default ‘‘; //刪除索引ALTER TAB

簡單演示django使用之五--(django概完結總結篇)

內容 正則 創建 5.7 五步 讀寫 應用名稱 如果 管理 經過前面四篇基本的django使用,下面對django這個web開發框架做個小小的個人總結: ??首先,打開瀏覽器訪問站點後,請求直接到服務器端。作為django的web服務器,接收請求的是由view視圖來處理,此

recv函式返回值總結

函式原型:int recv( SOCKET s, char *buf, int  len, int flags) 功能:不論是客戶還是伺服器應用程式都用recv函式從TCP連線的另一端接收資料。 引數一:指定接收端套接字描述符; 引數二:指明一個緩衝區,該緩衝區用來存放recv

python包-numpy的函式和屬性總結(一)

NumPy是高效能科學計算和資料分析的基礎包。 接下來為大家總結一些它的一些基礎知識。 目錄 0.匯入numpy的包 1.資料型別 2.常用函式 3.NumPy.ndarray的屬性 4.NumPy.ndarray的函式 5.NumPy.ndarray的索引與切片

C語言assert函式完全攻略

斷言assert函式,C語言assert函式完全攻略 對於斷言,相信大家都不陌生,大多數程式語言也都有斷言這一特性。簡單地講,斷言就是對某種假設條件進行檢查。在 C 語言中,斷言被定義為巨集的形式(assert(expression)),而不是函式,其原型定義在<assert.h>檔

sprintf()函式的用法總結

https://blog.csdn.net/u013485792/article/details/50475473 sprintf()函式的程式用例: #include  #include int main(void) { char buffer[80]; sprintf(buffer,

c 函式引數(總結

函式引數為兩種:形式引數和實際引數 1.形式引數 形參出現在被調函式當中,在整個函式體內都可以使用。形參在定義時編譯系統並不分配儲存空間,只有在呼叫該函式時才分配記憶體單元。呼叫結束記憶體單元被釋放,故形參只有在函式呼叫時有效,呼叫結束時不能再使用。

tf.py_func函式來擴充套件tensorflow的靈活性

tf.py_func(func, inp, Tout) 在這裡第一個引數是核心,也就是一個使用者自定義的函式,輸入是numpy array,輸出也是numpy array,在該函式中,使用者可以自由的使用numpy 操作 第二個引數是inp,是func函式接受的輸入,是一個列表。 第三個

Python中常用操作字串的函式與方法總結

本文轉載自:https://www.jb51.net/article/79196.htm Python中常用操作字串的函式與方法總結 這篇文章主要介紹了Python中常用操作字串的函式與方法總結,包括字串的格式化輸出與拼接等基礎知識,需要的朋友可以參考下 例如這樣一個字串 Python,

C++快速入門---assert函式和捕獲異常(22)

C++快速入門---assert函式和捕獲異常(22)   assert()函式,專為除錯而準備的工具函式。 assert()函式需要有一個引數,它將測試這個輸入引數的真 or 假狀態。 #include <iostream> #include <cass