程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 程序設計和調試中的幾點總結

程序設計和調試中的幾點總結

編輯:Delphi
程序設計和調試中的幾點總結。 在調試過程中 ,遇到了許多困難。 1. 不知道如何在函數中傳遞數組做實參,一開始連如何定義函數中的形參都不知道,還是用了幫助才了解,正式發現F1的幫助作的十分貼心,很好用,只是不太會用。我想,學好如何使用幫助能夠大大縮短學習的周期。    數組實參的傳遞最後解決了,要在type 中對數組進行定義 ,如下操作:       Type          arr1=array[1..100] of integer ;     這樣就定義了一個數組類型---arr1,以後聲明數組只要 x :arr1 ; 而不用 x :array[1..100] of integer ;在數組的實參傳遞中只要使用數組名,如下:     //函數定義       function  f1( x,y :arr1 ) :real ;       begin         .....       end;     //函數使用       p := f1(x,y) ;  //x,y 分別為兩個數組。   2. 在插值調試過程中,算法是以知的,具體的代碼調試要求比較細心。對於變量的定義尤其要注意,應當遵守一定的規則,否則在以後的維護和修改中會帶來許多不必要的麻煩,更有可能帶來許多意想不到的錯誤,這一點在以後說明。對於書上已經寫好的算法,可能由於你取數組下標不同(0或1),循環變量起點不同而有所差異,不能照抄。有時錯誤往往在一個符號(如:>寫成< 等)。   3 . 對於Delphi提供的函數、方法,他們在使用時都有一定的提示。比如 edit1. 當你.下去的時候就會列出此時可以使用的方法,如果沒有找到你要用的方法只有2種情況:①沒有該方法。②你在某地方有錯誤,使該方法不能顯現出來。比如:inttostr(edit1.Text) ,在寫好edit1. 後,找不到Text方法。因為用的函數錯誤,inttostr()中用的是整數值,但是 edit1.Text 是字符串類型,所以不會顯示。用這種方法可以自我檢測。   4. 對於變量的規范命名是十分必要和有用的,這在編寫一些小程序中察覺不出來。因為在小程序中使用不了許多變量,容易管理,用腦子就可以記住,不會產生許多麻煩。而在大程序中,尤其是多人合力完成的程序,你自己定義的變量別人也許不知道,所以規范的命名有助於別人和自己管理和維護程序。如果定義不得當的話,有可能出現意想不到的錯誤。我在寫Unit1的代碼時就遇到了這樣的情況。在寫一次線性插值的時候,在處理邊緣點的時候出現了錯誤。 錯誤是這樣的:當輸入點後,第一次按插值按鈕,沒有錯誤。但是在按一次按鈕就出錯了,這是為什麼呢?為什麼其他的插值沒有出現類似問題呢?我進行了單步調試,發現了出錯的地方是循環變量出錯。當按第二次的時候,循環變量改變了,從而使結果出錯。一看循環變量,原來是i ,而我又用i做了全局變量,由於全局變量中儲存的是循環的次數,因而就沒有在函數中定義i變量,而直接用全局變量代替局部變量。這樣局部的改變影響到全局,就是錯誤的根源。所以,通過這件事,我深刻的了解到規范命名和注釋的重要性。   5. 在對form進行退出過程的執行是一定要注意,如果你對任何一個form進行了操作,如果對其有影響的話,那麼就要在調用form的退出過程是進行復原操作,這是必須的工作,也是很重要的工作之一。     在對form的退出過程的編寫的時候要注意幾個方面:首先,如果你要關閉的form中有一些可視的組件,如:edit,listbox,label,memo等等一些組件,那麼就要將這些組件的內容恢復form剛創建時的樣子,這是十分必須的一步工作。別小看了這一步工作,這有可能給你帶來捆饒。大多數我們調用form使用的語句是formx.show 。而該語句僅僅把你所要調用的form顯示出來而不做其他任何事情,更別說是初始化工作,所以我們要對該form在上次退出的時候就進行初始化工作,以便為我們本次的操作打好基礎。否則,上次操作留下的數據會繼續在form中顯示,從而影響我們本次的操作。     其次,在form的退出過程的編寫也要注意某些有漏洞的地方,初學者往往容易犯這樣的錯誤。比如:大家往往習慣與用form.close來關閉窗口,這是對的,有時我們會單獨做一個退出按鈕,裡面調用了form.close,並且對本form進行了還原,這一切都很正常。但是在他使用form自帶的叉型圖標來關閉form時就會遇到麻煩。再次進入時會發現上次退出的時候沒有進行還原操作,但是還原操作的代碼明明寫了,這是為什麼呢?因為form自帶的關閉只調用了form.close,而不進行其他操作,解決的方法就是在form的Onclose事件中加入還原代碼就可以了。而在自己添加的退出按鈕的過程代碼段中也只需要用一句show.close,還原的是就交給了OnClose Event來完成。 再者,在form關閉的時候,如果對其他的form有過改動,必須要還原,否則會出現上面講過的錯誤。有時兩個form互相影響,就要互相還原。這樣難免就要用到對方form的unit,用語句uses unitx ;而這也有規定。在interface 裡,是不能互相uses 的。如果在interface 裡互相uses,系統會報錯 Circle use ;所以只能夠一個在interface中,另一個在implementation 裡uses,或者兩個都在implementation裡uses。   6. 文件的共享,這是一個減少代碼量和減少重復勞動,減少代碼冗余的好方法。具體來說就是寫一個公共的unit,把多個form都要用到的函數、過程、數據、類型等等都放在一起,這樣便於管理和修改。在每個要用到該unit中的函數的unit中uses一下就可以了。不過有一點很重要,那就是要為每一個函數,過程寫一個聲明,這樣的話別的unit才能夠看見這些函數和過程。否則,僅僅在implementation中寫了函數、過程的實現而不寫聲明的話,他們只在本unit可見,著一點很重要。切記,切記!   7.  對於命名規則我再多說一點,在給變量命名的時候要考慮到他的邏輯性。也就是說給這個變量起的名字是有意義的,能夠讓人一看見就能夠知道他是干什麼用的。這樣不僅僅方便維護人員管理與維護,也方便自己理清思路,可以很快的判斷出邏輯表達試。在這方面,邏輯變量的體現最為明顯,比如: 定義一個邏輯變量 flag 這樣我們就可以看出 flag 是標記的意思。那麼當有標記也就是 flag=true 時,我們可以寫成 if  flag     then …… 而不是寫成  if  flag=true  then …… 對於前一種寫法他的邏輯性更強,而且易於我們的邏輯思維。但是初學者往往會用後一種寫法,這是對 Boolean 類型不太熟悉造成的,我們要養成習慣。盡量使自己的程序的邏輯性強,而且遵守編程規范,這樣會給我們和他人節省很多寶貴的時間和精力。在給函數的形參和實參起名字的時候也要有意義,這樣才不至於搞混淆。我就遇到了這樣的情況,在該設計的 unit2 中,做的是有關積分的東西,積分分為上限和下限,這兩個限定一旦搞錯就會出現錯誤,如果是全部都搞錯還比較容易糾正,上限和下限顛倒過來只是值變成相反數。如果一部分搞錯,一部分是對的,那麼就錯的有夠離譜了,這樣的錯誤往往不能從錯誤的結果加以判斷,只能分段查找程序中的問題。看是否在那裡出錯,如此而已,費時費力,所以要進行合理的命名是十分重要的。   8. 調試工作中很重要的一步就是確定錯誤的位置,這個工作已經由編譯器代替我們完成了。有時後編譯器完成的工作只是初步,具體的位置還是要求我們自己去找出來。有一些錯誤的定位由於某些原因會和實際出錯的位置差別比較大,這些位置的查找是要靠編程的經驗和仔細的觀察才能夠找出來的,在實際中,良好的書寫習慣會幫助我們克服這些實際出錯位置和報錯位置差別比較大的錯誤。這些錯誤中,比較典型的就是:多寫或漏寫 begin 或 end ,使之沒有配對,從而造成程序的出錯。有時候對 ;,(),[ ] 的使用也會造成同樣的效果。克服這些錯誤就是要養成良好的書寫習慣,比如: 在寫程序的時候,一般在同一個循環內的語句都要向左對齊,一個二重循環的內循環要向內縮進一些,用來區別與外循環。在寫 begin 和end 的時候就要一起寫,對於括號(),[ ] 也是一樣的處理,這樣一起寫的好處是以後不會漏掉另一個這樣我們在寫程序的時候就不需要記著前面我還在哪兒用了一個 begin,這裡要寫一個 end 與之對應。這樣的好處在寫函數表達式的時候顯得尤其好用。在一個比較復雜的表達式中如果括號的層數超過3層就十分難以看清楚,這時良好的書寫習慣就會幫了你的大忙了。你不會為了找另一個對應的括號而瞅花了眼,只要一步一步的從裡到外的寫出來,不會有太大困難。當然,別人要看懂是要花一定時間的,但是你寫的卻不會有錯。 除了定位錯誤之外還要改正錯誤,當然我前面講的方法大都是改正錯誤,但是最有效的就是看編譯器給你的提示信息。這是我們查找錯誤的出發點,其中的一些小錯誤很容易就能看出來,比如:變量沒有聲明,在 else 前加了 ; ,類型不對應,函數參數傳遞錯誤等。而有一些錯誤是從信息中看不出來的,語法的錯誤不太難糾正,但是算法的錯誤就不好糾正了。這就要求我們用調試工具來一步步找出錯誤。其中最常用到的工具就是斷點、單步進入、單步跳出,以及 觀察變量。斷點可以幫助我們將程序分段,看一看到底是在那一部分出了錯,以便於查找。不過在調試完畢以後一定要記著把斷點都清除掉,不然你的程序會在運行時突然中斷,而你也查不出錯。我個人比較愛用的是單步進入+單步跳出+Add Watch 這是調試程序的一個必由之路。寫程序並不難,調試程序的高手才是很有本事的人,我一向是這麼認為。單步進入 就是一步一步的調試,邊解釋邊運行,這樣便於我們找到錯誤。單步跳出 是為了幫助單步進入的,單步跳出對於一個過程或者是一個函數是將其看成一條語句,一下子跳過去,這樣節省了那些正確的部分的檢查。也可以用 運行到光標處這一項,兩者都是縮短正確的程序段的檢查時間。 Add Watch 是一個非常好用的東東,你可以在裡面加入你想要監視的變量名稱。則該變量的值會在表中顯示出來,他配合單步操作,可以看見你想要知道的變量在每一步的變化情況是否和預料的一樣變化。如果有出入則可以對該語句進行分析,從而找出出錯的原因。可見單步操作+Add Watch 是調試程序必不可少的步驟,也是最有效的方法。但是,在程序比較復雜,調用函數比較多的時候,單步進入就不是那麼好用了。因為往往在一個按鈕事件中有用到好幾個procedure 或者 function ,在每一個function或者procedure中往往又要調用別的function和 procedure。所以用單步進入很容易讓人搞的暈頭轉向,不知所雲。假如用到了第三方的控件,那就更不知道程序運行到什麼地方了。所以,在程序量比較大,而且調用函數比較多的地方,單步操作就不太好用了。這時我們最好使用斷點工具,他使用的意義和單步操作的意義是一樣的,就是為了看清楚程序是否按我們所設計的思路在運行。斷點的好處就是在於他可以使我們在希望停止的地方暫停,而其余不需要停止的地方則按原來的速率進行運行。結合Add Watch,我們就可以看見整個程序運行的過程了。斷點的增加是比較有講究的,一般情況下都要在以下幾個地方加上斷點: ①循環語句的入口處,在此處加上斷點可以監視進入循環的數據,看看是否在循環以前就有錯誤。在每個循環前放一個就象作一個備份一樣,看看會出什麼樣的結果。 ②在循環語句的最後一句設置一個斷點,這樣就可以監視每一次的循環過程,看看是在那一次循環出錯。還有一個好處就是這樣在循環內部設置一個斷點可以防止無限循環。萬一你編寫的程序出錯,出現了無限循環,這樣會造成系統資源急劇下降,從而容易造成死機。如果你沒有備份這次所做的工作的話,那真是欲哭無淚了。 ③在循環完成處設置一個斷點,這樣可以把入口處和出口處進行對照,看一看該循環是否按照你的要求正常工作,可以很快的判斷出循環語句的正確性。 ④在判斷語句前設置斷點,這個斷點主要的目的是觀察此時的Add Watch 中的值。此時的各個判斷參數的值可以看出程序是否按照正常步驟進行,或者在判斷語句中出現了邏輯錯誤,這些都是很常見的斷點設置處。   9. 設置procedure 和function 的各種用法。不要小看了var 這三個字,我們通常在定義變量中使用,而他的一個很重要的用途就是在 procedure 或者function中設置變參。變參在普通的procedure 和function中不是很常用,但是卻有著十分重要的用途。如果你想編寫一個函數,要返回兩個值,因為這兩個值是在同一個函數中得出的。所以想要有兩個返回值,但是函數只能有一個返回值,這時該如何解決呢?變參就派上了用場,在函數和過程中使用的變參會改變實參的值就象傳址函數一樣。這樣的話,在一個過程或者函數中定義多個變參就可以返回多個參數了。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved