程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 使用VC6.0對C語言程序進行調試的基本手段分享

使用VC6.0對C語言程序進行調試的基本手段分享

編輯:C語言基礎知識

(1)設置固定斷點或臨時斷點

所謂斷點,是指定程序中的某一行,讓程序運行至該行後暫停運行,使得程序員可以觀察分析程序的運行過程中的情況。這些情況一般包括:

①在變量窗口(Varibles)中觀察程序中變量的當前值。程序員觀察這些值的目的是與預期值對比,若與預期值不一致,則此斷點前運行的程序肯定在某個地方有問題,以此可縮小故障范圍。例如以下程序是計算cos(x)並顯示,運行時發現無論x輸入為多少,結果都是0.046414。

代碼如下:

#include <stdio.h>
#include <math.h>

void main()
{
int  x;

printf("Please input x:");
scanf("% d", &x);
printf("cos(x)=%f\n", cos(x));
}

在該程序中,若你沒有看到問題——程序較長、較復雜時很難看出問題所在,則應該使用調試手段定位故障位置。

②在監控窗口(Watch)中觀察指定變量或表達式的值。當變量較多時,使用Varibles窗口可能不太方便,使用Watch窗口則可以有目的、有計劃地觀察關鍵變量的變化。

③在輸出窗口中觀察程序當前的輸出與預期是否一致。同樣地,若不一致,則此斷點前運行的程序肯定在某個地方有問題。

④在內存窗口(Memory)中觀察內存中數據的變化。在該窗口中能直接查詢和修改任意地址的數據。對初學者來說,通過它能更深刻地理解各種變量、數組和結構等是如何占用內存的,以及數組越界的過程。

⑤在調用堆棧窗口(Call Stack)中觀察函數調用的嵌套情況。此窗口在函數調用關系比較復雜或遞歸調用的情況下,對分析故障很有幫助。

(2)單步執行程序

讓程序被一步一步(行)地執行,觀察分析執行過程是否符合預要求。例如,以下程序預期的功能是從鍵盤上讀入兩個數(x和y),判斷x和y是否相等,相等則在屏幕上顯示x=y,不相等則顯示x<>y。這是要求實現的功能,但程序實際的運行狀況卻是:無論輸入什麼,都會在屏幕上顯示x=y和x<>y,程序肯定有問題,但表面上看卻可能找不到問題所在,使用單步執行,則能定位故障點,縮小看的范圍。例如,在單步執行的過程中,若輸入“2,3”,發現x和y的值的確變成了2和3,此時按道理不應執行“printf("x=y\n");”,但單步跟蹤卻發現被執行了,因此多半問題出在“if (x = y)”。

代碼如下:

#include <stdio.h>
void main()
{
int  x, y;

printf("Please input x, y:");
scanf("%d,%d", &x, &y);
if (x = y)
{
  printf("x=y\n");
}
else;
{
  printf("x<>y\n");
}
}

在單步執行的過程中,應靈活應用Step Over、Step Into、Step Out、Run to Cursor等方法,提高調試效率。建議在程序調試過程中,記住並使用“Step Over、Step Into、Step Out、Run to Cursor”等菜單項的快捷鍵,開始時可能較生疏、操作較慢,但堅持一段時間就能生巧、效率提高。

(3)使用斷言

斷言是對某種假設條件進行檢查(可理解為若條件成立則無動作,否則應報告),它可以快速發現並定位軟件問題,同時對系統錯誤進行自動報警。斷言可以對在系統中隱藏很深,用其它手段極難發現的問題進行定位,從而縮短軟件問題定位時間,提高系統的可測性。實際應用時,可根據具體情況靈活地設計斷言。
使用斷言時,必須在程序的開頭加上:

#include <assert.h>

①可用斷言來確認函數的參數。示例:假設某函數參數中有一個指針,那麼使用指針前可對它檢查,以防止其他人調用本函數時使用空指針作參數。代碼如下:

代碼如下:

int exam_fun( unsigned char *str )
{
    assert(str != NULL);  // 斷言“指針不為空”,若“空”(斷言不成立)則報錯
    ... //other program code
}

②可用斷言來確認是否發生了不該發生的情況。示例:以下程序段運行結果有錯,檢查起來很困難而且搞了很久都不知是什麼地方有問題。因此,建議分析程序的正常運行情況應該是什麼,運行過程中是否出了異常,針對所有(或關鍵狀態)應當正常的情況,使用斷言,就很有可能發現異常原因,且調試效率很高。針對該程序段,我們斷言(斷定)變量i的取值應該為“i>=0 && i<SIZE”且較關鍵,但在運行過程中是否有可能被無意修改(例如其它變量越界)而超出范圍呢,就可使用斷言檢查是否發生了這樣的情況。

代碼如下:

for (i=0; i<SIZE; i++)
{
    ... //other program code
assert(i>=0 && i<SIZE);  // 斷言“i的正常取值范圍”,若斷言不成立則報錯
array[i] = i;
    ... //other program code
}

斷言不成立時(一出現異常),系統將立即報錯,此時可進入程序調試狀態,檢查程序的運行情況。

(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(禁用/使能當前斷點)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved