Debugowanie — znajdź przyczynę, nie zgaduj

Program uruchamia się, ale podaje złą średnią. To dobry moment, by nauczyć się obserwować wykonanie i dobierać dane testowe.

C#Technikum
CEL LEKCJI

Czego się dziś nauczysz

  • Odróżnisz błąd kompilacji, wykonania i logiki.
  • Prześledzisz zmienne w debuggerze.
  • Dobierzesz przypadki zwykłe i brzegowe.

Przygotowanie: lekcje 01–54. Przewidywany czas: 45–90 minut z zadaniami. Przykłady wymagają .NET 8 lub nowszego, z włączonymi ImplicitUsings i Nullable.

TEORIA

Wyjaśnienie krok po kroku

Trzy rodzaje problemów

Błąd kompilacji uniemożliwia zbudowanie programu. Wyjątek pojawia się podczas wykonania. Błąd logiki może dawać niepoprawny wynik bez żadnego komunikatu. Średnia wyliczona dzieleniem całkowitym to właśnie taki przypadek.

Punkt wstrzymania

W Visual Studio kliknij margines obok instrukcji albo użyj polecenia wstawienia punktu wstrzymania. Uruchom z debugowaniem, a gdy program się zatrzyma, sprawdź zmienne w oknie lokalnych. Wykonuj kolejne instrukcje poleceniem Step Over. Nazwy i skróty mogą zależeć od ustawień IDE.

Przypadki testowe

Dla średniej sprawdź jedną ocenę, kilka ocen oraz pustą tablicę. Oczekiwany wynik oblicz niezależnie, zanim uruchomisz program. Jeśli dane są puste, metoda w tej lekcji zwraca null: brak średniej to nie średnia zero.

PRZYKŁAD

Przykład do zbadania

Wklej cały przykład do nowego projektu konsolowego jako Program.cs. Zastąp poprzednią zawartość pliku. Nie łącz kilku całych programów w jednym pliku.

Program.cs — cały plik
using System;
class Program
{
    static double? Srednia(int[] liczby)
    {
        if (liczby.Length == 0) return null;
        long suma = 0;
        foreach (int liczba in liczby) suma += liczba;
        return (double)suma / liczby.Length;
    }
    static void Main()
    {
        Console.WriteLine(Srednia(new int[] { 3, 4 }) == 3.5);
        Console.WriteLine(Srednia(new int[] { 5 }) == 5.0);
        Console.WriteLine(Srednia(new int[0]) == null);
    }
}
Oczekiwany wynik
True
True
True

Co dzieje się po kolei

  • Rzutowanie przed dzieleniem zachowuje część ułamkową.
  • Pusta tablica jest obsłużona przed dzieleniem przez jej długość.
  • Te trzy proste sprawdzenia są ćwiczeniem testowania; pełne projekty zwykle korzystają z frameworka testowego. 3.5 i 5.0 są tu reprezentowane dokładnie; dla innych obliczeń double może być potrzebna tolerancja.

Pobierz Program.cs

ELEMENTY WBUDOWANE

Użyte w tej lekcji elementy

Metody .NET są gotowymi narzędziami biblioteki. Instrukcje języka i nasze metody oznaczamy osobno. Właściwości, np. Length, odczytujemy bez nawiasów.

Element Wynik Działanie i ograniczenia
Srednia(liczby) double? Nasza metoda: średnia albo null dla pustej tablicy. Zakładamy nie-null tablicę liczb.
Console.WriteLine(wartosc) void Wyświetla, czy wynik zgadza się z oczekiwaniem.
CZĘSTE BŁĘDY

Częste błędy

  • Nie poprawiaj kodu bez przykładu, który odtwarza błąd.
  • Jedno udane uruchomienie nie sprawdza wszystkich danych.
  • Zaokrąglenie wyniku na ekranie nie naprawia dzielenia całkowitego.

Od sprawdzania do testowania

Trzy porównania wypisane na ekran to ćwiczenie. Prawdziwy zestaw testów uruchamiany jednym poleceniem opisuje lekcja 56.

Optymalizacja: najpierw zmierz

Optymalizowanie kodu „na oko” zwykle psuje czytelność i nic nie przyspiesza. Kolejność jest zawsze ta sama: (1) sprawdź, czy program w ogóle działa poprawnie — testy z lekcji 56; (2) zmierz, co trwa długo, klasą Stopwatch albo profilerem wbudowanym w Visual Studio; (3) popraw algorytm, bo zejście z O(n²) do O(n log n) daje więcej niż jakakolwiek sztuczka składniowa (lekcja 28); (4) dopiero na końcu szczegóły: StringBuilder zamiast sklejania w pętli, wstępny rozmiar kolekcji, mniej alokacji. Po każdej zmianie uruchom testy i zmierz ponownie.

ZADANIA

Zadania

ZAD 1Zepsuj i napraw★☆☆

Usuń rzutowanie (double), uruchom testy i znajdź pierwszy błąd.

Sprawdź: Pierwszy test daje False; po przywróceniu rzutowania True.

ZAD 2Przypadek ujemny★★☆

Dodaj test dla { -3, -4 }.

Sprawdź: Średnia wynosi -3.5.

ZAD 3Magazyn pod lupą★★★

Napisz klasę Magazyn z polem stan ustawianym w konstruktorze oraz metodą bool Pobierz(int ile), która zmniejsza stan i zwraca true, a przy braku towaru zwraca false i nie zmienia stanu. Uruchom program pod debuggerem i prześledź trzy sytuacje: stan początkowy, pobranie całości i kolejne pobranie z pustego magazynu.

Sprawdź: po pobraniu całości stan wynosi 0, a dalsze pobranie zwraca false i zostawia stan bez zmian.

PODSUMOWANIE

Sprawdź, czy rozumiesz

Wyjaśnij własnymi słowami, jak działa główny przykład i dlaczego daje taki wynik. Następnie zmień jedną daną i przewidź wynik przed uruchomieniem. Wróć do celów lekcji i sprawdź, które potrafisz już wykonać samodzielnie.

Dokumentacja: Microsoft Learn — temat tej lekcji.