?? 029.htm
字號:
<p>Msg: String;</p>
<p>begin</p>
<p>case ErrorNum of</p>
<p>1:</p>
<p>Msg := 'Can not convert String to Number';</p>
<p>2:</p>
<p>Msg := 'Number is out of Range';</p>
<p>else</p>
<p>Msg := 'Input is Invalid';</p>
<p>end;</p>
<p>inherited Create(Msg,ErrorNum);</p>
<p>end; </p>
<p><font face="宋體" lang="ZH-CN">對于</font>EInvalidInput<font face="宋體"
lang="ZH-CN">,</font>ErrorCode=1<font face="宋體" lang="ZH-CN">表示輸入的不是純數(shù)字序列,而</font>ErrorCode=2<font
face="宋體" lang="ZH-CN">表示輸入數(shù)值越界。</font></p>
<p><font face="宋體" lang="ZH-CN">口令檢查是用戶在</font>PassWord<font
face="宋體" lang="ZH-CN">中輸入口令并按下回車鍵后開始的。實現(xiàn)代碼在</font>PassWord<font
face="宋體" lang="ZH-CN">的</font>OnKeyPress<font face="宋體" lang="ZH-CN">事件處理過程中: </p>
</font><p>procedure TForm1.PassWordKeyPress(Sender: TObject; var Key: Char);</p>
<p>const</p>
<p>CurrentPassWord = 'Delphi';</p>
<p>begin</p>
<p>if Key = #13 then</p>
<p>begin</p>
<p>try</p>
<p>if PassWord.text <> CurrentPassWord then</p>
<p>raise EInvalidPassWord.Create;</p>
<p>Label2.Visible := True;</p>
<p>InputEdit.Visible := True;</p>
<p>InputEdit.SetFocus;</p>
<p>PassWord.Visible := False;</p>
<p>Label1.Visible := False;</p>
<p>except</p>
<p>on EInvalidPassWord do</p>
<p>begin</p>
<p>PassWord.text := '';</p>
<p>raise;</p>
<p>end; </p>
<p>end;</p>
<p>Key:=#0;</p>
<p>end;</p>
<p>end; </p>
<p><font face="宋體" lang="ZH-CN">同樣,在</font>InputEdit<font face="宋體"
lang="ZH-CN">的</font>OnKryPress<font face="宋體" lang="ZH-CN">事件處理過程中實現(xiàn)了輸入數(shù)字的合法性檢查: </p>
</font><p>procedure TForm1.InputEditKeyPress(Sender: TObject; var Key: Char);</p>
<p>var</p>
<p>Res: Real;</p>
<p>Code: Integer;</p>
<p>begin</p>
<p>if Key = #13 then</p>
<p>begin</p>
<p>try</p>
<p>val(InputEdit.text,Res,Code);</p>
<p>if Code <> 0 then</p>
<p>raise EInValidInput.create(1);</p>
<p>if (Res > 1) or (Res < 0) then</p>
<p>raise EInValidInput.create(2);</p>
<p>MessageDlg('Correct Input', mtInformation,[mbOk], 0);</p>
<p>Key := #0;</p>
<p>except</p>
<p>on E:EInValidInput do</p>
<p>begin</p>
<p>InputEdit.text := '';</p>
<p>MessageDlg(E.Message, mtWarning,[mbOk], 0);</p>
<p>end;</p>
<p>end;</p>
<p>end;</p>
<p>end; </p>
<p><font face="宋體" lang="ZH-CN">由于異常響應后即被清除,所以要顯示異常信息,需要另外的手段。在以上兩段程序中我們采用了兩種不同的方法:在口令合法性檢查中,利用異常重引發(fā)由系統(tǒng)進行缺省響應;在輸入數(shù)字合法性檢查中,通過異常實例來獲取異常信息并由自己來顯示它。</font></p>
<p><font face="宋體" lang="ZH-CN">以上所舉的是一個非常簡單的例子,但從中已可以發(fā)現(xiàn):使用自定義異常編程,為程序設計帶來了很大的靈活性。 </p>
</font><p>12.3.6 <font face="宋體" lang="ZH-CN">利用異常響應編程 </p>
<p> 利用異常處理機制不僅能使程序更加健壯,而且也提供了一種使程序更加簡捷、明了的途徑。事實上,使用自定義異常類就是一種利用異常響應編程的方式。這里我們再討論幾個利用標準異常類編程的例子。</p>
<p> 比如為了防止零作除數(shù),可以在進行除法運算前使用</font>if<font
face="宋體" lang="ZH-CN">…</font>then<font face="宋體" lang="ZH-CN">…</font>else<font
face="宋體" lang="ZH-CN">語句。但如果有一系列這樣的語句則繁瑣程度是令人難以忍受的。這時候我們可能傾向于使用</font>EDivByZero<font
face="宋體" lang="ZH-CN">異常。例如如下一段程序就遠比用</font>if<font
face="宋體" lang="ZH-CN">…</font>then<font face="宋體" lang="ZH-CN">…</font>else<font
face="宋體" lang="ZH-CN">實現(xiàn)簡捷明了。 </p>
</font><p>function Calcu(x,y,z,a,b,c:Integer):Real;</p>
<p>begin</p>
<p>try</p>
<p>Result := x/a+y/b+z/c ;</p>
<p>except</p>
<p>on EDivByZero do</p>
<p>Result := 0;</p>
<p>end;</p>
<p>end;</p>
<p><font face="宋體" lang="ZH-CN">在</font>(6.2.3)<font face="宋體" lang="ZH-CN">記錄文件的打開與創(chuàng)建中就是利用異常響應來實現(xiàn)文件的打開或創(chuàng)建。 </p>
</font><p>procedure TRecFileForm.OpenButtonClick(Sender: TObject);</p>
<p>begin</p>
<p>if OpenDialog1.Execute then</p>
<p>FileName := OpenDialog1.FileName</p>
<p>else</p>
<p>exit;</p>
<p>AssignFile(MethodFile,Filename);</p>
<p>try</p>
<p>Reset(MethodFile);</p>
<p>FileOpened := True;</p>
<p>except</p>
<p>on EInOutError do</p>
<p>begin</p>
<p>try</p>
<p>if FileExists(FileName) = False then</p>
<p>begin</p>
<p>ReWrite(MethodFile);</p>
<p>FileOpened := True;</p>
<p>end</p>
<p>else</p>
<p>begin</p>
<p>FileOpened := False;</p>
<p>MessageDlg('<font face="宋體" lang="ZH-CN">文件不能打開</font>',mtWarning,[mbOK],0);</p>
<p>end;</p>
<p>except</p>
<p>on EInOutError do</p>
<p>begin</p>
<p>FileOpened := False;</p>
<p>MessageDlg('<font face="宋體" lang="ZH-CN">文件不能創(chuàng)建</font>',mtWarning,[mbOK],0);</p>
<p>end;</p>
<p>end;</p>
<p>end;</p>
<p>end;</p>
<p>if FileOpened = False then exit;</p>
<p>Count := FileSize(MethodFile);</p>
<p>if Count > 0 then</p>
<p>ChangeGrid;</p>
<p>RecFileForm.Caption := FormCaption+' -- '+FileName;</p>
<p>NewButton.Enabled := False;</p>
<p>OpenButton.Enabled := False;</p>
<p>CloseButton.Enabled := True;</p>
<p>end; </p>
<p><font face="宋體" lang="ZH-CN">總之,利用異常響應編程的中心思想是雖然存在預防異常發(fā)生的確定方法,但卻對異常的產(chǎn)生并不進行事前預防,而是進行事后處理,并以此來簡化程序的邏輯結(jié)構(gòu)。 </p>
</font><p align="center">12.4<font face="宋體" lang="ZH-CN"> 程序調(diào)試簡介 </p>
<p> </font>Delphi<font face="宋體" lang="ZH-CN">提供了一個功能強大的內(nèi)置調(diào)試器</font>(Integrated
Debugger), <font face="宋體" lang="ZH-CN">因而對程序的調(diào)試不用離開集成開發(fā)環(huán)境</font>(IDE)<font
face="宋體" lang="ZH-CN">就可以進行。</p>
<p> 程序錯誤基本可以分為兩類,即運行時間錯和邏輯錯。所謂運行時間錯是指程序能正常編譯但在運行時出錯。邏輯錯是指程序設計和實現(xiàn)上的錯誤。程序語句是合法的,并順利執(zhí)行了,但執(zhí)行結(jié)果卻不是所希望的。</p>
<p> 對于這兩類錯誤,調(diào)試器都可以幫助你快速定位錯誤,并通過對程序運行的跟蹤和對變量值的監(jiān)視幫助你尋找錯誤的真正原因和解決錯誤的途徑。</p>
<p> 程序調(diào)試的主要內(nèi)容可以概括為如下的幾方面:</p>
<p> </font>1.<font face="宋體" lang="ZH-CN">調(diào)試的準備和開始;</p>
<p> </font>2.<font face="宋體" lang="ZH-CN">控制程序的執(zhí)行;</p>
<p> </font>3.<font face="宋體" lang="ZH-CN">斷點的使用;</p>
<p> </font>4.<font face="宋體" lang="ZH-CN">檢查數(shù)據(jù)的值。</p>
<p> 程序調(diào)試只有用戶實際上機操作才能真正掌握。在這一節(jié)中我們主要對調(diào)試中的主要問題和一些關(guān)鍵點進行介紹。至于一些很細小的問題相信讀者可以在上機實際應用中掌握,因而沒有列出。</p>
<p> </font></p>
<p>12.4.1 <font face="宋體" lang="ZH-CN">調(diào)試的準備和開始 </p>
<p> 在程序開發(fā)過程中程序編碼和調(diào)試是一個持續(xù)的循環(huán)過程,只有在你對程序進行了徹底的測試后才能交付最終用戶使用。為了保證調(diào)試的徹底性,在調(diào)試前應制定一個詳細的調(diào)試計劃。一般說來應該把程序劃分為幾個相對獨立的部分,分別進行調(diào)試,以利于錯誤的迅速定位,確保每一部分程序都按設計的要求運行。</p>
<p> 調(diào)試計劃準備好后就可以開始程序的調(diào)試。</p>
<p> 開始一個調(diào)試過程包括:</p>
<p> </font>1.<font face="宋體" lang="ZH-CN">編譯時產(chǎn)生調(diào)試信息;</p>
<p> </font>2.<font face="宋體" lang="ZH-CN">從</font>Delphi<font face="宋體"
lang="ZH-CN">里運行你的程序。</p>
<p> 在程序調(diào)試過程中,程序的執(zhí)行完全在你的控制之中。你可以在任何位置暫停程序的執(zhí)行去檢查變量和數(shù)據(jù)結(jié)構(gòu)的值,去顯示函數(shù)調(diào)用序列,去修改程序中變量的值以便觀察不同值對程序行為的影響。 </p>
</font><p>12.4.1.1 <font face="宋體" lang="ZH-CN">產(chǎn)生調(diào)試信息 </p>
<p> 要使用內(nèi)部調(diào)試器必須選中</font>Option| Environment<font face="宋體"
lang="ZH-CN">菜單</font>References<font face="宋體" lang="ZH-CN">頁的</font>Integrated
Debugging<font face="宋體" lang="ZH-CN">檢查框。缺省情況下該框被選中。</p>
<p> 在開始調(diào)試前需要使用</font>Symbols Debug Information(<font
face="宋體" lang="ZH-CN">調(diào)試符號信息</font>)<font face="宋體" lang="ZH-CN">編譯工程文件。調(diào)試符號信息包含了一個符號表,能夠使調(diào)試器在程序的源代碼與編譯器產(chǎn)生的機器代碼間建立聯(lián)系。這樣在程序執(zhí)行中可以同時查看對應的源代碼。</p>
<p> </font>Delphi <font face="宋體" lang="ZH-CN">在缺省情況下自動產(chǎn)生調(diào)試符號信息。在集成開發(fā)環(huán)境中的開關(guān)選項是</font>Option|project<font
face="宋體" lang="ZH-CN">菜單</font>Compiler Options<font face="宋體" lang="ZH-CN">頁的</font>Debug
Information and Local Symbols<font face="宋體" lang="ZH-CN">檢查框。</p>
<p> 當產(chǎn)生的調(diào)試符號信息供內(nèi)部調(diào)試器使用時,編譯器把調(diào)試符號表儲存在每個相應的</font>.dcu<font
face="宋體" lang="ZH-CN">文件中。</p>
<p> 如果希望在集成環(huán)境外使用</font>Turbo Debugger<font face="宋體"
lang="ZH-CN">,則需要把調(diào)試信息儲存在最終的</font> .exe<font face="宋體"
lang="ZH-CN">文件中。為此需要選定</font>Option|Project<font face="宋體"
lang="ZH-CN">菜單</font>Linker<font face="宋體" lang="ZH-CN">頁的</font>Include TDW
Debug Info<font face="宋體" lang="ZH-CN">檢查框。</p>
<p> 由于儲存調(diào)試信息大大增加了執(zhí)行文件的大小,因而調(diào)試完成后應重新生成一個不包含調(diào)試信息的執(zhí)行文件。 </p>
</font><p>12.4.1.2 <font face="宋體" lang="ZH-CN">運行程序 </p>
<p> 通過調(diào)試器</font>(<font face="宋體" lang="ZH-CN">包括內(nèi)置調(diào)試器</font>)<font
face="宋體" lang="ZH-CN">運行程序,當程序處于等待狀態(tài)時,調(diào)試器可以獲得控制,利用調(diào)試器的功能來檢查當前程序的狀態(tài)。通過合理布置屏幕顯示,使應用程序運行窗口和</font>Code
Editor(<font face="宋體" lang="ZH-CN">代碼編輯器</font>)<font face="宋體"
lang="ZH-CN">互不重疊,可以讓用戶在它們間方便地切換以觀察代碼執(zhí)行的效果。</p>
<p> 如果希望使用命令行參數(shù)來調(diào)試程序,則可以通過</font>Run|Parameters
<font face="宋體" lang="ZH-CN">菜單打開運行參數(shù)對話框進行設置。 </p>
</font><p>12.4.2 <font face="宋體" lang="ZH-CN">程序運行的控制 </p>
<p> 程序運行控制的方法和使用如下表。 </p>
<p> 表</font>12.7<font face="宋體" lang="ZH-CN"> 程序運行控制的方法和使用途徑</p>
<p>━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</p>
<p>方法 使用途徑</p>
<p>───────────────────────────────</p>
<p>運行到光標位置 ●</font> Code Editor<font face="宋體" lang="ZH-CN">加速菜單的</font>Run
to Cursor<font face="宋體" lang="ZH-CN">項</p>
</font><p>(Run to Cursor) <font face="宋體" lang="ZH-CN">●</font> Run<font
face="宋體" lang="ZH-CN">主菜單的</font>Run to Cursor<font face="宋體"
lang="ZH-CN">項</p>
<p>●</font> F4</p>
<p><font face="宋體" lang="ZH-CN">跟蹤</font>(Trace Into) <font face="宋體"
lang="ZH-CN">●</font> Run<font face="宋體" lang="ZH-CN">主菜單的</font>Trace Into<font
face="宋體" lang="ZH-CN">項</p>
<p>●</font> Trace Into<font face="宋體" lang="ZH-CN">加速按鈕</p>
<p>●</font> F7</p>
<p><font face="宋體" lang="ZH-CN">步進</font>(Step Over) <font face="宋體"
lang="ZH-CN">●</font> Run<font face="宋體" lang="ZH-CN">主菜單的</font>Step Over<font
face="宋體" lang="ZH-CN">項</p>
<p>●</font> Step Over<font face="宋體" lang="ZH-CN">加速按鈕</p>
<p>●</font> F8</p>
<p><font face="宋體" lang="ZH-CN">運行到斷點 設置斷點并按正常方式運行</p>
<p>暫停程序執(zhí)行 </font>Run<font face="宋體" lang="ZH-CN">主菜單的</font>Program
Pause<font face="宋體" lang="ZH-CN">項</p>
<p>━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ </p>
<p> 跟蹤和步進都是一種單步執(zhí)行方式。但“步”的含義不同。對跟蹤而言它一次執(zhí)行一條簡單程序語句。當碰到包含調(diào)試信息的函數(shù)或過程調(diào)用時則跳入該函數(shù)或過程,并執(zhí)行其第一條可執(zhí)行語句。對步進而言它一次執(zhí)行一條當前模塊的可執(zhí)行語句,而不管該語句是否是函數(shù)或過程調(diào)用。</p>
<p> 運行到光標位置和運行到斷點都是程序正常運行到某一確定的源代碼位置,而后進入調(diào)試狀態(tài)。但相對于運行到光標位置而言,運行到斷點更為靈活。因為斷點一次可設置多個,同時也可以對斷點設置一定的條件。只有滿足該條件程序運行才會中止。</font></p>
<p><font face="宋體" lang="ZH-CN"> </font></p>
<hr color="#EE9B73" size="1" width="94%">
</TD>
<TD CLASS="tt3" VALIGN="bottom" width="8%" bgcolor="#e0e0e0"><strong><A HREF="030.htm"><FONT style="FONT-SIZE: 9pt">后一頁</font></A><BR>
<A HREF="028.htm"><FONT style="FONT-SIZE: 9pt">前一頁</font></A><BR>
<A HREF="index.html"><FONT style="FONT-SIZE: 9pt">回目錄</font></A><BR>
<A HREF="../../../../index.htm"><FONT style="FONT-SIZE: 9pt">回首頁</font></A><BR>
</strong>
</TD>
</TR>
</table>
</BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -