C/C++ assert()函數用法總結與注意事項

2021-12-25 CPP開發者

(給CPP開發者加星標,提升C/C++技能)

https://blog.csdn.net/linuxguitu/article/details/1096886861. 簡介

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;}
[root@localhost error_process]# gcc badptr.c [root@localhost 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>

2. 用法總結與注意事項:

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

int resetBufferSize(int nNewSize){          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個生效,如果這麼做,會使用程序在真正運行時遇到問題,如:

錯誤:

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

正確:

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

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

assert是用來避免顯而易見的錯誤的,而不是處理異常的。錯誤和異常是不一樣的,錯誤是不應該出現的,異常是不可避免的。c語言異常可以通過條件判斷來處理,其它語言有各自的異常處理機制。

 一個非常簡單的使用assert的規律就是,在方法或者函數的最開始使用,如果在方法的中間使用則需要慎重考慮是否是應該的。方法的最開始還沒開始一個功能過程,在一個功能過程執行中出現的問題幾乎都是異常。

- EOF -

關於 C/C++ assert()函數用法總結與注意事項,歡迎在評論中和我探討。覺得文章不錯,請點讚和在看支持我繼續分享好文。謝謝!

關注『CPP開發者』

看精選C++技術文章 . 加C++開發者專屬圈子

↓↓↓

點讚和在看就是最大的支持❤️

相關焦點

  • C/C assert()函數用法總結與注意事項
    請看下面的程序清單badptr.c:#include #include #include int main( void ){  FILE *fp;  //以可寫的方式打開一個文件,如果不存在就創建一個同名文件  fp = fopen( "test.txt", "w" );     //所以這裡不會出錯  assert( fp )
  • C語言C++中assert的用法
    assert宏的原型定義在<assert.h>中,其作用是先計算表達式expression的值為假(即為0),那麼它就先向stderr列印一條出錯信息,然後通過條用abort來終止程序;使用assert的缺點是,頻繁的調用會極大的影響程序的性能,增加額外的開銷。
  • 面試:C/C++常見庫函數實現
    ,memcpy函數的功能是從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中void* memcpy(void* dest,void* src,size_t n){    assert(dest !
  • 斷言(assert)的用法
    本文轉載自【微信公眾號:雲深之無跡,ID:TT1827652464】經微信公眾號授權轉載,如需轉載與原文作者聯繫斷言(assert)的用法我一直以為 assert 僅僅是個報錯函數,事實上,它居然是個宏,並且作用並非"報錯"。
  • C,C++關鍵詞用法
    void function1(const int Var);//傳遞過來的參數在函數內不可變,但是有拷貝void function2(const int& Var);// 引用參數在函數內為常量,沒有拷貝static的用法如果用來修飾全局變量時,該變量只在本文件內使用,同時變量值存儲在靜態區,在main函數執行前就已經分配了空間。
  • assert函數-論java中assert函數和Python、PHP、C語言assert函數
    最初的出發點都是為了方便調試而設計的,但是最近越來越多的開發者不分測試環境和正式環境濫用assert函數,引發了我對廣大程式設計師朋友的擔憂,故寫此篇文章普及assert函數常識,避免各位朋友濫用assert函數。簡單的概況在各個語言中assert函數的意義:如果表達式的值為假,整個程序將退出,並輸出一條錯誤信息。如果表達式的值為真則繼續執行後面的語句。
  • c++之重載函數學習總結
    當函數名和不同的參數搭配時函數的含義不同注意:在c語言中是沒有函數重載這個概念的。5、函數重載的注意事項:重載函數在本質上是相互獨立的不同函數重載函數的函數類型不同函數返回值不能作為函數重載的依據extern "c"{}1、下面進行一個c++中調用c函數,這裡我在當前創建三個文件:add.c 、add.h 、main.cpp。
  • C++語言中std::array的神奇用法總結
    在這篇文章裡,我會從各個角度介紹下std::array的用法,希望能帶來一些啟發。本文的代碼都在C++17環境下編譯運行。當前主流的g++版本已經能支持C++17標準,但是很多版本(如gcc 7.3)的C++17特性不是默認打開的,需要手工添加編譯選項-std=c++17。
  • 【C/C++語言經典講解】c++中冒號(:)和雙冒號(::)的用法和c/c++ 位域結構體
    首先是感謝大家對我們的支持,應大家要求,對大家提出的問題總結後,做了一篇文章講解介紹,介紹的知識是不經常使用的知識點,常用的知識點可以在書本上查看。class 派生類名 : 繼承方式 基類名 {派生類的成員};繼承方式:public、private和protected,默認處理是public。
  • C/C++可變參數函數
    c/c++支持可變參數的函數,即函數的參數是不確定的。一、為什麼要使用可變參數的函數?一般我們編程的時候,函數中形式參數的數目通常是確定的,在調用時要依次給出與形式參數對應的所有實際參數。但在某些情況下希望函數的參數個數可以根據需要確定,因此c語言引入可變參數函數。這也是c功能強大的一個方面,其它某些語言,比如fortran就沒有這個功能。典型的可變參數函數的例子有大家熟悉的printf()、scanf()等。二、c/c++如何實現可變參數的函數?
  • c++中的string常用函數用法總結
    標準c++中string類函數介紹注意不是CString之所以拋棄char*的字符串而選用
  • Python assert斷言函數及用法
    Python assert 語句,又稱斷言語句,可以看做是功能縮小版的 if 語句,它用於判斷某個表達式的值,如果值為真,則程序可以繼續往下執行
  • C語言與C++面試知識總結
    這是一篇 C 語言與 C++面試知識點總結的文章,如果你覺得文章對你有幫助,點個再看,分享給更多的人。assert 宏的原型定義在 <assert.h>(C)、(C++)中,其作用是如果它的條件返回錯誤,則終止程序執行。可以通過定義 NDEBUG 來關閉 assert,但是需要在原始碼的開頭,include <assert.h> 之前。
  • C 語言與 C++ 面試知識總結
    這是一篇 C 語言與 C++面試知識點總結的文章,如果你覺得文章對你有幫助,文末右下角點個再看轉發給更多的人。assert 宏的原型定義在 <assert.h>(C)、(C++)中,其作用是如果它的條件返回錯誤,則終止程序執行。可以通過定義 NDEBUG 來關閉 assert,但是需要在原始碼的開頭,include <assert.h> 之前。
  • C/C++中const關鍵字詳解
    如:     const int a=5; 與 int const a=5; 等同     類名 const 對象名 與 const 類名 對象名 等同用法1:常量    取代了C中的宏定義,聲明時必須進行初始化(!c++類中則不然)。
  • C 2 C++進階篇(1)
    首先談談筆者的水平,只學過c和數據結構,接觸過指針,對於取地址&從來沒有接觸過(因為據說是老師說不符合嚴謹的c....), python
  • python3使用ctypes在windows中訪問C和C++動態連結庫函數示例
    Python3.7.0 (源碼和安裝文件)http://ffmpeg.club/python二 C/C++部分代碼1 首先完成C/C++的動態連結庫,與做python擴展庫不同,ctypes調用的c++
  • c++11新特性,所有知識點都在這了!
    本文基本上涵蓋了c++11的所有新特性,並有詳細代碼介紹其用法,對關鍵知識點做了深入分析,對重要的知識點我單獨寫了相關文章並附上了相關連結,我整理了完備的c++新特性腦圖(由於圖片太大,我沒有放在文章裡,同學可以在後臺回復消息「新特性」,即可下載完整圖片)。
  • 新手入門:關於C++中的內聯函數(inline)
    >   在c++中,為了解決一些頻繁調用的小函數大量消耗棧空間或者是叫棧內存的問題,特別的引入了inline修飾符,表示為內聯函數。奇":"偶";    }  上面的例子就是標準的內聯函數的用法,使用inline修飾帶來的好處我們表面看不出來,其實在內部的工作就是在每個for循環的內部所有調用dbtest(i)的地方都換成了(i%2>0)?"奇":"偶"這樣就避免了頻繁調用函數對棧內存重複開闢所帶來的消耗。
  • c語言中的字符串操作函數
    一,常量指針與指針常量先來補充一個上篇文章 手把手教你深入理解c/c++中的指針 我在講述指針中的一個問題,有人說常量指針與指針常量這兩個概念總是混淆怎麼辦,例如:int a = 100;const int * p = &a;  int const * p = &a;