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

Завершено

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

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

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

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

  2. У діалоговому вікні Створення нового проекту виберіть консольну програму та натисніть кнопку Далі.

  3. Назвіть проект DotNetDebugging і виберіть розташування, де потрібно зберегти проект. Залиште інші значення за замовчуванням, а потім натисніть кнопку Далі.

  4. Натисніть кнопку Створити на останньому екрані.

Visual Studio створює проект Console для нас за допомогою вибраного шаблону. Коли проект завантажиться, відкрийте Program.cs , вибравши його.

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

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

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

0, 1, 1, 2, 3, 5, 8, 13, 21...

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

  1. Замініть вміст Program.cs на такий код:
int result = Fibonacci(5);
Console.WriteLine(result);

static int Fibonacci(int n)
{
    Console.WriteLine("The output is: ");
    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, доки ми не виправимо цю помилку.

  1. Збережіть файл за допомогою клавіш Ctrl+S для Windows і Linux. Виберіть Cmd+S для Mac.

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

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

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

У цьому випадку ми попросили програму обчислити п'яте значення послідовності Fibonacci:

0, 1, 1, 2, 3, 5, 8, 13, 21...

П'яте значення в цьому списку – 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 , якщо n 1 або 2. Ці значення є нульовими, першими та другими значеннями в ряді Fibonacci за визначенням.
  3. Більш цікавим є випадок, коли n більше 2. У таких випадках поточне значення визначається як сума двох попередніх значень. Таким чином, n1 для цього циклу, і n2 є попередніми двома значеннями, і sum є значенням для поточної ітерації. Через цю логіку щоразу, коли ми з'ясовуємо суму двох попередніх значень і встановлюємо для неї sumзначення , ми оновлюємо наші n1 та n2 значення.

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

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

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

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

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

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

    Примітка

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

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

    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. Давайте встановимо ще одну точку зупинки в рядку 18, яка ознайомиться з:

    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)
    {
        Console.WriteLine("The output is: ");
        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. Внесіть попередні зміни до рядка 11 і залиште точку зупинки в рядку 18.

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

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

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

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

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

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

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

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