Delphi應用程式的調試(三)監視變數

來源:互聯網
上載者:User
監視變數(Watching Variables)

當程式停在一個斷點處時,使用者做些什麼呢?通常使用者在斷點處停下來是要檢查變數的值,某個變數的值是否與預料的取值相同?或者某個變數取什麼值(事先並不知道這個變數的取值)。

Watch List視窗的作用是使使用者能檢查變數的值。編程人員常常忽視這個簡單而又根本的特性,因為他們沒有花時間來完整地學習調試器的使用。使用者可添加任意多的變數到Watch List中。就是偵錯工作階段期間的Watch List視窗。

變數名和變數值都顯示在Watch List中。

Tooltip運算式求值(Tooltip Expression Evaluation)

調試器和Code Editor有一個很好的特性,它使檢查變數值的工作變得更容易。這個特性就是Tooltip運算式求值器(expression evaluator),其預設狀態是開啟,因此使用者不需要做任何事情就能使用它。如果需要,也可以通過Editor Properties對話方塊的Code Insight頁面來關閉它,如:

那麼,什麼是Tooltip運算式求值呢?它是這樣工作的:當程式停在一個斷點處,使用者把編輯游標移到一個變數上,就會彈出一個提示視窗,其中顯示該變數的當前值。這樣就使快速檢查變數的工作變得更容易,只需將游標移到變數上並稍等片刻。

Tooltip evaluator求值器對於不同的變數類型由不同的顯示。對於常規資料成員(Integer、Char、Byte、String等等),顯示變數的實際值;對於動態建立的對象(例如一個類的執行個體),Tooltip evaluator顯示記錄的全部元素。如所示:

Note

有時候Tooltip evaluator好像工作不正常。例如,若將編輯游標移到一個範圍外的變數上時,就不會顯示提示視窗,因為Tooltip evaluator 無任何資訊可顯示。被編輯器最佳化過的變數也可能不能顯示正確值。

當游標位於with塊中時,Tooltip evaluator也不工作。例如,看下面這段代碼:

var  pp: Point;begin  with  pp do  begin    x := 20;    y := 40;  end;  Caption := IntToStr(pp.x);end;

如果把游標放到變數x上,Tooltip evaluator不會顯示x的值,因為x屬於with語句(Point變數)。如果將游標移到變數Point上,調試器會顯示Point的值(包括x欄位)。如:

Tooltip 運算式求值器很有用的,別忘記使用它。

Watch List捷徑功能表(The Watch List Context Menu)

正如前面講到的每一個Delphi視窗一樣,Watch List也有它自己的捷徑功能表。如下描述:

Edit Watch——開啟Watch Properties對話方塊修改監視項屬性

Add Watch——開啟Watch Properties對話方塊新監視項

Enable Watch——啟用一個已經禁用的監視項

Disable Watch——禁用一個已啟用的監視項

Delete Watch——刪除一個監視項

Enable All Watches——啟用所有已經禁用的監視項

Disable All Watches——禁用所有已經啟用的監視項

Delete All Watches——刪除所有監視項

Add Group——增加一個監視組

Delete Group——刪除一個監視組

Move Watch to Group——移動監視項到組

Stay On Top——使Watch List視窗始終在最上層

Inspect——顯示選中的監視項的有關資訊

Break When Changed——當監看式視窗中的變數改變時,調試器將終端。監視變數以紅色顯示,表示Break When Changed起作用。

Dockable——視窗是可泊位。

使用Watch Properties對話方塊(Using the Watch Properties Dialog Box)

 

當使用者增加或編輯監視項時,要使用Watch Properties對話方塊。如顯示的是正在編輯pp變數的Watch Properties對話方塊。

位於對話方塊頂部的【Expression欄位】,是使用者輸入要編輯或增加到Watch List中的變數名的地方,這個欄位是一個組合框,可以用來選取以前用過的監視項。

但使用者要檢查數組時,使用【Repeat count欄位】,比如,有一個20個整數元素的數組,要檢查數組的頭10個整數,可在【Expression欄位】中輸入數組的第一個元素(例如Array[0]),再在【Repeat count欄位】中輸入10。數組的頭10個元素就會顯示在Watch List中。如pp為有20個元素的整型數組:

Note

如果將數組名增加到Watch List中,則數組的全部元素都會顯示在Watch List中。當要查看數組的部分元素時,使用【Repeat count欄位】。

僅當檢查浮點數時,采使用【Digits欄位】;在此輸入顯示浮點數時要顯示的有效位元,有效位後面的餘數作四捨五入處理。【Enabled欄位】確定監視項是否當前啟用。

Watch Properties對話方塊上的其餘選項都是顯示選項。每一種資料類型都有一種預設顯示類型,當使用者選中【Default】時,就使用預設顯示類型,Default查看選項的預設狀態時“選中”的。選擇其他的查看選項,就以其他方式查看資料。如:

要修改一個監視項,可在Watch List中點擊該項,然後在右鍵捷徑功能表中選擇【Edit Watch…】功能表項目,也可雙擊該監視項,快速開啟Watch Properties對話方塊。

啟用和禁用監視項(Enabling and Disabling Watch Items)

就像使用斷點時一樣,Watch List中每項都可被啟用或禁用。當一個監視項被禁用時,它會變灰,並且它的值顯示為<disabled>。如:

要禁用一個監視項,可點擊Watch List中該項的名字,並從Watch List捷徑功能表中選擇【Disabled Watch】功能表項目;要啟用該監視項,就從捷徑功能表中選【Enabled Watch】功能表項目。

Note

使用者可能希望禁用當前不使用但以後要使用的監視項。在調試過程中,Watch List中的許多有效監視項會減慢程式執行速度,因為每當一個程式碼執行時,所有Watch List變數都要更新。

向Watch List中添加變數(Adding Variables to the Watch List)

可用多種方法往Watch List中添加監視項。最快速的方法是點擊Code Editor中的變數名,然後從Code Editor的捷徑功能表中選擇【Debug | Add Watch at Cursor】或按【Ctrl + F5】鍵,該監視項就會被立即增加到Watch List中。如果需要,使用者可以編輯該監視項,修改其屬性。

要增加一個變數到Watch List中而又不想在源檔案中找出該變數時,可從主菜單選擇【Run | Add Watch】功能表項目;當Watch Properties對話方塊彈出後,輸入要增加到Watch List中的變數名並點擊OK。

Note

雖然可將類執行個體變數添加到Watch List中,但顯示的值可能無用。如:

應該使用Debug Inspector查看類的所有資料成員。

使用Watch List(Using the Watch List)

當碰到斷點時,Watch List顯示其中所有變數的當前值,如果當前沒有開啟Watch List視窗,可從主菜單【View | Debug Window | Watches】功能表項目開啟Watch List視窗。

Note

將Watch List視窗泊位到Code Editor視窗的底部,這樣,在調試代碼時,總可以看到它。

在某些情況下,Watch List中變數的後面會顯示一條訊息,而不是該變數的值。例如,如果一個變數不在範圍之外,或未找到,Watch List在該變數名後面顯示“Undeclared identifier: ‘X’”;如果程式沒有運行或不停在斷點處,Watch List在所有的監視項後都顯示[process not accessible]。禁用監視項後顯示<disabled>。根據應用程式的目前狀態或某個變數的目前狀態,還可能顯示其他訊息。

就像上一章提到過的,使用者在Watch List中偶爾會看到這樣的顯示:variable 'X' inaccessible here due to optimization,這是帶最佳化功能的編輯器的一個小缺點。如果要檢查易被最佳化的變數,則必須關閉編譯器的最佳化功能,即把Project Options對話方塊中的Compiler頁面上的Optimization選項關閉。

未被初始化的變數會顯示隨機值,直到它被初始化。

Note

Watch List可用作一個簡單的十進位/十六進位轉換器。要把一個十六進位數轉換成十進位數,可從主菜單選擇【Run | Add Watch】,在Expression欄位輸入十六進位數後點擊OK,輸入的十六進位數和與之等價的十進位數就會顯示在Watch List中;要將一個十進位數轉換成十六進位數,除點擊Hexadecimal單選鈕將顯示類型改為十六進位外,其餘操作都與前面相同。由於Expression接受數學運算式,因此還可以把Watch List當做一個十六進位計算機,甚至可以在同一個運算式中同時使用十六進位和十進位值。如:

這樣使用Watch List只有一個缺點,應用程式必須停在一個斷點處

在調試應用程式的過程中,Watch List是一個簡單而又關鍵的工作。為了說明Watch List的使用,接下來做一個練習:

1)建立一個應用程式,在其主表單上放置一個按鈕。將按鈕的Name屬性設定為WatchBtn,Caption屬性改為Watch Test。將主表單Name屬性改為DebugMain,Caption屬性改為Debug Watch List Test。

2)雙擊按鈕,會在Code Editor中顯示按鈕的OnClick處理事件,按下面的樣子修改其OnClick處理常式:

procedure TDebugMain.WatchBtnClick(Sender: TObject);var  S: string;  X, Y: Integer;begin  X := Width;  S := IntToStr(X);  Y := Height;  X := X * Y;  S := IntToStr(X);  X := X div Y;  S := IntToStr(X);  Width := X;  Height := Y;end;

3)儲存該工程,將單元命名為DbgMain,工程命名為DebugTest。

4)在OnClick處理常式的begin語句之後的第一行上設定一個斷點,運行該應用程式。

5)點擊Watch Test按鈕,調試器會停止在斷點處。當調試器停在斷點處時,IDE和Code Editor會顯示在最頂層。

6)把變數S,X和Y增加到Watch List中(由於代碼最佳化,變數X和變數Y在開始時是不可訪問的),如:

7)安排好Watch List和Code Editor的位置,以便使用者能同時看到兩個視窗(不妨把Watch List泊位到Code Editor的底部)。

8)將輸入焦點切換到Code Editor,並按F8執行下一行代碼,執行完畢後,執行點移到下一行。此時Watch List中變數X顯示一個值。如:

9)按F8繼續一行一行執行程式,監視Watch List中變數的結果。

10)當執行點到達OnClick處理常式的最後一行時,點擊工具列中的Run按鈕繼續運行應用程式。

使用者可反覆點擊Watch Test按鈕來體會Watch List是如何工作的,每次還可實驗不同監視設定的效果。

Note

在上面的例子中,OnClick處理常式先擷取主表單的Width屬性和Height屬性的值,接著執行一些計算,然後再將Width和Height設定成開始時的值。這段程式執行完後,什麼都未發生改變。在該方法末尾給Width和Height屬性賦值是有原因的。

如果在代碼中不真正使用變數X和Y的話,使用者就不能檢查這兩個變數,因為編譯器在最佳化代碼時會發現這個兩個變數未被使用,從而將它們刪除。在方法的末尾使用這兩個變數就是為了避免編譯器把它們最佳化掉。

前面提到過這個問題,希望大家對帶最佳化功能的編譯器的工作過程有個基本瞭解。這樣,當開始調試應用程式,碰到諸如“Variable ‘Y’ inaccessible here due to optimization”一類的訊息時就不會不知所措。

以上代碼均在Delphi7中測試通過,執行個體代碼下載:WatchList測試程式.rar

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.