Debugowanie — znajdź przyczynę, nie zgaduj
Program uruchamia się, ale podaje złą średnią. To dobry moment, by nauczyć się obserwować wykonanie i dobierać dane testowe.
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.
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 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.
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);
}
}
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.
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
- 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
Usuń rzutowanie (double), uruchom testy i znajdź pierwszy błąd.
Sprawdź: Pierwszy test daje False; po przywróceniu rzutowania True.
Dodaj test dla { -3, -4 }.
Sprawdź: Średnia wynosi -3.5.
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.
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.