一步步使用Code::Blocks進行設置斷點調試程序

1、調試以前要作的工做

首先,咱們要確保Code::Blocks的配置正確,調試工做才能進行得更順利ios

爲此,咱們須要生成調試符號。調試符號可讓調試器知道代碼的哪一行正在執行,這樣你就能夠知道程序運行到哪裏了。函數

爲確保調試符號設置正確,請在Code::Blocks中選擇項目 | 編譯選項(Project | Build Options),會看到這樣一個對話框:ui

你須要確保調試(Debug)目標裏的生成調試符號(Produce debugging symbols)選項被勾選上。spa

還須要在編譯 | 選擇目標 | 調試(Build | Select Target |Debug)中,確保調試(Debug)做爲項目的目標被選中:debug

 

以上操做確保了目標是對項目進行調試,調試器將使用調試符號來編譯你的程序。3d

 

2、設置斷點

調試器的價值在於,它能讓咱們看到程序正在作的事情——哪些代碼正在執行,以及變量的值是多少。調試

爲此,咱們在程序的某個地方設置斷點,而後在調試器下運行該程序。調試器將執行程序,直到到達設置了斷點的代碼行。此時,編譯器即可以讓你查看程序,或者一步步地執行程序,檢查代碼的每一行是如何影響你的變量的。rest

首先咱們來看一段用來計算特定數額資金的利率(interest rate)、年利息(compounded annually)的程序:code

#include <iostream>
using namespace std;
double computeInterest (double base_val, double rate, int years)
{
    double final_multiplier;
    for ( int i = 0; i < years; i++ )
    {
        final_multiplier *= (1 + rate);
    }
    return base_val * final_multiplier;
}

int main ()
{
    double base_val;
    double rate;
    int years;
    cout << "Enter a base value: ";
    cin >> base_val;
    cout << "Enter an interest rate: ";
    cin >> rate;
    cout << "Enter the number of years to compound: ";
    cin >> years;

    cout << "After " << years << " you will have " << computeInterest( base_val, rate, years ) << " money" << endl;
}

 

 看了運行結果,很明顯,出現了錯誤,這時咱們將設置斷點開始進行調試。blog

1,先在main函數開始的地方,設置一個斷點。這樣就能夠查看整個程序的執行過程了。

(1)將光標移到 double base_val 這一行

(2)選擇 調試 | 設置斷點 (Debug | Toggle Breakpoint)或者按下F5。這會在該代碼行旁邊的側邊欄中設置一個小紅點,代表這一行有一個斷點:

 

(3)可使用設置斷點命令或者單擊小紅點用來設置或取消設置該斷點。

(4)開始運行程序。選擇調試 | 開始(Debug | Start)或者按下F8。

這樣程序將正常執行,直到遇到斷點。

 

如今咱們應該看到了打開的調試器,它看起來應該是這樣的:

 

首先要注意的是小圓點下面的三角形,它表示接下來要執行的代碼行。它跟小紅點之間相隔若干行。

它之因此沒有緊挨着小紅點,是由於變量的聲明不產生任何的機器代碼,所以,儘管斷點看起來是在15行,但實際上它在第18行。

 

(5)這時應該還有一個監視(Watches)窗口打開了,以下圖:

我已經展開了監視窗口的兩個子項:局部變量(Local variables)和函數參數(Function Arguments)。

監視窗口會顯示出全部當前可用的變量,包括局部變量和函數參數,以及這些變量的值。

注意:這裏看起來像亂碼的緣由是由於咱們尚未對它們進行初始化,這也是接下來的幾行程序所要作的事情。

 

(6)爲了執行接下來的幾行代碼,咱們須要告訴調試器向下執行下一行(F7)

所謂向下執行一行,就會執行當前的代碼行,也就是三角形所標識的那一行。

 

一旦走到下一行,程序就會執行cout語句,輸出一條信息到屏幕中,要求你輸入一個值。

若是你嘗試輸入一個值但沒有任何效果——由於程序還在調試器的控制之下。

再次按下F7後,程序會等待用戶輸入,由於這時候cin函數還未返回——cin函數須要在返回前獲得用戶的輸入。

重複這一過程,分別輸入0.1給利率,輸入1給年數。

如今,斷點到達了這一行代碼:

 

再次確認輸入是否正確。咱們能夠經過監視窗口來檢查局部變量的值:

 

注意:rate的值不是0.1,是由於0.10000...1中最末尾的1只是浮點數的一種怪異的表達方式(浮點數並非精確的),它實在過小了,對大多數程序來講不會形成很大影響。

 

(7)如今咱們肯定一切都沒問題,來調查一下computerInterest函數中會發生什麼,單步執行(Step into)

 

 單步執行會進入當前行的函數裏面去執行,而不像下一行命令,只是執行函數而後顯示給你最終的結果。

如今咱們就單步進入computerInterest函數之中:

 

(8)從結果中咱們能夠看出函數的參數部分一切正常,但變量i 和 final_multiplier 值不對勁。

爲此,使用下一行命令(F7),執行循環語句,因爲它與一些初始化操做相關聯,咱們看看會發生什麼。

(9)從中咱們能夠看出,final_multiplier沒有正確初始化。並且,接下來要執行的語句將要用到final_multiplier:

    final_multiplier *= (1 + rate);

這條語句的意思是,將final_multiplier乘以(1+rate),再把結果從新賦值給final_multiplier。可是咱們看到final_multiplier並無被初始化,所以這個乘法的結果也將會是一個莫名其妙的值。

 

(10)如何修復bug?

咱們須要在聲明final_multiplier變量的語句中,把它也初始化。在這個例子中,它應該被初始化1。

double final_multiplier=1;

 

(11)修復bug後的運行結果爲:

 

3、總結

經過以上一個簡單的程序案例,使我掌握了調試一個程序的基本流程,和分析bug的過程,爲之後本身獨立尋找bug,解決bug提供了實用的技能。

我不光能夠寫bug,還能Debug!

相關文章
相關標籤/搜索