練習 - 監視變數和執行流程
RUN AND DEBUG 檢視可讓開發人員輕鬆監視變數和表示式、觀察執行流程,以及在偵錯程式期間管理斷點。
檢查執行與偵錯視圖的區段
RUN AND DEBUG 檢視的每個區段都提供獨特的功能。 在偵錯過程中組合這些區段通常很有幫助。
變數區段
監視變數狀態是程式代碼偵錯的重要層面。 變數狀態中的非預期變更通常有助於識別程式代碼中的邏輯錯誤。
VARIABLES 區段會依範圍組織您的變數。 範圍 Locals 會顯示目前範圍中的變數(目前方法)。
備註
主控台應用程式的最上層語句區段會被視為它自己的方法。 名為 Main的方法。
您可以選取範圍名稱左邊的箭號,以展開顯示的範圍。 您也可以展開變數和物件。 下列螢幕快照顯示 numbers 範圍下展開的 Locals 陣列。
您也可以使用 VARIABLES 區段在運行時間變更變數的值。 您可以按兩下變數名稱,然後輸入新的值。
[監看式] 區段
如果您想要追蹤一段時間或不同方法的變數狀態,該怎麼辦? 每次查找變數可能會很繁瑣。 這就是 WATCH 區段派上用場的地方。
您可以選取 [ 新增運算式] 按鈕(顯示為加號: +),以輸入要監看的變數名稱或表達式。 或者,您可以在 VARIABLES 區段中以滑鼠右鍵點擊變數,然後選取 Add to watch。
當程式代碼執行時,WATCH 區段內的所有運算式都會自動更新。
[呼叫堆疊] 區段
每次程式代碼從另一個方法輸入方法時,呼叫層就會新增至應用程式的呼叫堆疊。 當您的應用程式變得複雜,而且有一長串方法被其他方法呼叫時,呼叫堆疊代表了方法呼叫的路徑。
當您嘗試尋找例外狀況或 WATCH 表達式的來源位置時,CALL STACK 區段很有用。 如果您的應用程式擲回非預期的例外狀況,您通常會在控制台中看到類似下列的訊息:
Exception has occurred: CLR/System.DivideByZeroException
An unhandled exception of type 'System.DivideByZeroException' occurred in Debug1.dll: 'Attempted to divide by zero.'
at Program.<<Main>$>g__WriteMessage|0_1() in C:\Users\howdc\Desktop\Debug1\Program.cs:line 27
at Program.<<Main>$>g__Process1|0_0() in C:\Users\howdc\Desktop\Debug1\Program.cs:line 16
at Program.<Main>$(String[] args) in C:\Users\howdc\Desktop\Debug1\Program.cs:line 10
錯誤訊息底下的縮排行群組 at Program ... 稱為堆疊追蹤。 堆疊追蹤會列出在例外狀況前呼叫之每個方法的名稱和來源。 不過,資訊可能有點難以解讀,因為它也可以包含 .NET 執行環境的資訊。 在此範例中,堆疊追蹤相當乾淨,而且您可以看到例外狀況發生在名為 WriteMessage的方法中。 堆疊源自名為 Main的方法,也就是控制台應用程式的最上層語句區段。
[呼叫堆疊] 區段可協助您避免難以解譯摻雜了 .NET 執行階段資訊的堆疊追蹤。 其會篩選掉不必要的資訊,依預設只會顯示您自己程式代碼的相關方法。 您可以手動回溯呼叫堆疊,以找出例外狀況的來源。
[中斷點] 區段
BREAKPOINTS 區段會顯示目前的斷點設定,可用來在偵錯會話期間啟用或停用特定斷點。
設定您的應用程式並啟動設定
當您在讀取使用者輸入的主控台應用程式上工作時,您可能需要更新啟動設定檔。
更新Program.cs檔案中的程序代碼,如下所示:
string? readResult; int startIndex = 0; bool goodEntry = false; int[] numbers = { 1, 2, 3, 4, 5 }; // Display the array to the console. Console.Clear(); Console.Write("\n\rThe 'numbers' array contains: { "); foreach (int number in numbers) { Console.Write($"{number} "); } // To calculate a sum of array elements, // prompt the user for the starting element number. Console.WriteLine($"}}\n\r\n\rTo sum values 'n' through 5, enter a value for 'n':"); while (goodEntry == false) { readResult = Console.ReadLine(); goodEntry = int.TryParse(readResult, out startIndex); if (startIndex > 5) { goodEntry = false; Console.WriteLine("\n\rEnter an integer value between 1 and 5"); } } // Display the sum and then pause. Console.WriteLine($"\n\rThe sum of numbers {startIndex} through {numbers.Length} is: {SumValues(numbers, startIndex)}"); Console.WriteLine("press Enter to exit"); readResult = Console.ReadLine(); // This method returns the sum of elements n through 5 static int SumValues(int[] numbers, int n) { int sum = 0; for (int i = n; i < numbers.Length; i++) { sum += numbers[i]; } return sum; }花一分鐘的時間檢閱程序代碼。
請注意下列項目:
- 程式碼指定一個包含五個數字的整數數組。
- 程式碼會在主控台中顯示輸出。
- 程式代碼會提示使用者輸入用來透過
n加總數組元素n的起始項目編號5。 - 程式代碼會計算方法中的總和、在控制台中顯示結果,然後暫停。
備註
[偵錯主控台] 面板不支援來自主控台的使用者輸入。
在 Visual Studio Code 的 [檔案] 功能表上,選取 [儲存]。
在 [執行] 功能表上,選取 [移除所有斷點]。
這會移除上一個練習中剩餘的任何中斷點。
在 [執行和偵錯] 檢視上,選取 [ 開始偵錯]。
請注意,執行程式代碼行時
Console.Clear();發生錯誤。在 [偵錯工具列] 上,選取 [停止]。
切換至 EXPLORER 檢視,然後在編輯器中開啟 launch.json 檔案。
更新
console屬性的值,如下所示:"console":"integratedTerminal",在 [Visual Studio Code 檔案 ] 功能表上,選取 [ 儲存],然後關閉 launch.json 檔案。
檢閱應用程式輸出並找出問題
檢閱應用程式的輸出可能會顯示您在撰寫程式代碼時忽略的邏輯問題。
切換回 [執行並偵錯] 檢視。
在 [執行和偵錯] 檢視上,選取 [ 開始偵錯]。
在 [偵錯控制台] 面板顯示的訊息會顯示偵錯器已附加至
Debug101.dll應用程式。請注意,不會顯示任何錯誤訊息。
將屬性的值
console從 internalConsole 變更為啟動組態檔中的 integratedTerminal 已修正控制台錯誤。 但現在,您需要找出包含輸出的控制台。在 [編輯器] 下方的 [面板] 區域中,從 [偵錯控制台] 面板切換至 [終端機] 面板。
請注意,程式碼執行在要求使用者輸入
n值的訊息處暫停。終端機面板上的輸出看起來應該如下所示:
The 'numbers' array contains: { 1 2 3 4 5 } To sum values 'n' through 5, enter a value for 'n':在 [終端] 命令提示字元中,輸入 3
檢閱應用程式的輸出。
終端機面板上的輸出看起來應該如下所示:
The 'numbers' array contains: { 1 2 3 4 5 } To sum values 'n' through 5, enter a value for 'n': 3 The sum of numbers 3 through 5 is: 9 press Enter to exit請花一分鐘的時間來考慮回報的值
sum,以及控制台頂端所顯示陣列元素 3 到 5 的值。訊息說:
The sum of numbers 3 through 5 is: 9。 不過,陣列元素 3 到 5 是3、4和5。 報告的總和不該是 12 嗎?您可以使用 RUN AND DEBUG 檢視的 VARIABLES 區段來調查問題。
監視變數狀態
在某些情況下,只要監視變數狀態就足以識別應用程式中的邏輯問題。
在下列程式代碼列上設定斷點:
Console.WriteLine($"\n\rThe sum of numbers {startIndex} through {numbers.Length} is: {SumValues(numbers, startIndex)}");在 [執行和偵錯] 檢視上,選取 [ 開始偵錯]。
從 [偵錯控制台] 面板切換至 [終端機] 面板。
在 [終端] 命令提示字元中,輸入 3
程式代碼執行會在斷點暫停。
請花一分鐘的時間檢閱 RUN AND DEBUG 檢視的 VARIABLES 區段。
請注意,
startIndex已指定您輸入的值,也就是3。選取 [逐步執行]。
請注意,變數和 CALL STACK 區段已更新。
CALL STACK 區段顯示程式代碼執行已移至
SumValues方法。列出局部變數的 VARIABLES 區段會顯示整數
n的值。 方法參數n會從方法呼叫自變數startIndex指派其值。 在此情況下,變數名稱的變更會清楚指出已傳遞值,而不是參考指標。備註
在此情況下,您可以在編輯器中看到大部分的程式代碼,因此您可能不需要 CALL STACK 區段,但是當您使用深度巢狀且互連的方法呼叫來處理較大的應用程式時,CALL STACK 區段中所示的執行路徑可能非常實用。
繼續選取 [逐步執行],直到指派給
sum的值不再是0。花一分鐘的時間檢閱 VARIABLES 區段中顯示的資訊。
您應該看到下列內容:
請注意,指派給
sum的值會從0移至4。若要展開
numbers陣列,請選取數位 [int[]]。
回想一下,陣列元素是使用以零起始的索引編號來存取。
在此情況下,邏輯錯誤是使用者介面中的指示與基礎程式代碼之間的差異。 使用者介面指的是陣列項目1到5。 不過,程式代碼會使用使用者輸入的值來存取以零起始的陣列元素。 索引為
3的陣列元素儲存了值4。 程序代碼不會補償以零起始的索引編號。若要終止偵錯會話,請選取 [ 停止]。
請花一分鐘時間考慮如何修正問題。
此問題可在使用者介面中修正,方法是提示使用者輸入介於 0 到 4 之間的值。 在程式代碼中,它也可以藉由從輸入的值減去 1 來加以更正。 一般來說,您的目標應該是清楚且容易遵循的使用者介面。 在此情況下,最好更新程序代碼,如下所示:
Console.WriteLine($"\n\rThe sum of numbers {startIndex} through {numbers.Length} is: {SumValues(numbers, startIndex - 1)}");執行更新的程式代碼會產生下列輸出:
使用建議的方法更新程式代碼,然後儲存Program.cs檔案。
清除斷點、在調試程式中重新執行應用程式,並確認預期的結果會顯示在終端機中。
您剛剛使用變數狀態來識別並修正邏輯問題! 偉大的工作。
監視監看式運算式
WATCH 區段可用來監視以一或多個變數為基礎的表達式。
假設您正在處理在資料集上執行數值計算的應用程式。 您認為當兩個數值變數之間的比率大於 5 時,您的程式代碼會產生不可靠的結果。 您可以使用 WATCH 區段來監視計算的比例。
使用下列程式代碼更新Program.cs檔案:
bool exit = false; var rand = new Random(); int num1 = 5; int num2 = 5; do { num1 = rand.Next(1, 11); num2 = num1 + rand.Next(1, 51); } while (exit == false);儲存您的Program.cs檔案。
在最後一行程式代碼行上設定斷點。
設定下列 WATCH 表示式:
num2 / num1 > 5在 [執行和偵錯] 檢視上,選取 [ 開始偵錯]。
請注意 VARIABLES 和 WATCH 區段中顯示的值。
選取 [繼續],直到您看到「監看式」運算式評估為
true為止。如果「監看式」運算式在第一次反覆項目上評估為
true,請選取 [繼續] 數次,或直到您再次看到true為止。花點時間考慮 WATCH 區段的使用方式。
在此案例中,您判斷當兩個數值變數之間的比率大於 5 時,您的程式代碼會產生不可靠的結果。 您在 WATCH 區段中建構了代表此條件的表達式。 您現在可以使用 WATCH 區段來追蹤該條件。
修改在 VARIABLES 區段中指派給變數的值
有時您可能想要手動建立程序設計條件。 RUN AND DEBUG 檢視的 VARIABLES 區段可讓您藉由在運行時間變更變數的狀態來執行這項作。
花一分鐘的時間檢閱您正在執行的程序代碼。
請注意,程式代碼永遠不會從
do循環中退出,因為exit永遠不會是true。 這不是您在真實世界應用程式中需要改變的程式設計條件,但它示範了功能。在 [變數] 區段中,以滑鼠右鍵按兩下
exit [bool],然後選取 [ 設定值]。VARIABLES 區段可讓您變更在運行時間指派給變數的值。 當您想要查看程式代碼對特定條件的反應時,這非常有用。
若要將 的值
exit設定為true,請輸入 true ,然後按 Enter。在這種情況下,將
exit的值變更為true,會在執行while語句時導致應用程式關閉。選取 [ 繼續]。
請注意,[偵錯控制台] 面板會顯示訊息,通知您程式已結束。
祝賀! 您已成功使用 RUN AND DEBUG 檢視的 VARIABLES 和 WATCH 區段。
回顧
以下為本單元須記住的一些重點:
- 使用 RUN AND DEBUG 檢視的 VARIABLES 區段來監視變數狀態。
- 使用 RUN AND DEBUG 檢視的 WATCH 區段,追蹤不同時間或不同方法的表達式。
- 使用 RUN AND DEBUG 檢視的 CALL STACK 區段來尋找例外狀況或 WATCH 表達式的來源位置。
- 使用 VARIABLES 區段在運行時間變更變數的指派值。