国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C語言編程常見問題解答之調試

2019-11-17 05:41:40
字體:
來源:轉載
供稿:網友
    調試(debugging)是指去掉程序中的錯誤(通常被稱為bugs)的過程。一個錯誤可能非常簡單,例如拼錯一個單詞或者漏掉一個分號;也可能比較復雜,例如使用一個指向并不存在的地址的指針。無論錯誤的復雜程度如何,把握正確的調試方法都能使程序員受益匪淺。

    11.1 假如我運行的程序掛起了,應該怎么辦?
    當你運行一個程序時會有多種原因使它掛起,這些原因可以分為以下4種基本類型:
    (1)程序中有死循環;
    (2)程序運行的時間比所期望的長;
    (3)程序在等待某些輸入信息,并且直到輸入正確后才會繼續運行;
    (4)程序設計的目的就是為了延遲一段時間,或者暫停執行。
    在討論了因未知原因而掛起的程序的調試技巧后,將逐個分析上述的每種情況。
    調試那些因未知原因而掛起的程序是非常困難的。你可能花費了很長的時間編寫一個程序,并努力確保每條代碼都準確無誤,你也可能只是在一個原來運行良好的程序上作了一個很小的修改,然而,當你運行程序時屏幕上卻什么也沒有顯示。假如你能得到一個錯誤的結果,或者部分結果,你也許知道應該作些什么修改,而一個空白的屏幕實在令人沮喪,你根本不知道錯在哪里。
    在開始調試這樣一個程序時,你應該先檢查一下程序結構,然后再按執行順序依次查看程序的各個部分,看看它們是否能正確運行。
    例如,假如主程序只包含3個函數調用——A()、B()和C(),那么在調試時,你可以先檢查函數A()是否把控制權返回給了主程序。為此,你可以在調用函數A()的語句后面加上exit()命令,也可以用注釋符把對函數B()和C()的調用括起來,然后重新編譯并運行這個程序。

    注重:通過調試程序(debugger)也可以做到這一點,然而上述方法是一種很傳統的調試方法。調試程序是一個程序,它的作用是讓程序員能夠觀察程序的運行情況、程序的當前運行行號、變量的值,等等。

    此時你將看到函數A()是否將控制權返回給了主程序——假如該程序運行并退出,你可以判定是程序的其它部分使程序掛起。你可以用這種方法測試程序的每一部分,直到發現使程序掛起的那一部分,然后集中精力修改相應的函數。
    有時,情況會更復雜一些。例如,使程序掛起的函數本身是完全正常的,問題可能出在該函數從別的地方得到了一些錯誤的數據。這時,你就要檢查該函數所接受的所有的值,并找出是哪些值導致了錯誤操作。

    技巧:監視函數是調試程序的出色功能之一。
   
    分析下面這個簡單的例子將幫助你把握這種技巧的使用方法:
#include <stdio. h>
#include <stdlib. h>
/*
   * Declare the functions that the main function is using
   */
int A(), B(int), C(int, int);
/*
   * The main PRogram
   */
int A(), B(), C(); /*These are functions in some other
                      module * /
int main()
{
    int v1,  v2, v3;
    v1  = A();
    v2  = B(v1);
    v3  = C(v1, v2);
    printf ("The Result is %d. /n" , v3);
    return(0) ;
}

    你可以在調用函數A()的語句后輸出變量v1的值,以確認它是否在函數B()所能接受的值的范圍之內,因為即使是函數B()使程序掛起,它本身并不一定就有錯,而可能是因為函數A()給了函數B()一個并非它所期望的值。
  現在,已經分析了調試“掛起”的程序的基本方法,下面來看看一些使程序掛起的常見錯誤。

    死循環
    當你的程序出現了死循環時,機器將無數次地執行同一段代碼,這種操作當然是程序員所不希望的。出現死循環的原因是程序員使程序進行循環的判定條件永遠為真,或者使程序退出循環的判定條件永遠為假。下面是一個死循環的例子:
/* initialize a double dimension array */
for (a = 0 ;  a < 10; ++a )
{
    for(b =  0; b<10; ++a)
    {
         array[a][b]==0;
    }
}

    這里的問題是程序員犯了一個錯誤(事實上可能是鍵入字母的錯誤),第二個循環本應在變量b增加到10后結束,但是卻從未讓變量b的值增加!第二個for循環的第三部分增加變量a的值,而程序員的本意是要增加變量b的值。因為b的值將總是小于10,所以第二個for循環會一直運行下去。
    怎樣才能發現這個錯誤呢?除非你重新閱讀該程序并注重到變量b的值沒有增加,否則你不可能發現這個錯誤。當你試圖調試該程序時,你可以在第二個for循環的循環體中加入這樣一條語句:
    printf(" %d %d %d/n" ,  a  , b , array[a][b]) ;
這條語句的正確輸出應該是:
    0 0 0
    0 1 0
    (and eventually reaching)
    9 9 0
但你實際上看到的輸出卻是:
    0 0 0
    1 0 0
    2 0 0
    ...
你所得到是一個數字序列,它的第一項不斷增加,但它本身永遠不會結束。用這種方法輸出變量不僅可以找出錯誤,而且還能知道數組是否由所期望的值組成。這個錯誤用其它方法似乎很難發現!這種輸出變量內容的技巧以后還會用到。
    產生死循環的其它原因還有一些其它的原因也會導致死循環。請看下述程序段:
int main()
{
     int a = 7;
     while ( a  <  10)
    {
      + +a;
      a /= 2;
    }
    return (0);
}
    盡管每次循環中變量a的值都要增加,但與此同時它又被減小了一半。變量a的初始值為7,它先增加到8,然后減半到4。因此,變量a永遠也不會增加到10,循環也永遠不會結束。

   運行時間比期望的時間長

    在有些情況下,你會發現程序并沒有被完全“鎖死”,只不過它的運行時間比你所期望的時間長,這種情況是令人討厭的。假如你所使用的計算機運算速度很快,能在極短的時間內完成很復雜的運算,那么這種情況就更令人討厭了。下面舉幾個這樣的例子:

/*
   * A subroutine to calculate Fibonacci numbers
   */
int fib ( int i)
{
    if  (i <3)
         return 1;
    else
         return fib( i - 1)+fib( i - 2);
}

    一個菲波那契(Fibonacci)數是這樣生成的:任意一個菲波那契數都是在它之前的兩個菲波那契數之和;第一個和第二個菲波那契數是例外,它們都被定義為1。菲波那契數在數學中很有意思,而且在實際中也有許多應用。

    注重:在向日葵的種子中可以找到菲波那契數的例子——向日葵有兩組螺旋形排列的種子,一組含21顆種子,另一組含34顆種子,這兩個數恰好都是菲波那契數。

    從表面上看,上述程序段是定義菲波那契數的一種很簡單的方法。這段程序簡潔短小,看上去執行時間不會太長。但事實上,哪怕是用計算機計算出較小的菲波那契數,例如第100個,都會花去很長的時間,下文中將分析其中的原因。
    假如你要計算第40個菲波那契數的值,就要把第39個和第38個菲波那契數的值相加,因此需要先計算出這兩個數,而為此又要分別計算出另外兩組更小的菲波那契數的和。不難看出,第一步是2個子問題,第二步是4個子問題,第三步是8個子問題,如此繼續下去,結果是子問題的數目以步數為指數不斷增長。例如,在計算第40個菲波那契數的過程中,函數fib()將被調用2億多次!即便在一臺速度相當快的計算機上,這一過程也要持續好幾分鐘。
    數字的排序所花的時間有時也會超出你的預料:
  /*
   *  Routine to sort an array of integers.
   *  Takes two parameters:
   *     ar---The array of numbers to be sorted, and
   *     size---the size of the array.
   */
void sort( int ar[], int size )
{
      int i,j;
      for( i = 0; i<size - 1;  ++ i)
       {
           for( j = 0; j< size - 1; ++j )
           {
   


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 东明县| 福州市| 宝鸡市| 鹤峰县| 社旗县| 金平| 吴桥县| 石首市| 华安县| 临夏县| 奉贤区| 莲花县| 固阳县| 台东县| 姚安县| 冷水江市| 垫江县| 鱼台县| 闸北区| 株洲县| 古浪县| 阿拉善右旗| 喀喇| 郓城县| 同仁县| 海淀区| 海林市| 阜南县| 高碑店市| 哈尔滨市| 乐业县| 诏安县| 丰原市| 迁安市| 洱源县| 湟源县| 庄浪县| 江华| 彰化市| 彰化市| 岗巴县|