天天看點

第11篇 ACM/ICPC競賽之調試

在寫程式時,調試程式也是一個重要的環節。怎樣才能夠更有效地調試程式,發現并修正錯誤呢?

1、調試中的輸入輸出

為了調試程式,我們可能需要反複執行程式,也就需要反複輸入相同或不相同的測試資料。如果每次調試運作時都是以手工的方式輸入測試資料,相信很多人都會覺得不勝其煩。其實我們可以用一些輔助的手段來簡化這個過程。

方法一:使用剪貼闆

可以将輸入資料預先寫好(用記事本、開發環境的編輯器或随便什麼能夠錄入的東西),再将輸入資料複制到剪貼闆上(也就是說我們通常所說的複制操作)。在調試運作時,就可以直接将輸入資料粘貼上去,不需要手工輸入,這對于反複調試同一組測試資料尤其友善。

方法二:使用重定向

使用剪貼闆對于多組測試資料或者比較長的測試資料就會顯得不那麼好用了。而使用輸入輸出的重定向則會更友善。

輸入輸出重定向是在終端視窗下的一種指令行功能,在指令行上可以用“<”表示輸入重定向,在“<”後跟随輸入檔案名,則程式将從指定的輸入檔案中擷取輸入資料,而不再從鍵盤讀入資料。也可以用“>”表示輸出重定向。在“>”後跟輸出檔案名,則程式産生的标準輸出将寫入指定的輸出檔案中,而不是顯示在螢幕上。

我們可以預先将輸入資料存到文本檔案中(如果有多組測試資料,可以存成多個檔案),用重定向指定準備使用的輸入資料。

例如,程式名為myprog,輸入資料已經存到檔案test.txt中,則在指令行下可以這樣執行:

C:>myprog < test.txt

則程式會直接從test.txt中讀取輸入。如果想把輸出結果也存到檔案中(這在輸出結果比較多的時候尤其有用,因為直接輸出到螢幕上可能會來不及看到輸出,或看不全所有的輸出),例如,可以這樣執行:

C:>myprog > test.out

這樣我們就可以在執行後,用一個文本編輯器打開輸出檔案,慢慢閱讀和分析輸出結果。

如果把輸入和輸出的重定向結合起來,也可以這樣執行:

C:>myprog < test.txt > test.out

2、輸出調試資訊

在調試時,很多同學往往首先想到的是使用開發環境所提供的調試功能:設定斷點、單步執行、檢視和修改變量,甚至改變程式的流程。不可否認,使用開發環境所提供的調試功能的确很友善,但當你過分依賴于這些內建工具時,你可能忽略了很多更有效的手段:仔細地分析、充分的資訊。

當我們發現程式沒有按照自己預期得那樣工作時,不要急于跟蹤甚至修改程式,而是應該首先仔細對程式的邏輯、語句、表達式進行檢查和分析,盡可能使程式在表達上更簡潔、更幹淨。如果實在難以發現問題所在,也不必急于借助于內建工具去跟蹤程式的運作。早期的程式員在調試程式時經常會在程式中加入輸出調試資訊的語句或過程,用以觀察程式的運作過程,分析程式的運作邏輯,這種調試手段即使在今天也仍然是非常有效的。

輸出的調試資訊要盡量容易閱讀,格式清楚,在必要的時候,可以借助工具程式或自己編寫的程式對輸出資訊進行處理,以幫助分析問題。

3、發現線索

調試的目的就是要分析錯誤發生的原因,尋找線索。盲目的調試隻會浪費時間。

調試中的技巧很多,這裡提出幾條基本原則:

首先是要使錯誤可重制,要設法保證能夠使錯誤按照自己的意願重複出現。對于不知道什麼時候會冒出來的錯誤,分析起來會困難得多!

縮小導緻錯誤的輸入,設法構造出最小的又能保證錯誤出現的輸入,這樣可以減少變化的可能性,使分析範圍更集中。經常可以采用二分選擇的方法來選擇輸入,就是舍掉一半輸入,看看錯誤是否會出現,如果不出現,則選擇另一半輸入,如此反複,并不斷縮小導緻錯誤的輸入。

4、構造測試資料和測試程式

在題目中所給出的測試樣例隻是一小組測試資料,這雖然通常是我們用來測試程式的第一組資料,但卻是遠遠不夠的。我們應該根據題意自行構造更多的測試資料,尤其是一些邊界狀态的測試資料(資料極大、資料極小、資料量極多、資料量極少、預期出現極端結果等情況)。

邊界測試資料可以用于檢查程式中是否存在邊界錯誤,設計有缺陷的程式,在處理邊界測試資料時往往容易暴露出錯誤。但如果沒有發生明顯的運作錯誤,就需要對結果的正确性進行驗證。

有些測試資料可以通過手工計算求出結果,再與程式的計算結果相對比,而也有些問題,可以通過構造測試程式來進行驗證。

測試程式通常是用确定可靠的算法編寫的解題程式,但不須考慮時間和空間的消耗,用測試程式對測試資料進行求解,用計算結果與待測試程式的計算結果進行對比。

以題1041--純素數問題為例,我們可以用最簡單的窮舉法進行求解,也許這樣的解法是不被接受的,因為效率太低,但這個解法卻可以用作我們的測試程式,甚至——有同學索性在本地先用這個程式把結果算出來,再寫一個程式直接輸出結果——居然也被接受了!

本文來自CSDN部落格,轉載請标明出處:http://blog.csdn.net/camel_flying/archive/2009/08/17/4454206.aspx

繼續閱讀