(1)設置固定斷點或臨時斷點
所謂斷點,是指定程序中的某一行,讓程序運行至該行後暫停運行,使得程序員可以觀察分析程序的運行過程中的情況。這些情況一般包括:
①在變量窗口(Varibles)中觀察程序中變量的當前值。程序員觀察這些值的目的是與預期值對比,若與預期值不一致,則此斷點前運行的程序肯定在某個地方有問題,以此可縮小故障范圍。例如以下程序是計算cos(x)並顯示,運行時發現無論x輸入為多少,結果都是0.046414。
復制代碼 代碼如下:void main()
{
int x;
printf("Please input x:");
scanf("% d", &x);
printf("cos(x)=%fn", cos(x));
}
在該程序中,若你沒有看到問題——程序較長、較復雜時很難看出問題所在,則應該使用調試手段定位故障位置。
②在監控窗口(Watch)中觀察指定變量或表達式的值。當變量較多時,使用Varibles窗口可能不太方便,使用Watch窗口則可以有目的、有計劃地觀察關鍵變量的變化。
③在輸出窗口中觀察程序當前的輸出與預期是否一致。同樣地,若不一致,則此斷點前運行的程序肯定在某個地方有問題。
④在內存窗口(Memory)中觀察內存中數據的變化。在該窗口中能直接查詢和修改任意地址的數據。對初學者來說,通過它能更深刻地理解各種變量、數組和結構等是如何占用內存的,以及數組越界的過程。
⑤在調用堆棧窗口(Call Stack)中觀察函數調用的嵌套情況。此窗口在函數調用關系比較復雜或遞歸調用的情況下,對分析故障很有幫助。
(2)單步執行程序
讓 程序被一步一步(行)地執行,觀察分析執行過程是否符合預要求。例如,以下程序預期的功能是從鍵盤上讀入兩個數(x和y),判斷x和y是否相等,相等則在 屏幕上顯示x=y,不相等則顯示x<>y。這是要求實現的功能,但程序實際的運行狀況卻是:無論輸入什麼,都會在屏幕上顯示x=y和x& lt;>y,程序肯定有問題,但表面上看卻可能找不到問題所在,使用單步執行,則能定位故障點,縮小看的范圍。例如,在單步執行的過程中,若輸入 “2,3”,發現x和y的值的確變成了2和3,此時按道理不應執行“printf("x=yn");”,但單步跟蹤卻發現被執行了,因此多半問題出在 “if (x = y)”。
printf("Please input x, y:");
scanf("%d,%d", &x, &y);
if (x = y)
{
printf("x=yn");
}
else;
{
printf("x<>yn");
}
}
在單步執行的過程中,應靈活應用Step Over、Step Into、Step Out、Run to Cursor等方法,提高調試效率。建議在程序調試過程中,記住並使用“Step Over、Step Into、Step Out、Run to Cursor”等菜單項的快捷鍵,開始時可能較生疏、操作較慢,但堅持一段時間就能生巧、效率提高。
(3)使用斷言
斷 言是對某種假設條件進行檢查(可理解為若條件成立則無動作,否則應報告),它可以快速發現並定位軟件問題,同時對系統錯誤進行自動報警。斷言可以對在系統 中隱藏很深,用其它手段極難發現的問題進行定位,從而縮短軟件問題定位時間,提高系統的可測性。實際應用時,可根據具體情況靈活地設計斷言。
使用斷言時,必須在程序的開頭加上:
#include <assert.h>
①可用斷言來確認函數的參數。示例:假設某函數參數中有一個指針,那麼使用指針前可對它檢查,以防止其他人調用本函數時使用空指針作參數。代碼如下:
②可用斷言來確認是否發生了不該發生的情況。示例:以下程序段運行結果有錯,檢查起來很困難而且搞了很久都不知是什麼地方有問題。因此,建議分析程 序的正常運行情況應該是什麼,運行過程中是否出了異常,針對所有(或關鍵狀態)應當正常的情況,使用斷言,就很有可能發現異常原因,且調試效率很高。針對 該程序段,我們斷言(斷定)變量i的取值應該為“i>=0 && i<SIZE”且較關鍵,但在運行過程中是否有可能被無意修改(例如其它變量越界)而超出范圍呢,就可使用斷言檢查是否發生了這樣的情況。
復制代碼 代碼如下:斷言不成立時(一出現異常),系統將立即報錯,此時可進入程序調試狀態,檢查程序的運行情況。
(4)與調試相關的操作菜單:Build菜單
Compile:快捷鍵Ctrl+F7。編譯當前處於源代碼窗口中的源程序文件,以便檢查是否有語法錯誤或警告,如果有的話,將顯示在Output輸出窗口中。
Build:快捷鍵F7。對當前工程中的有關文件進行連接,若出現錯誤的話,也將顯示在Output輸出窗口中。
Execute:快捷鍵Ctrl+F5。運行(執行)已經編譯、連接成功的可執行程序(文件)。
Start Debug:選擇該項將彈出子菜單,其中含有用於啟動調試器運行的幾個選項。例如其中的Go選項用於從當前語句開始執行程序,直到遇到斷點或遇到程序結 束;Step Into選項開始單步執行程序,並在遇到函數調用時進入函數內部再從頭單步執行;Run to Cursor選項使程序運行到當前鼠標光標所在行時暫停其執行(注意,使用該選項前,要先將鼠標光標設置到某一個你希望暫停的程序行處)。執行該菜單的選 擇項後,就啟動了調試器,此時菜單欄中將出現Debug菜單(而取代了Build菜單)。
(5)與調試相關的操作菜單:Debug菜單
啟動調試器後才出現該Debug菜單(而不再出現Build菜單)。
Go:快捷鍵F5。從當前語句啟動繼續運行程序,直到遇到斷點或遇到程序結束而停止(與Build→Start Debug→Go選項的功能相同)。
Restart:快捷鍵Ctrl+Shift+F5。重新從頭開始對程序進行調試執行(當對程序做過某些修改後往往需要這樣做!)。選擇該項後,系統將重新裝載程序到內存,並放棄所有變量的當前值(而重新開始)。
Stop Debugging:快捷鍵Shift+F5。中斷當前的調試過程並返回正常的編輯狀態(注意,系統將自動關閉調試器,並重新使用Build菜單來取代Debug菜單)。
Step Into:快捷鍵F11。單步執行程序,並在遇到函數調用語句時,進入那一函數內部,並從頭單步執行(與Build→Start Debug→Step Into選項的功能相同)。
Step Over:快捷鍵F10。單步執行程序,但當執行到函數調用語句時,不進入那一函數內部,而是一步直接執行完該函數後,接著再執行函數調用語句後面的語句。
Step Out:快捷鍵Shift+F11。與“Step Into”配合使用,當執行進入到函數內部,單步執行若干步之後,若發現不再需要進行單步調試的話,通過該選項可以從函數內部返回(到函數調用語句的下一語句處停止)。
Run to Cursor:快捷鍵Ctrl+F10。使程序運行到當前鼠標光標所在行時暫停其執行(注意,使用該選項前,要先將鼠標光標設置到某一個你希望暫停的程序 行處)。事實上,相當於設置了一個臨時斷點,與Build→Start Debug→Run to Cursor選項的功能相同。
Insert/Remove Breakpoint:快捷鍵F9。本菜單項並未出現在Debug菜單上(在工具欄和程序文檔的上下文關聯菜單上),列在此處是為了方便大家掌握程序調試 的手段,其功能是設置或取消固定斷點——程序行前有一個圓形的黑點標志,表示已經該行設置了固定斷點。另外,與固定斷點相關的還有Alt+F9(管理程序 中的所有斷點)、Ctrl+F9(禁用/使能當前斷點)。