除錯你的程式
我覺得這是一個需要詳細討論的話題。除錯是程式設計中一個非常重要的部分。如果你遇到錯誤,你需要知道如何找到問題並解決它。如果你只是缺少一個分號,你不應該為此發帖求助。
請記住,這並不是具體的除錯方法。它不是一套規則,而是一組建議。我的建議可能不一定是正確的做法。如果在本文中發現任何不正確的內容,請告知我,以便我進行更正。我不喜歡傳播錯誤的知識。
無論如何,我們將從基礎開始,從識別和理解編譯器錯誤,到使用 IDE 的偵錯程式單步執行程式。
請注意:我參考了 Stephen Randy Davis 編寫的《C++ for Dummies》第 5 版,第 139-155 頁。
識別錯誤
通常,你的程式不會按計劃工作,並且無法正確編譯。即使是最好的程式設計師也會犯錯誤,能夠識別你做錯了什麼是至關重要的。存在兩種型別的錯誤:C++ 編譯器可以自行捕獲的錯誤,以及編譯器無法捕獲的錯誤。C++ 可以捕獲的錯誤稱為編譯時錯誤。編譯時錯誤應該相對容易修復,因為編譯器會指出問題所在。編譯器輸出的所有垃圾資訊都有其用途。這是一個例子。我忘記在 return 語句後新增分號。
1 2 3 4
|
int main()
{
return 0
}
|
你的編譯器應該會生成類似這樣的錯誤…
\main.cpp(4) : error C2143: syntax error : missing ';' before '}'
編譯器錯誤因編譯器而異,但總體上都差不多。在我的例子中,我使用的是 Visual Studio 2008,但如果你使用的是 Dev-C++ 或 G++,情況也是一樣的。
現在讓我們分解一下這個編譯器錯誤。它的第一部分
\main.cpp(4)
表示錯誤在 main.cpp 檔案中,第 4 行。之後是
error C2143:
,這是編譯器特定的錯誤程式碼。如果你使用的是 Visual Studio,如果需要,你可以很容易地在 MSDN 上查詢錯誤程式碼。之後,錯誤宣告
syntax error :
,這告訴你你弄亂了一些語法。所以你一定沒有正確輸入某些內容。然後它告訴我
missing ‘;’ before ‘}’
在右括號前缺少一個分號。好的,我知道我缺少一個分號,我知道錯誤在第 4 行,我知道它在右括號之前。所以我轉到 main.cpp,第 4 行,在右括號之前我需要一個分號。由於第 4 行上唯一的東西是一個右括號,我只需向上移動到第 3 行,OH!我注意到我忘記在
return 0
之後新增分號。識別編譯器錯誤應該如此簡單。
C++ 無法捕獲的另一種型別的錯誤稱為執行時錯誤。執行時錯誤通常更難捕獲。
除錯技巧
除錯程式有幾種方法。我最常使用的兩種是 WRITE 技術和單步除錯。首先,我將介紹 WRITE 技術。它涉及為你所有的變數建立輸出語句,以便你可以檢視所有變數的值。我將使用《C++ for Dummies》第 5 版中的這個程式示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
// ErrorProgram – This program averages a series
// of numbers, except that it contains
// a fatal bug.
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int nNumberofArgs, char *pszArgs[])
{
cout << "This program is designed to crash!"
<< endl;
int nSum;
int nNums;
// accumulate input numbers until the
// user enteres a negative number, then
// return the average
nNums = 0;
while(true)
{
// enter another number to add
int nValue;
cout << "Enter another number:";
cin >> nValue;
cout << endl;
// if the input number is negative...
if(nValue < 0)
{
// ... then output the average
cout << "Average is: "
<< nSum/nNums
<< endl;
break;
}
// not negative, add the value to
// the accumulator
nSum += nValue;
}
cin.ignore(10000, '\n');
return 0;
}
|
執行此程式碼時,你會得到一個執行時錯誤。解決問題的簡單方法是使用 WRITE 技術。每次你進入 while 迴圈時,讓它輸出 nNums 的值。
1 2 3 4 5 6 7
|
While(true)
{
// output
cout << “nNums = “ << nNums << endl;
// The rest of the program is unchanged
}
|
輸出將如下所示
This program is designed to crash!
nNums = 0
Enter another number:1
nNums = 0
Enter another number:2
nNums = 0
Enter another number:3
nNums = 0
Enter another number: |
你可以看到 nNums 被初始化為 0,但是它在哪裡遞增?沒有,這就是 bug。顯然 nNums 應該在輸入部分的每次迴圈中遞增。透過使用 WRITE 技術,我們告訴程式輸出每次迴圈中 nNums 的值,從而發現它沒有被正確遞增。
對於較小的程式,WRITE 技術效果很好,但是隨著程式變得更大,輸出所有變數變得更加困難,並且看起來只是浪費時間。相反,我們將依靠偵錯程式。首先,讓我們定義一個偵錯程式。偵錯程式是構建到大多數開發環境中的工具(儘管它們有所不同,但大多數偵錯程式的工作原理相同)。程式設計師透過與編輯器相同的介面,透過命令來控制偵錯程式。你可以在選單項中或使用熱鍵訪問這些命令。偵錯程式允許程式設計師控制他/她的程式的執行。他/她可以在程式中一次執行一個步驟,他/她可以在任何時候停止程式,並且他/她可以檢查變數的值。要體會偵錯程式的強大功能,你需要親眼目睹它的實際應用。用語言很難解釋(而且我不擅長用語言表達)。因此,有關除錯的更多資訊,我將連結到一個非常方便的網頁。
http://www.cprogramming.com/tutorial/debugging_concepts.html
如果有任何需要新增的內容,請告訴我。