• <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>

            斷言的使用

            Posted on 2010-01-17 19:36 rikisand 閱讀(604) 評論(0)  編輯 收藏 引用 所屬分類: 工作記錄~~everydayC/C++Windows ~

            解決項目的問題,意識到斷言的重要性。如果一個程序在某處遇到了非法的值,那么最好的情況便是在此刻停下報錯,最壞的情況便是程序不吭不響的執行著~~直到你發現他執行的方式極為詭異,此時,你要花九牛二虎之力才能找到錯誤所在之處~~~~

            學習一下斷言吧:

            ·······什么是斷言

            在某處判斷某一個表達式的值為真或者假,如果假則輸出錯誤消息并停止程序的執行~

            assert是宏,而不是函數,只在debug版本中有效,因此無需在release版本刪除。

            ·······哪幾種斷言

            MFC

            ASSERT

            void foo(char* p,int size)
            {
            ASSERT(p != 0); // 驗證緩沖區指針
            ASSERT((size >= 100); // 確認緩沖區大小至少為100字節
            // foo 函數的其它計算過程
            }
            如果沒有定義_DEBUG預處理符,則該語句不會真正生成代碼。Visual C++會在調試模式編譯時自動定義_DEBUG,而在發行模式下,該預處理符是不存在的。如果定義了_DEBUG,則上述兩個斷言生成的代碼類如:
            //ASSERT(p != 0);
            do
            {
            if(!(p != 0) && AfxAssertFailedLine(__FILE__, __LINE__))
            AfxDebugBreak();
            } while(0);
            //ASSERT((size >= 100);
            do
            {
            if(!(size >= 100) && AfxAssertFailedLine(__FILE__,__LINE__))
            AfxDebugBreak();
            }while(0);

            ASSERT_KINDOF(classname,pObject); ASSERT_KINDOF(CDocument,pDocument);

            檢驗pObject指向的對象是classname類的一個對象或者其派生類的對象

            ASSERT_VALID(pObject); pObject 必須是一個派生于CObject類的類對象,會調用其重寫的AssertValid函數 ,例如

            如果使用應用向導或類向導生成基于MFC的類,通常會得到AssertValid()的骨架,最好改寫這些骨架代碼以增加最基本的完整性檢查。下面是一個典型的例子,類Sample從CObject繼承,假定它含有職員名字及其薪水:
            class Sample : public CObject
            {
                protected:
                CString m_Name; // 職員名字
                double m_Salary; // 薪水
            public:
                Sample(LPCTSTR name,double salary) : m_Name(name), m_Salary(salary) {}
               #ifdef _DEBUG
                    virtual void AssertValid() const;
                #endif

            };
            #ifdef _DEBUG
            void Sample::AssertValid() const
            {
                CObject::AssertValid(); // 驗證基類
                ASSERT(!m_Name.IsEmpty()); // 驗證職員名字
                ASSERT(m_Salary > 0); // 驗證薪水
            }
            #endif

            CRT assertion

            _ASSERT 和  _ASSERTE 后一個會在出錯時同時打印出條件判斷句

            ANSI

            assert()

            注意:assert用于檢測非法的輸入,但是合法的輸入并不一定是正確的,例如:

            int pB = (int*)malloc(sizeof(int)*1000);

            assert(pB!=NULL) //錯誤的使用assert 他會在release版本失效~也就是說assert不應該對程序產生副作用

            正確的做法:

            int pB = (int*) malloc(sizeof(int)*1000);

            if(pB == NULL)

            {
               //錯誤處理

            }

            else{

            }

            另一個例子:

            void draw(){

               CFigure* pF = getCF();

               assert(pf!=NULL);

               if(pf == NULL){}

               else{

               }

            }

            此處,對于getCF來說返回值為NULL是非法的,如果他的返回值可能為null就沒必要加上assert語句。

            而下面的if語句則是為了防止release版本出現null指針的情況。

             

             

            VERIFY()

            由于ASSERT僅在程序的調試版起作用,測試表達式總是被動的。也就是說,它們不能包含賦值、增量、減量等真正改變數據的操作。但有時候我們需要驗證一個主動表達式,比如賦值語句。這時可以使用VERIFY代替ASSERT。下面是一個例子:
            void foo(char* p,int size)
            {
            char* q; // 指針的副本
            VERIFY(q = p); // 拷貝指針并執行驗證
            ASSERT((size >= 100); // 確保緩沖區大小至少為100字節
            // 執行 foo 的其它操作
            }
            在調試模式下ASSERT和VERIFY是相同的。但在release模式下,VERIFY能夠繼續對表達式求值(但不再進行斷言檢驗),而ASSERT語句在效果上就如同已經刪除了一樣。
            盡管在MFC源代碼中可以找到一些應用VERIFY的例子,但ASSERT用得更為普遍。一些程序員總是完全避免使用VERIFY,因為他們已經習慣于使用被動斷言。請記住,如果在ASSERT語句中使用了主動表達式,編譯器不會發出任何警告。在發行模式下編譯時該表達式會被直接刪除,從而導致程序運行的錯誤。由于發行版程序不含調試信息,這種類型的錯誤是很難找到原因的。

             

             

             

             

             

             

             

             

             

             

             

             

            久久国产免费观看精品3| 久久99国产精一区二区三区| 久久人人爽人人澡人人高潮AV| 国产精品内射久久久久欢欢| 天堂无码久久综合东京热| 狠狠色丁香婷婷久久综合五月| 色8久久人人97超碰香蕉987| 精品久久久久久国产| 久久婷婷人人澡人人| 久久精品无码一区二区无码| 国产AV影片久久久久久| 伊人久久综合精品无码AV专区| 久久精品国产亚洲av影院| 污污内射久久一区二区欧美日韩| av无码久久久久不卡免费网站| 伊人精品久久久久7777| 久久久精品一区二区三区| 中文字幕久久精品 | 久久久无码精品亚洲日韩京东传媒| 无码人妻精品一区二区三区久久久| 伊人久久免费视频| 亚洲AV无码成人网站久久精品大| 国产精品99久久不卡| 99久久精品国产高清一区二区| 伊人久久一区二区三区无码| 99精品伊人久久久大香线蕉| 亚洲AV日韩精品久久久久久 | 国产成人综合久久综合| 三级三级久久三级久久 | 精品久久久久成人码免费动漫 | 日日噜噜夜夜狠狠久久丁香五月| 久久人人爽人人爽人人片AV麻豆 | 国产精品视频久久| 久久亚洲精精品中文字幕| 久久亚洲精品无码aⅴ大香 | 精品久久久久久国产| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 狠狠人妻久久久久久综合蜜桃 | 久久婷婷五月综合97色直播| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 精品久久久久久久久免费影院|