• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            assert() 函數(shù)用法

            Posted on 2011-04-20 21:18 RTY 閱讀(1019) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++

            assert宏的原型定義在assert.h中,其作用是如果它的條件返回錯(cuò)誤,則終止程序執(zhí)行.
              原型定義:

            顯示代碼打印1   #include "assert.h" 

            2   void assert( int expression );


              assert的作用是現(xiàn)計(jì)算表達(dá)式 expression ,如果其值為假(即為0),那么它先向stderr打印一條出錯(cuò)信息,然后通過調(diào)用 abort 來終止程序運(yùn)行。
              
              請(qǐng)看下面的程序清單badptr.c:

            顯示代碼打印01   #include  

            02   #include  

            03   #include  

            04   int main( void )  

            05   {  

            06    FILE *fp;  

            07     

            08    fp = fopen( "test.txt", "w" );//以可寫方式打開一個(gè)文件,如果不存在就創(chuàng)建一個(gè)同名文件  

            09    assert( fp ); //所以這里不會(huì)出錯(cuò)  

            10    fclose( fp );  

            11     

            12    fp = fopen("noexitfile.txt", "r" );//以只讀方式打開一個(gè)文件,如果不存在就打開文件失敗  

            13    assert( fp ); //所以這里出錯(cuò)  

            14    fclose( fp ); //程序永遠(yuǎn)都執(zhí)行不到這里來  

            15     

            16    return 0;  

            17   }


              
              使用assert的缺點(diǎn)是,頻繁的調(diào)用會(huì)極大的影響程序的性能,增加額外的開銷。
              在調(diào)試結(jié)束后,可以通過在包含#include 的語句之前插入 #define NDEBUG 來禁用assert調(diào)用,示例代碼如下:

            顯示代碼打印1   #include  

            2   #define NDEBUG  

            3   #include


              
              用法總結(jié)與注意事項(xiàng):
              1)在函數(shù)開始處檢驗(yàn)傳入?yún)?shù)的合法性
              如:
              

            顯示代碼打印01   int resetBufferSize(int nNewSize)  

            02   {  

            03   //功能:改變緩沖區(qū)大小,  

            04   //參數(shù):nNewSize 緩沖區(qū)新長(zhǎng)度  

            05   //返回值:緩沖區(qū)當(dāng)前長(zhǎng)度  

            06   //說明:保持原信息內(nèi)容不變 nNewSize<=0表示清除緩沖區(qū)  

            07   assert(nNewSize >= 0);  

            08   assert(nNewSize <= MAX_BUFFER_SIZE);  

            09     

            10   ...  

            11   }


              
              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個(gè)生效,如果這么做,會(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)空一行,以形成邏輯和視覺上的一致感
              
              5)有的地方,assert不能代替條件過濾
              
              #C++
              
              程序一般分為Debug 版本和Release 版本,Debug 版本用于內(nèi)部調(diào)試,Release 版本發(fā)行給用戶使用。斷言assert 是僅在Debug 版本起作用的宏,它用于檢查“不應(yīng)該”發(fā)生的情況。以下是一個(gè)內(nèi)存復(fù)制程序,在運(yùn)行過程中,如果assert 的參數(shù)為假,那么程序就會(huì)中止(一般地還會(huì)出現(xiàn)提示對(duì)話,說明在什么地方引發(fā)了assert)。

            顯示代碼打印01   //復(fù)制不重疊的內(nèi)存塊  

            02   void memcpy(void *pvTo, void *pvFrom, size_t size)  

            03   {  

            04   void *pbTo = (byte *) pvTo;  

            05   void *pbFrom = (byte *) pvFrom;  

            06   assert( pvTo != NULL && pvFrom != NULL );  

            07   while(size - - > 0 )  

            08   *pbTo + + = *pbFrom + + ;  

            09   return (pvTo);  

            10   }


              
              assert 不是一個(gè)倉促拼湊起來的宏,為了不在程序的Debug 版本和Release 版本引起差別,assert 不應(yīng)該產(chǎn)生任何副作用。所以assert 不是函數(shù),而是宏。程序員可以把a(bǔ)ssert 看成一個(gè)在任何系統(tǒng)狀態(tài)下都可以安全使用的無害測(cè)試手段。
              
              很少有比跟蹤到程序的斷言,卻不知道該斷言的作用更讓人沮喪的事了。你化了很多時(shí)間,不是為了排除錯(cuò)誤,而只是為了弄清楚這個(gè)錯(cuò)誤到底是什么。有的時(shí)候,程序員偶爾還會(huì)設(shè)計(jì)出有錯(cuò)誤的斷言。所以如果搞不清楚斷言檢查的是什么,就很難判斷錯(cuò)誤是出現(xiàn)在程序中,還是出現(xiàn)在斷言中。幸運(yùn)的是這個(gè)問題很好解決,只要加上清晰的注釋即可。這本是顯而易見的事情,可是很少有程序員這樣做。這好比一個(gè)人在森林里,看到樹上釘著一塊“危險(xiǎn)”的大牌子。但危險(xiǎn)到底是什么?樹要倒?有廢井?有野獸?除非告訴人們“危險(xiǎn)”是什么,否則這個(gè)警告牌難以起到積極有效的作用。難以理解的斷言常常被程序員忽略,甚至被刪除。 [Maguire 1993]
              
              以下是使用斷言的幾個(gè)原則:
              
              (1)使用斷言捕捉不應(yīng)該發(fā)生的非法情況。不要混淆非法情況與錯(cuò)誤情況之間的區(qū)別,后者是必然存在的并且是一定要作出處理的。
              
              (2)使用斷言對(duì)函數(shù)的參數(shù)進(jìn)行確認(rèn)。
              
              (3)在編寫函數(shù)時(shí),要進(jìn)行反復(fù)的考查,并且自問:“我打算做哪些假定?”一旦確定了的
              假定,就要使用斷言對(duì)假定進(jìn)行檢查。
              
              (4)一般教科書都鼓勵(lì)程序員們進(jìn)行防錯(cuò)性的程序設(shè)計(jì),但要記住這種編程風(fēng)格會(huì)隱瞞錯(cuò)誤。當(dāng)進(jìn)行防錯(cuò)性編程時(shí),如果“不可能發(fā)生”的事情的確發(fā)生了,則要使用斷言進(jìn)行報(bào)警。
             
            ASSERT ()是一個(gè)調(diào)試程序時(shí)經(jīng)常使用的宏,在程序運(yùn)行時(shí)它計(jì)算括號(hào)內(nèi)的表達(dá)式,如果表達(dá)式為FALSE (0), 程序?qū)?bào)告錯(cuò)誤,并終止執(zhí)行。如果表達(dá)式不為0,則繼續(xù)執(zhí)行后面的語句。這個(gè)宏通常原來判斷程序中是否出現(xiàn)了明顯非法的數(shù)據(jù),如果出現(xiàn)了終止程序以免導(dǎo)致嚴(yán)重后果,同時(shí)也便于查找錯(cuò)誤。 

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

            ASSERT宏定義如下 


            顯示代碼打印1 #define ASSERT(f)  

            2 do 

            3 {  

            4        if (!(f) && AfxAssertFailedLine(THIS_FILE, __LINE__))  

            5                AfxDebugBreak();  

            6 } while (0)


            ASSERT(邏輯表達(dá)式)

            如果括號(hào)中的邏輯表達(dá)式值為假的話,會(huì)彈出調(diào)試命令窗口,提示具體在哪個(gè)文件的哪一行發(fā)生了斷言錯(cuò)誤! 
            ---------------------------------------------------------------

            ASSERT
            Evaluates an expression, and displays a diagnostic message if the expression is FALSE. Ignored in retail builds.

            Syntax

            ASSERT(
                   cond
            );

            Parameters

            cond

            Expression to evaluate.

            Remarks

            In debug builds, if the expression is FALSE, this macro displays a message box with the text of the expression, the name of the source file, and the line number. The user can ignore the assertion, enter the debugger, or quit the application.

            Example

            ASSERT(rtStartTime <= rtEndTime);


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

            斷言(ASSERT)的使用,方法很簡(jiǎn)單。為什么要用,初學(xué)者可能比較迷惑。 
            契約式編程講的比較清楚,建議可以先看看這類書。 
            一個(gè)函數(shù)由前置條件、后置條件和不變式組成。在VC中,我們可以通過斷言來保證這三個(gè)條件。可以大大提高了軟件的質(zhì)量。 
            ---------------------------------------------------------------

            如果ASSERT()中的條件不成立(比如 ASSERT(0) ;     ),會(huì)彈出一個(gè)比較嚇人的對(duì)話框。 

            點(diǎn)擊重試,可以到達(dá) ASSERT 斷言不成立的那一行, 

            此時(shí)可以在watch窗口查看變量值,找出出錯(cuò)的原因。 

            如果程序能夠繼續(xù)運(yùn)行,可以按F5繼續(xù)調(diào)試。

            久久天天躁狠狠躁夜夜avapp| 久久亚洲中文字幕精品一区四| 久久亚洲高清观看| 国产精品久久久久久吹潮| 一本久久知道综合久久| 久久天天躁夜夜躁狠狠| 久久国产AVJUST麻豆| 18禁黄久久久AAA片| 国内精品伊人久久久久妇| 久久只有这里有精品4| 大香伊人久久精品一区二区| 欧美国产成人久久精品| 伊人久久大香线焦AV综合影院 | 青青草原综合久久大伊人| 婷婷久久综合九色综合绿巨人| 久久99久久无码毛片一区二区| 青青久久精品国产免费看| 精品久久久久久中文字幕大豆网| 亚洲熟妇无码另类久久久| 99久久精品国产免看国产一区| 久久久久久久99精品免费观看| 国产精品热久久毛片| 亚洲日本va午夜中文字幕久久| 狠狠色综合网站久久久久久久高清| 亚洲精品乱码久久久久久| 久久国产乱子伦精品免费强| 久久久久亚洲av成人无码电影| 精品国产日韩久久亚洲| 亚洲精品成人久久久| 香蕉久久AⅤ一区二区三区| 亚洲狠狠婷婷综合久久蜜芽 | 99久久精品费精品国产一区二区| 办公室久久精品| 蜜臀久久99精品久久久久久小说| 国产免费久久精品99久久| 天堂久久天堂AV色综合| 久久精品无码一区二区日韩AV| 亚洲精品乱码久久久久久蜜桃不卡| 国产精品成人精品久久久 | 欧美丰满熟妇BBB久久久| 国内精品欧美久久精品|