Вправа – налагодження за допомогою коду Visual Studio
Настав час на практиці втілити свої нещодавно придбані налагодити знання. Це ваш перший день на роботі, і настав час покласти ваші навички налагодження .NET для роботи, виправляючи помилку в флагманському продукті компанії, калькуляторі Fibonacci.
Створення зразка проекту .NET для налагодження
Щоб налаштувати код Visual Studio для налагодження .NET, спочатку знадобиться проект .NET. Код Visual Studio містить інтегрований термінал, що спрощує створення нового проекту.
У Коді Visual Studio виберіть Файл>Відкрити папку.
Створіть нову папку з іменем
DotNetDebuggingу вибраному розташуванні. Потім натисніть кнопку Вибрати папку.Відкрийте інтегрований термінал із коду Visual Studio, вибравши Переглянути> терміналу в головному меню.
У вікні термінала скопіюйте та вставте таку команду:
dotnet new consoleЦя команда створює файл Program.cs у папці з уже написаною базовою програмою "Hello World". Він також створює файл проекту C# з іменем DotNetDebugging.csproj.
У вікні термінала скопіюйте та вставте наведену нижче команду, щоб запустити програму "Hello World".
dotnet runВікно термінала відображає "Hello World!" як результат.
Настроювання коду Visual Studio для налагодження .NET
Відкрийте Program.cs , вибравши його.
Під час першого відкриття файлу C# в коді Visual Studio з'явиться запит на інсталяцію рекомендованих розширень для C#. Якщо з'явиться цей запит, натисніть кнопку Інсталювати в запиті.
Visual Studio Code інсталює розширення C# та покаже ще один запит на додавання необхідних активів для побудови та налагодження проекту. Натисніть кнопку Так .
Ви можете закрити вкладку Розширення: C# , щоб зосередитися на коді, який ми налагодимо.
Додавання логіки програми Fibonacci
Наш поточний проект пише повідомлення "Hello World" на консоль, що не дає нам багато налагодити. Натомість ви скористаєтеся короткою програмою .NET, щоб обчислити N-й номер послідовності Fibonacci.
Послідовність Fibonacci – це набір чисел, який починається з чисел 0 і 1, а кожне інше наступне число – це сума двох попередніх. Послідовність продовжується, як показано тут:
0, 1, 1, 2, 3, 5, 8, 13, 21...
Відкрийте Program.cs , вибравши його.
Замініть вміст Program.cs на такий код:
int result = Fibonacci(5); Console.WriteLine(result); static int Fibonacci(int n) { int n1 = 0; int n2 = 1; int sum; for (int i = 2; i < n; i++) { sum = n1 + n2; n1 = n2; n2 = sum; } return n == 0 ? n1 : n2; }Примітка
Цей код містить помилку, яку ми налагодимо пізніше в цьому модулі. Ми не радимо використовувати її в будь-яких критично важливих програмах Fibonacci, доки ми не виправимо цю помилку.
Збережіть файл, натиснувши клавіші Ctrl+S для Windows і Linux. Виберіть Cmd+S для Mac.
Давайте розглянемо, як працює оновлений код, перш ніж налагоджувати його. Запустіть програму, ввівши таку команду в терміналі:
dotnet run
Результат 3 відображається у виводі термінала. Якщо проконсультуватися з цією діаграмою послідовності Fibonacci, яка відображає нульове положення послідовності для кожного значення в дужках, ви побачите, що результат має бути 5. Настав час ознайомитися з налагоджувачем і виправити цю програму.
0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...
Аналіз проблем
Запустіть програму, вибравши ліворуч вкладку Виконати та налагодження , а потім натисніть кнопку Почати налагодження . Можливо, спочатку знадобиться натиснути кнопку Виконати та налагодження , а потім вибрати файл Program.cs .
Програма має швидко завершитися. Це нормально, тому що ви ще не додали жодних точок зупинки.
Якщо консоль налагодження не відображається, натисніть клавіші Ctrl+Shift+Y для Windows і Linux або Cmd+Shift+Y для Mac. У кінці мають відображатися кілька рядків діагностичних відомостей, а потім такі рядки:
... Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Threading.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Text.Encoding.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 3 The program '[88820] DotNetDebugging.dll' has exited with code 0 (0x0).
У рядках у верхній частині відображається повідомлення про те, що параметри налагодження за замовчуванням дозволяють параметр "Лише мій код". Це означає, що налагоджувач налагодить код і не ввійде у вихідний код для .NET, якщо ви не вимкнете цей режим. Цей параметр дає змогу зосередитися на налагодженні коду.
У кінці виходу консолі налагодження відобразиться програма пише 3 на консоль, а потім завершує роботу з кодом 0. Зазвичай код виходу програми з 0 вказує на те, що програма запускається та завершується без аварійного завершення роботи. Однак існує різниця між аварійним завершенням роботи та поверненням правильного значення. У цьому випадку ми попросили програму обчислити п'яте значення послідовності Fibonacci:
0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...
П'яте значення в цьому списку – 5, але наша програма повернула 3. Діагностуйте та виправимо цю помилку за допомогою налагоджувача.
Використання точок зупинки та покрокового виконання
Додайте точку зупинки, клацнувши ліве поле в рядку 1 на
int result = Fibonacci(5);.
Знову почніть налагодження. Програма почне виконуватися. Він розриває (призупиняє виконання) у рядку 1 через встановлену точку зупинки. Використовуйте елементи керування налагоджувача, щоб увійти у
Fibonacci()функцію.
Перевірка стану змінних
Тепер перевірте значення різних змінних за допомогою панелі Змінні .
- Яке значення відображається для
nпараметра? - На початку виконання функції відображаються значення для локальних
n1змінних ,n2іsum?
Далі ми переступимо до
forциклу за допомогою елемента керування налагоджувача Крок за кроком .
Продовжуйте просуватися, доки не потрапите в перший рядок усередині
forциклу, у рядку, який читає:sum = n1 + n2;
Примітка
Можливо, ви помітили, що для переміщення рядком for(...) {} потрібно виконати кілька кроків у командах. Ця ситуація виникає, тому що є кілька операторів в цьому рядку. Під час виконання кроку ви переходите до наступної інструкції в коді. Зазвичай в одному рядку є одна інструкція. Якщо це не так, потрібно виконати кілька кроків, щоб перейти до наступного рядка.
Подумайте про код
Важлива частина налагодження полягає в тому, щоб зупинити і прийняти деякі обґрунтовані припущення про те, що, на вашу думку, намагаються зробити частини коду (як функції, так і блоки, такі як цикли). Це нормально, якщо ви не впевнені, що це частина процесу налагодження. Але активна участь у процесі налагодження допоможе вам знайти помилки набагато швидше.
Перш ніж копати далі, давайте пам'ятати, що послідовність Fibonacci – це ряд чисел, які починаються з чисел 0 і 1, а кожне інше наступне число – це сума двох попередніх.
Це означає, що:
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1 (0 + 1)
Fibonacci(3) = 2 (1 + 1)
Fibonacci(4) = 3 (1 + 2)
Fibonacci(5) = 5 (2 + 3)
Розуміючи, що визначення і дивлячись на цей for цикл, ми можемо вивести це:
- Цикл рахується від 2 до
n(номер послідовності Fibonacci, який ми шукаємо). - Якщо
nменше 2, цикл ніколи не запуститься. Операторreturnу кінці функції поверне 0, якщоn0, а 1 – 1 , якщоn1 або 2. Це нульові, перші та другі значення в ряді Fibonacci за визначенням. - Більш цікавим є випадок, коли
nбільше 2. У таких випадках поточне значення визначається як сума двох попередніх значень. Таким чином,n1для цього циклу, іn2є попередніми двома значеннями, іsumє значенням для поточної ітерації. Через це щоразу, коли ми з'ясовуємо суму двох попередніх значень і встановлюємо для нихsumзначення , ми оновлюємо нашіn1таn2значення.
Гаразд, нам не потрібно переосмислювати це минуле. Ми можемо трохи спертися на наш налагоджувач. Але варто подумати про код, щоб побачити, чи він робить те, що ми очікуємо, і бути більш поінформованим, коли він не робить.
Пошук помилки з точками зупинки
Проходження коду може бути корисним, але нудним, особливо якщо ви працюєте з циклами або іншим кодом, який викликається кілька разів. Замість того, щоб переходити циклом знову і знову, ми можемо встановити нову точку зупинки на першому рядку циклу.
Коли ми робимо це, важливо бути стратегічним про те, де ми поставили наші точки зупинки. Нас особливо цікавить значення sum, оскільки воно представляє поточне максимальне значення Fibonacci. Через це давайте поставимо нашу точку зупинки на лінію післяsum встановлення.
Додайте другу точку зупинки в рядку 13.
Примітка
Якщо ви помітили, що ви продовжуєте працювати з кодом, а потім крокуєте лінією або двома лініями, ви можете легко оновити точки зупинки до більш ефективних ліній.
Тепер, коли ми маємо хороший набір точок зупинки в циклі, використовуйте елемент керування Continue debugger, щоб перейти до точки зупинки. У наших локальних змінних відображаються такі рядки:
n [int]: 5 n1 [int]: 0 n2 [int]: 1 sum [int]: 1 i [int]: 2Усі ці рядки здаються правильними. Перший цикл
sumіз двох попередніх значень – 1. Замість того, щоб переходити через лінію за рядком, ми можемо скористатися нашими точками зупинки, щоб перейти до наступного разу через петлю.Натисніть кнопку Продовжити , щоб продовжити передавання програми, доки не потрапить наступна точка зупинки, яка перебуватиме на наступному проході через цикл.
Примітка
Не турбуйтеся про пропуск через помилку під час використання функції "Продовжити". Слід очікувати, що ви часто налагоджуватимете код кілька разів, щоб знайти проблему. Часто це швидше, щоб працювати через нього кілька разів, на відміну від того, занадто обережно, коли ви проходите.
Цього разу відображаються такі значення:
n [int]: 5 n1 [int]: 1 n2 [int]: 1 sum [int]: 2 i [int]: 3Давайте подумаймо про це. Чи мають ці значення сенс? Схоже, вони роблять. Для третього номера Fibonacci ми очікуємо побачити наші
sumрівні 2, і це так.Гаразд, давайте переглянемо кнопку Продовжити , щоб знову зацикити його.
n [int]: 5 n1 [int]: 1 n2 [int]: 2 sum [int]: 3 i [int]: 4Знову ж таки, все виглядає добре. Четверте значення в ряді, як очікується, буде 3.
На цьому етапі ви можете почати цікавитися, чи правильно вказано код, і ви уявили собі помилку! Давайте продовжимо з ним в останній раз через цикл. Натисніть кнопку Продовжити ще раз.
Зачекай хвилинку. Програму завершено та надруковано 3! Це неправильно.
Гаразд, не хвилюйтеся. Ми не зазнали невдачі, ми дізналися. Тепер ми знаємо, що код проходить через цикл правильно, поки не
iдорівнює 4, але потім він виходить, перш ніж обчислити остаточне значення. Я починаю отримувати деякі ідеї про те, де помилка. Ти?Давайте встановимо ще одну точку зупинки в рядку 17, яка ознайомиться з:
return n == 0 ? n1 : n2;Ця точка зупинки дасть змогу перевірити стан програми до виходу функції. Ми вже дізналися все, що ми можемо очікувати від наших попередніх точок зупинки в рядках 1 і 13, так що ми можемо очистити їх.
Видаліть попередні точки зупинки в рядках 1 і 13. Це можна зробити, клацнувши їх на полі поруч із номерами рядків або знявши прапорці точки зупинки для рядків 1 і 13 в області Точки зупинки в нижньому лівому куті.
Тепер, коли ми розуміємо, що відбувається набагато краще, і встановили точку зупинки, призначену, щоб зловити нашу програму в акті неналежної поведінки, ми повинні бути в змозі зловити цю помилку!
Запустіть налагоджувач в останній раз.
n [int]: 5 n1 [int]: 2 n2 [int]: 3 sum [int]: 3Ну, це не правильно. Ми спеціально попросили Fibonacci(5), і ми отримали Fibonacci(4). Ця функція повертає
n2, і кожна ітерація циклу обчислює значення та набориsumn2дорівнюєsum.Виходячи з цієї інформації та нашого попереднього запуску налагодження, ми можемо бачити, що цикл вийшов, коли
iбуло 4, а не 5.Погляньмо на першу лінію
forциклу трохи ближче.for (int i = 2; i < n; i++)Гаразд, зачекайте хвилинку! Це означає, що він вийде, як тільки верхній частині циклу бачить, що
iбільше не меншеn. Це означає, що код циклу не буде запущено для випадку, колиiдорівнюєn. Схоже, що ми хотіли, щоб запустити доi <= n, замість цього:for (int i = 2; i <= n; i++)Отже, після цієї зміни оновлена програма має виглядати так:
int result = Fibonacci(5); Console.WriteLine(result); static int Fibonacci(int n) { int n1 = 0; int n2 = 1; int sum; for (int i = 2; i <= n; i++) { sum = n1 + n2; n1 = n2; n2 = sum; } return n == 0 ? n1 : n2; }Зупиніть сеанс налагодження, якщо ви ще цього не зробили.
Потім внесіть попередні зміни до рядка 10 і залиште нашу точку зупинки в рядку 17.
Перезапустіть налагоджувач. Цього разу, коли ми потрапили в точку зупинки в рядку 17, з'являться такі значення:
n [int]: 5 n1 [int]: 3 n2 [int]: 5 sum [int]: 5Салют! Схоже, ми отримали його! Чудова робота, ви зберегли день для Fibonacci, Inc.!
Натисніть кнопку Продовжити , щоб переконатися, що програма повертає правильне значення.
5 The program '[105260] DotNetDebugging.dll' has exited with code 0 (0x0).І це повертає правильний результат.
Ви впоралися! Ви налагодили код, який ви не писали за допомогою налагоджувача .NET у коді Visual Studio.
У наступній одиниці ви дізнаєтеся, як полегшити налагодження коду за допомогою вбудованих у .NET функцій журналювання та трасування.