Przejdź do treści
School IT / Przestrzeń do nauki
← C# od podstawLekcja 16 z 58

Pętle while i do-while

Instrukcja warunkowa pozwala coś pominąć. Pętla pozwala coś powtórzyć — tyle razy, ile trzeba, i tyle razy, ile z góry nie wiadomo. To dzięki niej program może pytać o dane do skutku, liczyć sumę wprowadzanych liczb albo działać, dopóki użytkownik nie wybierze „koniec”.

C# while do-while 50 min
CEL LEKCJI

Czego się dziś nauczysz

  • Powtórzysz fragment kodu, dopóki warunek jest spełniony
  • Napiszesz pętlę, która pyta o dane tak długo, aż użytkownik wpisze poprawną wartość
  • Odróżnisz while od do-while i wybierzesz właściwą
  • Zsumujesz i policzysz nieznaną z góry liczbę wprowadzonych wartości
  • Rozpoznasz i naprawisz pętlę nieskończoną
TEORIA

Pętla while

Pętla while wygląda dokładnie jak if — z jedną różnicą: po wykonaniu bloku wraca i sprawdza warunek jeszcze raz. I jeszcze raz. Dopóki warunek jest prawdziwy.

składnia
while (warunek)
{
    // instrukcje powtarzane, dopoki warunek jest prawdziwy
}
Program.cs
int i = 1;

while (i <= 5)
{
    Console.WriteLine($"Powtorzenie numer {i}");
    i++;
}

Console.WriteLine("Koniec petli.");
wynik w konsoli
Powtorzenie numer 1
Powtorzenie numer 2
Powtorzenie numer 3
Powtorzenie numer 4
Powtorzenie numer 5
Koniec petli.

Co się dzieje krok po kroku

KrokWartość iWarunek i <= 5Działanie
11prawdawypisuje „1″, zwiększa i do 2
22prawdawypisuje „2″, zwiększa i do 3
33prawdawypisuje „3″, zwiększa i do 4
44prawdawypisuje „4″, zwiększa i do 5
55prawdawypisuje „5″, zwiększa i do 6
66fałszpętla się kończy, program idzie dalej

Warunek sprawdzany jest przed każdym obiegiem

Także przed pierwszym. Gdyby i startowało od 10, warunek 10 <= 5 byłby od razu fałszywy i blok nie wykonałby się ani razu. To ważna cecha while — potrafi wykonać się zero razy.

TEORIA

Trzy rzeczy, o których trzeba pamiętać

Każda poprawna pętla while ma trzy elementy. Brak któregokolwiek to gotowy błąd:

Program.cs
int i = 1;              // 1. przygotowanie - wartosc poczatkowa

while (i <= 5)          // 2. warunek - kiedy powtarzac
{
    Console.WriteLine(i);
    i++;                // 3. zmiana - to, co w koncu unieważni warunek
}
ElementGdy go brakujeObjaw
przygotowanie zmienna nie istnieje albo nie ma wartości błąd kompilacji CS0103 lub CS0165
warunek warunek jest od początku fałszywy pętla nie wykonuje się ani razu — łatwo tego nie zauważyć
zmiana nic nie zmienia wartości sprawdzanej w warunku pętla nieskończona — program się zawiesza

Zmiana musi dotyczyć zmiennej z warunku

To nie wystarczy, że w pętli „coś się dzieje”. Musi zmieniać się dokładnie ta wartość, którą sprawdza warunek. Zwiększanie zmiennej suma, gdy warunek patrzy na i, nie zakończy pętli nigdy.

TEORIA

Pętla nieskończona

Prędzej czy później napiszesz taką pętlę przez pomyłkę. Warto wiedzieć, jak wygląda i co wtedy zrobić.

trzy sposoby na zawieszenie programu
// 1. brak zmiany licznika
int i = 1;
while (i <= 5)
{
    Console.WriteLine(i);      // i nigdy nie rosnie
}

// 2. srednik po warunku
int j = 1;
while (j <= 5);                // pusta instrukcja - petla bez tresci
{
    Console.WriteLine(j);
    j++;
}

// 3. zmiana w zla strone
int k = 5;
while (k > 0)
{
    Console.WriteLine(k);
    k++;                       // rosnie, a warunek czeka na zejscie do zera
}

Jak przerwać zawieszony program

W oknie konsoli naciśnij Ctrl + C. W Visual Studio zatrzymaj debugowanie kwadratowym przyciskiem „Stop” (albo Shift + F5). Jeśli program wypisuje coś w pętli, konsola potrafi zapchać się tysiącami linii w sekundę — im szybciej zareagujesz, tym lepiej.

Pętla nieskończona bywa celowa

Program z menu ma działać, dopóki użytkownik nie wybierze wyjścia. Wtedy pisze się pętlę bez warunku końcowego i przerywa ją instrukcją break — poznasz ją dokładniej w lekcji 18:

Program.cs
while (true)
{
    Console.Write("Polecenie (koniec = zamknij): ");
    string polecenie = (Console.ReadLine() ?? "").Trim().ToLower();

    if (polecenie == "koniec")
    {
        break;              // jedyne wyjscie z tej petli
    }

    Console.WriteLine($"Wykonuje: {polecenie}");
}

Taka pętla jest bezpieczna, o ile widzisz instrukcję break i jesteś pewien, że da się do niej dojść. Jeśli warunek wyjścia da się zapisać wprost w nawiasie while, zrób to — czyta się to lepiej.

TEORIA

Pętla do-while

Różnica jest jedna, ale zmienia wszystko: warunek sprawdzany jest po wykonaniu bloku. Dzięki temu blok wykona się co najmniej raz, choćby warunek był od początku fałszywy.

składnia
do
{
    // instrukcje - wykonaja sie przynajmniej raz
}
while (warunek);        // UWAGA: sredniki na koncu
Program.cs
int i = 10;

Console.WriteLine("--- while ---");
while (i <= 5)
{
    Console.WriteLine($"while: {i}");
    i++;
}

int j = 10;

Console.WriteLine("--- do-while ---");
do
{
    Console.WriteLine($"do-while: {j}");
    j++;
}
while (j <= 5);
wynik w konsoli
--- while ---
--- do-while ---
do-while: 10

Pętla while nie wykonała się ani razu, bo warunek 10 <= 5 jest fałszywy od początku. Pętla do-while zdążyła wykonać się raz, zanim sprawdziła ten sam warunek.

Cechawhiledo-while
Warunek sprawdzanyprzed każdym obiegiempo każdym obiegu
Minimalna liczba obiegówzerojeden
Średnik na końcunie majest, po nawiasie warunku
Typowe zastosowanieprzetwarzanie danych, których może nie byćmenu, pytanie o dane — coś, co trzeba zrobić raz, zanim jest o co pytać

Jak wybrać

Zadaj sobie pytanie: czy jest sens wykonać ten blok choć raz, zanim cokolwiek sprawdzę? Przy pytaniu użytkownika o dane — tak, przecież najpierw trzeba zapytać. To do-while. Przy „wypisz pozostałe pozycje z listy” — niekoniecznie, lista może być pusta. To while.

TEORIA

Wzorzec: pytanie do skutku

To obiecany w lekcji 12 brakujący fragment. Do tej pory program przy błędnych danych po prostu się kończył. Teraz będzie pytał tak długo, aż dostanie to, czego potrzebuje.

Program.cs
int wiek;
bool poprawny;

do
{
    Console.Write("Podaj wiek (0-120): ");
    bool ok = int.TryParse(Console.ReadLine(), out wiek);

    poprawny = ok && wiek >= 0 && wiek <= 120;

    if (!poprawny)
    {
        Console.WriteLine("  To nie jest poprawny wiek. Sprobuj jeszcze raz.");
    }
}
while (!poprawny);

Console.WriteLine($"Dziekuje. Zapisany wiek: {wiek}");
wynik w konsoli
Podaj wiek (0-120): dwadziescia
  To nie jest poprawny wiek. Sprobuj jeszcze raz.
Podaj wiek (0-120): -5
  To nie jest poprawny wiek. Sprobuj jeszcze raz.
Podaj wiek (0-120): 17
Dziekuje. Zapisany wiek: 17

Dlaczego akurat tak

FragmentUzasadnienie
int wiek; przed pętlą Zmienna musi przeżyć zakończenie pętli, bo używamy jej w ostatniej linii. Zadeklarowana wewnątrz bloku znikłaby razem z klamrą.
out wiek, a nie out int wiek Zmienna już istnieje, więc nie deklarujemy jej ponownie. Zapis out int wiek wewnątrz pętli utworzyłby drugą, lokalną zmienną i pierwsza zostałaby pusta.
do-while, a nie while Zanim cokolwiek sprawdzimy, musimy najpierw zapytać. Wersja z while wymagałaby sztucznego ustawienia poprawny = false przed pętlą.
ok && wiek >= 0 && ... Skrócone obliczanie z lekcji 10: gdy ok jest fałszywe, reszta warunku nie jest nawet sprawdzana. To ważne, bo po nieudanej konwersji wiek zawiera zero, które przypadkiem mieści się w zakresie.
while (!poprawny); „Powtarzaj, dopóki nie jest poprawnie”. Zapis while (poprawny) byłby odwrotnością — pętla kręciłaby się tylko przy dobrych danych.

Zawsze daj drogę wyjścia

Pętla walidacji zapętla się, dopóki dane są złe. Jeśli program dostaje dane z pliku, który się skończył, Console.ReadLine() zwraca brak wartości — i pętla nigdy się nie skończy. W programach uruchamianych z klawiatury to nie problem, ale w poważniejszym kodzie warto ograniczyć liczbę prób albo pozwolić na wpisanie „anuluj”.

TEORIA

Wzorzec: licznik i sumator

Drugi wzorzec, który wraca w co drugim zadaniu: przed pętlą przygotowujemy zmienne na wynik, w pętli je uzupełniamy, po pętli wypisujemy.

Program.cs
int suma = 0;        // sumator zaczyna od ZERA
int ile = 0;         // licznik zaczyna od ZERA
int i = 1;

while (i <= 10)
{
    suma += i;       // to samo co: suma = suma + i
    ile++;
    i++;
}

double srednia = (double)suma / ile;

Console.WriteLine($"Suma liczb 1-10:  {suma}");
Console.WriteLine($"Ile skladnikow:   {ile}");
Console.WriteLine($"Srednia:          {srednia:F2}");
wynik w konsoli
Suma liczb 1-10:  55
Ile skladnikow:   10
Srednia:          5,50

Sumator zaczyna od zera, iloczyn od jedynki

Gdyby suma startowała od 1, wynik byłby zawyżony o jeden. Odwrotnie przy mnożeniu: zmienna na iloczyn musi zaczynać od 1, bo wszystko pomnożone przez zero daje zero. To najczęstszy błąd przy liczeniu silni.

Skąd (double) przed dzieleniem

suma i ile są typu int, więc suma / ile byłoby dzieleniem całkowitym — dla 55 i 10 dałoby 5, a nie 5,5. Rzutowanie jednej ze stron na double włącza dzielenie z resztą. To pułapka z lekcji 09 i wraca przy każdej średniej.

TEORIA

Wzorzec: wartownik

Wartownik (ang. sentinel) to umówiona wartość, która oznacza koniec danych. Użytkownik wprowadza liczby jedna po drugiej, a wpisanie zera (albo pustej linii, albo słowa „koniec”) kończy zbieranie.

Program.cs
Console.WriteLine("Podawaj liczby. Pusta linia konczy.");

double suma = 0;
int ile = 0;

Console.Write("Liczba: ");
string wpis = Console.ReadLine() ?? "";

while (wpis.Length > 0)
{
    if (double.TryParse(wpis, out double liczba))
    {
        suma += liczba;
        ile++;
    }
    else
    {
        Console.WriteLine("  Pomijam - to nie liczba.");
    }

    Console.Write("Liczba: ");
    wpis = Console.ReadLine() ?? "";
}

Console.WriteLine();

if (ile == 0)
{
    Console.WriteLine("Nie podano zadnej liczby.");
}
else
{
    Console.WriteLine($"Podano liczb: {ile}");
    Console.WriteLine($"Suma:         {suma:F2}");
    Console.WriteLine($"Srednia:      {suma / ile:F2}");
}
wynik w konsoli
Podawaj liczby. Pusta linia konczy.
Liczba: 12,5
Liczba: 7
Liczba: abc
  Pomijam - to nie liczba.
Liczba: 20,5
Liczba:

Podano liczb: 3
Suma:         40,00
Srednia:      13,33

Wczytanie pojawia się dwa razy — i to jest poprawne

Raz przed pętlą (żeby warunek miał co sprawdzić przy pierwszym obiegu) i raz na końcu bloku (żeby przy kolejnym sprawdzeniu warunek patrzył na nową wartość). Ten układ nazywa się „wczytaj z wyprzedzeniem”. Alternatywa to while (true) z instrukcją break w środku — poznasz ją w lekcji 18 i wtedy powtórzenie zniknie.

Licznik dzieli — sprawdź, czy nie jest zerem

Gdyby użytkownik od razu nacisnął Enter, ile zostałoby zerem, a suma / ile na typie double dałoby NaN — program nie zgłosiłby błędu, tylko wypisał bzdurę. Dlatego przed liczeniem średniej zawsze sprawdzamy licznik.

TEORIA

Liczby losowe

Pętla, która ma czegoś szukać albo coś zgadywać, potrzebuje danych, których nie znamy z góry. Do tego służy klasa Random.

Program.cs
Random los = new Random();

int oczko = los.Next(1, 7);        // liczba calkowita od 1 do 6 — SZESC nie wypadnie... wypadnie, 7 nie
int procent = los.Next(101);       // od 0 do 100
double ulamek = los.NextDouble();  // od 0 (wlacznie) do 1 (wylacznie)

Console.WriteLine($"Kostka: {oczko}, procent: {procent}, ulamek: {ulamek:F3}");

Górna granica jest wyłączna

los.Next(1, 7) daje liczby 1, 2, 3, 4, 5 i 6 — siódemka jest granicą, a nie ostatnią możliwą wartością. To ta sama zasada, którą zobaczysz przy indeksach tablic i zakresach. Kostka sześcienna to Next(1, 7), a nie Next(1, 6).

Jeden generator na cały program

Twórz new Random() raz, przed pętlą, i używaj tego samego obiektu w środku. Tworzenie nowego generatora w każdym obiegu było w starszych wersjach .NET klasycznym błędem dającym serie identycznych liczb. Alternatywa bez tworzenia obiektu to Random.Shared.Next(1, 7). Podanie ziarna — new Random(42) — daje przy każdym uruchomieniu ten sam ciąg, co jest wygodne przy testowaniu.

METODY WBUDOWANE

Użyte w tej lekcji elementy

NazwaZwracaDziałanie
i++ / i--liczba Zwiększa / zmniejsza zmienną o 1. W pętli while to najczęstsza „zmiana”, która doprowadza do zakończenia.
new Random() / los.Next(a, b)Random / int Generator liczb losowych i pobranie liczby od a do b bez b. Obiekt twórz raz, przed pętlą. los.Next(n) daje zakres od 0 do n - 1, a los.NextDouble() ułamek z przedziału <0, 1).
suma += xliczba Skrót od suma = suma + x. Analogicznie -=, *=, /=.
s.Lengthint Właściwość — liczba znaków napisu. s.Length > 0 to sprawdzenie „coś wpisano”. Uwaga: to nie metoda, więc bez nawiasów.
double.TryParse(s, out x)bool Znane z lekcji 11. Wywołane wprost w warunku if pozwala połączyć konwersję i sprawdzenie w jedną linię.
Console.ReadKey(true)ConsoleKeyInfo Czeka na jeden klawisz. Właściwość .Key daje wciśnięty klawisz, a .KeyChar — jego znak. Przydatne do menu bez Entera.
Math.Abs(x)liczba Wartość bezwzględna — w tej lekcji przy sprawdzaniu, czy liczba zmieściła się w tolerancji.
new string(znak, n)string Napis złożony z n powtórzeń znaku — wygodne do rysowania linii i słupków.
PRZYKŁAD Z OMÓWIENIEM

Kasa sklepowa

Program przyjmuje kolejne ceny pozycji zakupów, sumuje je, a na koniec przyjmuje zapłatę i wydaje resztę. Wszystkie trzy wzorce z tej lekcji naraz.

Program.cs
Console.WriteLine("=== KASA ===");
Console.WriteLine("Podaj cene pozycji. Zero konczy paragon.");
Console.WriteLine();

decimal suma = 0;
int pozycje = 0;

// --- 1. wartownik: zbieranie pozycji do wpisania zera ---
decimal cena;

do
{
    Console.Write($"Pozycja {pozycje + 1} - cena (0 = koniec): ");
    string? wpisCeny = Console.ReadLine();
    if (wpisCeny == null) return; // koniec wejscia: konczymy program
    bool ok = decimal.TryParse(wpisCeny, out cena);

    if (!ok || cena < 0)
    {
        Console.WriteLine("  Podaj nieujemna liczbe.");
        cena = -1;                       // wymuszamy kolejny obieg
    }
    else if (cena > 0)
    {
        if (cena > decimal.MaxValue - suma)
        {
            Console.WriteLine("Suma przekroczylaby zakres decimal.");
            return;
        }
        suma += cena;
        pozycje++;
        Console.WriteLine($"  Dodano. Suma: {suma:F2} zl");
    }
}
while (cena != 0);

Console.WriteLine();

if (pozycje == 0)
{
    Console.WriteLine("Paragon pusty. Do widzenia.");
}
else
{
    Console.WriteLine(new string('-', 28));
    Console.WriteLine($"{"Pozycji:",-16}{pozycje,12}");
    Console.WriteLine($"{"DO ZAPLATY:",-16}{suma,12:F2}");
    Console.WriteLine(new string('-', 28));
    Console.WriteLine();

    // --- 2. walidacja: zaplata musi wystarczyc ---
    decimal zaplata;
    bool wystarczy;

    do
    {
        Console.Write("Otrzymano od klienta: ");
        string? wpisZaplaty = Console.ReadLine();
        if (wpisZaplaty == null) return;
        bool ok = decimal.TryParse(wpisZaplaty, out zaplata);

        wystarczy = ok && zaplata >= suma;

        if (!ok)
        {
            Console.WriteLine("  To nie jest kwota.");
        }
        else if (!wystarczy)
        {
            Console.WriteLine($"  Za malo o {suma - zaplata:F2} zl.");
        }
    }
    while (!wystarczy);

    Console.WriteLine();
    Console.WriteLine($"Reszta: {zaplata - suma:F2} zl");
}
wynik w konsoli
=== KASA ===
Podaj cene pozycji. Zero konczy paragon.

Pozycja 1 - cena (0 = koniec): 12,50
  Dodano. Suma: 12,50 zl
Pozycja 2 - cena (0 = koniec): 4,99
  Dodano. Suma: 17,49 zl
Pozycja 3 - cena (0 = koniec): 23,00
  Dodano. Suma: 40,49 zl
Pozycja 4 - cena (0 = koniec): 0

----------------------------
Pozycji:                   3
DO ZAPLATY:            40,49
----------------------------

Otrzymano od klienta: 20
  Za malo o 20,49 zl.
Otrzymano od klienta: 50

Reszta: 9,51 zl

Omówienie

FragmentCo robi i dlaczego tak
decimal cena; przed pętlą Warunek while (cena != 0) stoi poza blokiem, więc zmienna musi być zadeklarowana wcześniej. Deklaracja wewnątrz pętli dałaby CS0103.
cena = -1; po błędzie Sztuczka, która wygląda dziwnie, ale rozwiązuje realny problem: po nieudanym TryParse zmienna zawiera zero, a zero jest sygnałem końca. Bez tej linii wpisanie litery kończyłoby paragon. Ustawiamy wartość, która na pewno nie jest zerem — pętla robi kolejny obieg.
else if (cena > 0) Zero nie jest ani błędem, ani pozycją — to sygnał końca. Dlatego dodajemy do sumy tylko wartości dodatnie, a wyjście z pętli obsługuje sam warunek.
{pozycje + 1} w zachęcie Licznik pokazuje numer pozycji, którą użytkownik właśnie wpisuje, a nie liczbę już dodanych. Drobiazg, ale bez tego pierwsza pozycja miałaby numer 0.
while (!wystarczy) Druga pętla, ta sama konstrukcja co wzorzec walidacji. Warunek łączy dwa wymagania: kwota ma być liczbą i ma wystarczyć.
suma - zaplata w komunikacie Konkretna informacja, ile brakuje, zamiast ogólnego „za mało”. Przy danych 40,49 i 20,00 daje 20,49.
decimal, nie double Pieniądze. Przy double suma 12,50 + 4,99 + 23,00 mogłaby wyjść 40,489999999999995 i reszta różniłaby się o grosz.

Sprawdź sam

12,50 + 4,99 + 23,00 = 40,49. Zapłata 50,00 zł daje resztę 9,51 zł. Uruchom program i wpisz swoje ceny — potem policz na kartce i porównaj.

CZĘSTE BŁĘDY

Na czym się najczęściej potykamy

BłądCo się dzieje i jak poprawić
brak zmiany licznika Pętla nieskończona — program się zawiesza. Sprawdź, czy w bloku zmienia się dokładnie ta zmienna, którą bada warunek.
while (warunek); Średnik tworzy pustą instrukcję: pętla bez treści, czyli zawieszenie. Kompilator ostrzega (CS0642), ale program się zbuduje. Wyjątek: w do-while średnik po while (...) jest obowiązkowy.
brak średnika w do-while Odwrotna pomyłka — CS1002. Zapamiętaj: while bez średnika, do-while ze średnikiem.
out int wiek wewnątrz pętli Tworzy nową zmienną w każdym obiegu, a ta zadeklarowana przed pętlą zostaje pusta. Gdy zmienna już istnieje, pisz samo out wiek.
zmienna wyniku deklarowana w pętli Zerowanie sumy przy każdym obiegu — na końcu zostaje tylko ostatnia wartość. Sumator i licznik deklaruj przed pętlą.
iloczyn zaczynający od zera Wynik zawsze zero. Zmienna na iloczyn startuje od 1.
suma / ile na typach int Dzielenie całkowite obcina resztę: 55/10 daje 5. Rzutuj jedną stronę: (double)suma / ile.
dzielenie przez licznik równy zero Przy typie int program przerywa działanie (DivideByZeroException), przy double po cichu zwraca NaN. Zawsze sprawdź if (ile > 0).
zero jako wartownik przy TryParse Po nieudanej konwersji zmienna dostaje zero — czyli przypadkiem sygnał końca. Albo wybierz inny wartownik (pusta linia), albo po błędzie nadpisz zmienną wartością, która końca nie oznacza.
błąd o jeden i < 5 daje pięć obiegów (1–4 przy starcie od 1), i <= 5 daje pięć obiegów przy starcie od 1. Zanim uruchomisz, wypisz sobie pierwszy i ostatni obieg na kartce.
ZADANIA

Zadania

ZAD 1Odliczanie★☆☆

Wczytaj liczbę całkowitą dodatnią i odlicz od niej w dół do 1, a na końcu wypisz „Start!”. Każdą liczbę w osobnej linii.

ZAD 2Tabliczka mnożenia★☆☆

Wczytaj liczbę od 1 do 10 i wypisz jej tabliczkę mnożenia od 1 do 10, w równych kolumnach.

ZAD 3Suma cyfr liczby★★☆

Wczytaj liczbę całkowitą dodatnią i policz sumę jej cyfr — bez zamieniania jej na tekst. Wskazówka: reszta z dzielenia przez 10 daje ostatnią cyfrę, a dzielenie całkowite przez 10 ją odcina.

ZAD 4Zgadnij liczbę★★☆

Program losuje liczbę od 1 do 100, a użytkownik zgaduje. Po każdej próbie program podpowiada „za mało” albo „za dużo”. Na końcu wypisuje liczbę prób.

ZAD 5Statystyka wprowadzonych liczb★★☆

Użytkownik podaje liczby, aż wpisze pustą linię. Wypisz: ile liczb podano, sumę, średnią, wartość najmniejszą i największą.

ZAD 6Największy wspólny dzielnik★★★

Wczytaj dwie liczby całkowite dodatnie i policz ich największy wspólny dzielnik algorytmem Euklidesa: dopóki druga liczba nie jest zerem, zastępuj parę (a, b) parą (b, a % b). Wypisz też najmniejszą wspólną wielokrotność.

PODSUMOWANIE

Co trzeba zapamiętać

  • while sprawdza warunek przed obiegiem, a do-while po obiegu.
  • Pętla musi mieć przewidziany sposób zakończenia albo świadomie działać jako pętla ciągła.
  • Sumator i licznik zwykle inicjalizujemy przed pętlą.
  • Przed dzieleniem przez liczbę elementów obsłuż przypadek zera.
  • Dane wejściowe mogą się skończyć. ReadLine równe null trzeba odróżnić od błędnego wpisu i nie pytać wtedy bez końca.
  • Nieudane TryParse zapisuje 0 w wyniku liczbowym, więc nie wolno traktować samego zera jako potwierdzonego wartownika.
  • W szukaniu minimum i maksimum można zacząć od pierwszej wartości, ale wcześniej trzeba upewnić się, że dane nie są puste.
Postęp zapisuje się w tej przeglądarce.