1. 程式人生 > >c語言中的assert函式

c語言中的assert函式

  函式名: assert

  功 能: 測試一個條件並可能使程式終止

  用 法: void assert(int test);

  程式例:

  #include <assert.h>

  #include <stdio.h>

  #include <stdlib.h>

  struct ITEM {

  int key;

  int value;

  };

  /* add item to list, make sure list is not null */

  void additem(struct ITEM *itemptr) {

  assert(itemptr != NULL);

  /* add item to list */

  }

  int main(void)

  {

  additem(NULL);

  return 0;

  }

  assert() 函式用法

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

  #include <assert.h>

  void assert( int expression );

  assert的作用是現計算表示式 expression ,如果其值為假(即為0),那麼它先向stderr列印一條出錯資訊,

  然後通過呼叫 abort 來終止程式執行。

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

  #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)在函式開始處檢驗傳入引數的合法性

  如:

  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不能代替條件過濾

  注意:當對於浮點數:

  #include<assert.h>

  // float pi=3.14;

  // assert(pi=3.14); //

  float pi=3.14f;

  assert (pi=3.14f);

  ---------------------------------------------------------

  在switch語句中總是要有default子句來顯示資訊(Assert)。

  int number = SomeMethod();

  switch(number)

  {

  case 1:

  Trace.WriteLine("Case 1:");

  break;

  case 2:

  Trace.WriteLine("Case 2:");

  break;

  default :

  Debug.Assert(false);

  break;

  }

相關推薦

C言中assert函式的用法

  2)每個assert只檢驗一個條件,因為同時檢驗多個條件時,如果斷言失敗,無法直觀的判斷是哪個條件失敗   不好: assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);   好:  assert(nOffset >

c言中 gotoxy() 函式的使用

轉自  https://blog.csdn.net/radjedef/article/details/79028329 #include <stdio.h> #include <windows.h> void gotoxy(int x, int y) {

關於C言中printf函式“輸出歧視”的問題

目錄 關於C語言中printf函式“輸出歧視”的問題 問題描述 探索問題原因 另一種研究方法 問題結論 關於C語言中printf函式“輸出歧視”的問題 問題描述 昨天晚上被問到一個問題,為什麼在同一個printf函式中兩次輸出一個double型變

c言中rand()函式的用法筆記

最近在學著用c寫一些小程式,過程中遇到很多問題,在網上查很多大神的講解,以及查閱vs2010的幫助文件。在此做個筆記,以便今後查閱,備忘。感謝無私奉獻講解的大神們! 一、rand() rand()函式用來產生隨機數,但是,rand()的內部實現是用線性同餘法實現的,是偽隨機數,由於週期較長,

(C言中printf函式讀取的具體分析)

(C語言中printf函式讀取的具體分析) 不多說,直接上。printf函式將傳入的資料傳送到記憶體堆區(緩衝區),然後再根據前面的(格式說明符一個個讀取,這樣會造成錯誤) #include<stdio.h> #include<limits.h> #incl

C言中main函式引數使用

在C99標準中定義main函式兩種正確的寫法 int main(void); int main(int argc, char* argv[]); 常見的不標準寫法 void main() main()

C言中strlen函式的模擬實現n種方法

strlen 函式採用遞迴形式編寫 # include <stdio.h> # include <stdlib.h> int strlen (char* num) // 形參接受實參傳遞的陣列 {

C言中scanf函式輸入回車符的問題

 在用c語言編寫輸入語句的時候常用到scanf函式,初學者在剛用scanf函式輸入時,經常會遇到各種各樣的輸入錯誤,最重要的是一定要記住scanf函式的輸入格式,scanf函式裡包含了哪些東西,輸入的時候就必須有哪些東西,比如:scanf("%c%c%c"),那麼輸入的時

c言中printf函式列印char型變數0xFF,輸出為0xFFFFFFFF的解決方法

問題描述:在編寫udp程式解析資料的時候,發現接收的char型變數為0xFF,但是使用printf後列印為0xFFFFFFFF,除錯程式查詢原因後發現使用char時,對於printf來說其值為0xFFFFFFFF。原因是%x要求的是無符號整形變數,你傳入的是char型,這裡有

C言中函式指標陣列的用途:轉移表

計算器的實現: 方法一: #include <stdio.h> int add(int a, int b) { return a + b; } int sub(int a, int b)

C言中 main 函式的引數 argc&argv

argc、argv用命令列編譯時有用 argc:整數 srgv:二維陣列、指標的指標、指標陣列 例子 #include<stdio.h> #include<stdlib.h> int main(int argc, char** argv) { i

c言中get()函式的原理及返回值

首先要記住的一句話就是Never use gets(). 這是因為gets()函式不檢查目標陣列是否能夠容納輸入,而若想把一個字串讀到程式中,最先要做的事情就是預留儲存字串的空間。所以這很容易導致分配的空間不夠大而陣列越界,然而gets()函式並不檢查這個方面,所以導致的結

c言中getchar()函式一個常見Error

getchar() 從這個名字來看應該是 得到一個字元。 正好C語言裡面有一個char型別, 很容易就出現瞭如下程式: # include <stdio.h> int main (voi

c言中signal函式詳細解釋說明

對於 訊號處理函式 位於 <signal.h> 中.void ( *signal( int sig, void (* handler)( int ))) ( int );這個函式的宣告很是嚇人, 一看就難弄懂. 下面是解釋用法.一步一步解釋:int (*p)();這是一個函式指標, p所指向的函

C言中fopen函式用法詳解

fopen函式用來開啟一個檔案,其呼叫的一般形式為:檔案指標名=fopen(檔名,使用檔案方式); 其中,“檔案指標名”必須是被說明為FILE 型別的指標變數;“檔名”被開啟檔案的檔名,是字串常量或字串陣列,要求是全路徑;“使用檔案方式”是指檔案的型別和操作要求。 檔案使用方

C言中函式不宣告也能使用,但會出現warning: implicit declaration of function

偶然發現有很多自定義函式未經宣告卻能在主程式中被呼叫,這就奇怪了,連使用標準庫函式printf()都要包括標準輸入輸出標頭檔案<stdio.h>,何況是自定義函式?這個問題困擾了我很久。 今天通過實驗,基本明白了箇中原因。一、在VC6中, 1、檔案test1.

14.C言中time函式和localtime獲取系統時間和日期

C語言中time函式和localtime獲取系統時間和日期可以通過time()函式來獲得計算機系統當前的日曆時間(Calendar Time),處理日期時間的函式都是以本函式的返回值為基礎進行運算。1. time 函式 返回1970-1-1, 00:00:00以來經過的秒數 

關於C言中printf函式的引數執行順序

RT...看到有類似的題目,說是從右到左,, 藍後在VS2012中寫了如下的程式碼...但是執行出來的結果如下,, 這是為啥...  留一疑惑在這先. ok,這裡有了一個解釋: i++會建立一個拷貝 %d取值輸出,引數的傳遞是從右到左壓入棧,所以從右邊開始,i++,此時拷貝

C言中atoi()函式實現--字串轉int型整數

C語言中有個atoi()函式,將字串轉成整數,返回int型別的數值。思路很簡單,但是有很多邊界和細節要處理,本文參考劍指offer上的例項,僅供參考。 #include <iostream&

C言中printf函式對多個引數的計算順序和輸出順序

例: [cpp] view plain copy print?#include<stdio.h> void main()   {       int i=2;       printf(”%d,%d,%d,%d,\n”,i++,++i,i,i++);       printf(”%d\n”,