Вправа – налагодження за допомогою коду Visual Studio

Завершено

Настав час на практиці втілити свої нещодавно придбані налагодити знання. Це ваш перший день на роботі, і настав час покласти ваші навички налагодження .NET для роботи, виправляючи помилку в флагманському продукті компанії, калькуляторі Fibonacci.

Створення зразка проекту .NET для налагодження

Щоб налаштувати код Visual Studio для налагодження .NET, спочатку знадобиться проект .NET. Код Visual Studio містить інтегрований термінал, що спрощує створення нового проекту.

  1. У Коді Visual Studio виберіть Файл>Відкрити папку.

  2. Створіть нову папку з іменем DotNetDebugging у вибраному розташуванні. Потім натисніть кнопку Вибрати папку.

  3. Відкрийте інтегрований термінал із коду Visual Studio, вибравши Переглянути> терміналу в головному меню.

  4. У вікні термінала скопіюйте та вставте таку команду:

    dotnet new console
    

    Ця команда створює файл Program.cs у папці з уже написаною базовою програмою "Hello World". Він також створює файл проекту C# з іменем DotNetDebugging.csproj.

  5. У вікні термінала скопіюйте та вставте наведену нижче команду, щоб запустити програму "Hello World".

    dotnet run
    

    Вікно термінала відображає "Hello World!" як результат.

Настроювання коду Visual Studio для налагодження .NET

  1. Відкрийте Program.cs , вибравши його.

  2. Під час першого відкриття файлу C# в коді Visual Studio з'явиться запит на інсталяцію рекомендованих розширень для C#. Якщо з'явиться цей запит, натисніть кнопку Інсталювати в запиті.

    screenshot of Visual Studio Code prompt to install the C# extension.

  3. Visual Studio Code інсталює розширення C# та покаже ще один запит на додавання необхідних активів для побудови та налагодження проекту. Натисніть кнопку Так .

    знімок екрана із запитом на додавання необхідних активів для створення та налагодження проекту .NET.

  4. Ви можете закрити вкладку Розширення: C# , щоб зосередитися на коді, який ми налагодимо.

Додавання логіки програми Fibonacci

Наш поточний проект пише повідомлення "Hello World" на консоль, що не дає нам багато налагодити. Натомість ви скористаєтеся короткою програмою .NET, щоб обчислити N-й номер послідовності Fibonacci.

Послідовність Fibonacci – це набір чисел, який починається з чисел 0 і 1, а кожне інше наступне число – це сума двох попередніх. Послідовність продовжується, як показано тут:

0, 1, 1, 2, 3, 5, 8, 13, 21...
  1. Відкрийте Program.cs , вибравши його.

  2. Замініть вміст 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, доки ми не виправимо цю помилку.

  3. Збережіть файл, натиснувши клавіші Ctrl+S для Windows і Linux. Виберіть Cmd+S для Mac.

  4. Давайте розглянемо, як працює оновлений код, перш ніж налагоджувати його. Запустіть програму, ввівши таку команду в терміналі:

    dotnet run
    

    Вікно термінала зі зміненим виходом програми.

  5. Результат 3 відображається у виводі термінала. Якщо проконсультуватися з цією діаграмою послідовності Fibonacci, яка відображає нульове положення послідовності для кожного значення в дужках, ви побачите, що результат має бути 5. Настав час ознайомитися з налагоджувачем і виправити цю програму.

    0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...
    

Аналіз проблем

  1. Запустіть програму, вибравши ліворуч вкладку Виконати та налагодження , а потім натисніть кнопку Почати налагодження . Можливо, спочатку знадобиться натиснути кнопку Виконати та налагодження , а потім вибрати файл Program.cs .

    Знімок екрана: кнопка

    Програма має швидко завершитися. Це нормально, тому що ви ще не додали жодних точок зупинки.

  2. Якщо консоль налагодження не відображається, натисніть клавіші 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. Додайте точку зупинки, клацнувши ліве поле в рядку 1 на int result = Fibonacci(5);.

    Знімок екрана: розташування точки зупинки в коді.

  2. Знову почніть налагодження. Програма почне виконуватися. Він розриває (призупиняє виконання) у рядку 1 через встановлену точку зупинки. Використовуйте елементи керування налагоджувача, щоб увійти у Fibonacci() функцію.

    Знімок екрана: кнопка Крок у.

Перевірка стану змінних

Тепер перевірте значення різних змінних за допомогою панелі Змінні .

Знімок екрана: панель змінних.

  • Яке значення відображається для n параметра?
  • На початку виконання функції відображаються значення для локальних n1змінних , n2і sum?
  1. Далі ми переступимо до for циклу за допомогою елемента керування налагоджувача Крок за кроком .

    Знімок екрана: кнопка

  2. Продовжуйте просуватися, доки не потрапите в перший рядок усередині 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 цикл, ми можемо вивести це:

  1. Цикл рахується від 2 до n (номер послідовності Fibonacci, який ми шукаємо).
  2. Якщо n менше 2, цикл ніколи не запуститься. Оператор return у кінці функції поверне 0, якщо n 0, а 1 – 1 , якщо n 1 або 2. Це нульові, перші та другі значення в ряді Fibonacci за визначенням.
  3. Більш цікавим є випадок, коли n більше 2. У таких випадках поточне значення визначається як сума двох попередніх значень. Таким чином, n1 для цього циклу, і n2 є попередніми двома значеннями, і sum є значенням для поточної ітерації. Через це щоразу, коли ми з'ясовуємо суму двох попередніх значень і встановлюємо для них sumзначення , ми оновлюємо наші n1 та n2 значення.

Гаразд, нам не потрібно переосмислювати це минуле. Ми можемо трохи спертися на наш налагоджувач. Але варто подумати про код, щоб побачити, чи він робить те, що ми очікуємо, і бути більш поінформованим, коли він не робить.

Пошук помилки з точками зупинки

Проходження коду може бути корисним, але нудним, особливо якщо ви працюєте з циклами або іншим кодом, який викликається кілька разів. Замість того, щоб переходити циклом знову і знову, ми можемо встановити нову точку зупинки на першому рядку циклу.

Коли ми робимо це, важливо бути стратегічним про те, де ми поставили наші точки зупинки. Нас особливо цікавить значення sum, оскільки воно представляє поточне максимальне значення Fibonacci. Через це давайте поставимо нашу точку зупинки на лінію післяsum встановлення.

  1. Додайте другу точку зупинки в рядку 13.

    Знімок екрана: другий набір точок зупинки.

    Примітка

    Якщо ви помітили, що ви продовжуєте працювати з кодом, а потім крокуєте лінією або двома лініями, ви можете легко оновити точки зупинки до більш ефективних ліній.

  2. Тепер, коли ми маємо хороший набір точок зупинки в циклі, використовуйте елемент керування Continue debugger, щоб перейти до точки зупинки. У наших локальних змінних відображаються такі рядки:

    n [int]: 5
    n1 [int]: 0
    n2 [int]: 1
    sum [int]: 1
    i [int]: 2
    

    Усі ці рядки здаються правильними. Перший цикл sum із двох попередніх значень – 1. Замість того, щоб переходити через лінію за рядком, ми можемо скористатися нашими точками зупинки, щоб перейти до наступного разу через петлю.

  3. Натисніть кнопку Продовжити , щоб продовжити передавання програми, доки не потрапить наступна точка зупинки, яка перебуватиме на наступному проході через цикл.

    Примітка

    Не турбуйтеся про пропуск через помилку під час використання функції "Продовжити". Слід очікувати, що ви часто налагоджуватимете код кілька разів, щоб знайти проблему. Часто це швидше, щоб працювати через нього кілька разів, на відміну від того, занадто обережно, коли ви проходите.

    Цього разу відображаються такі значення:

    n [int]: 5
    n1 [int]: 1
    n2 [int]: 1
    sum [int]: 2
    i [int]: 3
    

    Давайте подумаймо про це. Чи мають ці значення сенс? Схоже, вони роблять. Для третього номера Fibonacci ми очікуємо побачити наші sum рівні 2, і це так.

  4. Гаразд, давайте переглянемо кнопку Продовжити , щоб знову зацикити його.

    n [int]: 5
    n1 [int]: 1
    n2 [int]: 2
    sum [int]: 3
    i [int]: 4
    

    Знову ж таки, все виглядає добре. Четверте значення в ряді, як очікується, буде 3.

  5. На цьому етапі ви можете почати цікавитися, чи правильно вказано код, і ви уявили собі помилку! Давайте продовжимо з ним в останній раз через цикл. Натисніть кнопку Продовжити ще раз.

    Зачекай хвилинку. Програму завершено та надруковано 3! Це неправильно.

    Гаразд, не хвилюйтеся. Ми не зазнали невдачі, ми дізналися. Тепер ми знаємо, що код проходить через цикл правильно, поки не i дорівнює 4, але потім він виходить, перш ніж обчислити остаточне значення. Я починаю отримувати деякі ідеї про те, де помилка. Ти?

  6. Давайте встановимо ще одну точку зупинки в рядку 17, яка ознайомиться з:

    return n == 0 ? n1 : n2;
    

    Ця точка зупинки дасть змогу перевірити стан програми до виходу функції. Ми вже дізналися все, що ми можемо очікувати від наших попередніх точок зупинки в рядках 1 і 13, так що ми можемо очистити їх.

  7. Видаліть попередні точки зупинки в рядках 1 і 13. Це можна зробити, клацнувши їх на полі поруч із номерами рядків або знявши прапорці точки зупинки для рядків 1 і 13 в області Точки зупинки в нижньому лівому куті.

    Знімок екрана: точки зупинки, перелічені в області

    Тепер, коли ми розуміємо, що відбувається набагато краще, і встановили точку зупинки, призначену, щоб зловити нашу програму в акті неналежної поведінки, ми повинні бути в змозі зловити цю помилку!

  8. Запустіть налагоджувач в останній раз.

    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;
    }
    
  9. Зупиніть сеанс налагодження, якщо ви ще цього не зробили.

  10. Потім внесіть попередні зміни до рядка 10 і залиште нашу точку зупинки в рядку 17.

  11. Перезапустіть налагоджувач. Цього разу, коли ми потрапили в точку зупинки в рядку 17, з'являться такі значення:

    n [int]: 5
    n1 [int]: 3
    n2 [int]: 5
    sum [int]: 5
    

    Салют! Схоже, ми отримали його! Чудова робота, ви зберегли день для Fibonacci, Inc.!

  12. Натисніть кнопку Продовжити , щоб переконатися, що програма повертає правильне значення.

    5
    The program '[105260] DotNetDebugging.dll' has exited with code 0 (0x0).
    

    І це повертає правильний результат.

Ви впоралися! Ви налагодили код, який ви не писали за допомогою налагоджувача .NET у коді Visual Studio.

У наступній одиниці ви дізнаєтеся, як полегшити налагодження коду за допомогою вбудованих у .NET функцій журналювання та трасування.