Pętle to struktury programistyczne, które pozwalają na wielokrotne wykonywanie tego samego bloku kodu. Dzięki nim możemy uniknąć powtarzania kodu i efektywnie przetwarzać duże zbiory danych.
Po co nam pętle?
Wyobraź sobie, że chcesz wyświetlić liczby od 1 do 100:
// Bez pętli - bardzo nieefektywne!
Console.WriteLine(1);
Console.WriteLine(2);
Console.WriteLine(3);
// ... i tak dalej do 100 - to byłoby 100 linijek kodu!Z pętlą możesz to zrobić w kilku liniach:
// Z pętlą - elegancko i efektywnie!
for (int i = 1; i <= 100; i++)
{
Console.WriteLine(i);
}Podstawowe pojęcia
- Iteracja – jedno przejście przez pętlę
- Warunek pętli – określa, kiedy pętla ma się wykonywać
- Licznik pętli – zmienna śledząca liczbę iteracji
- Ciało pętli – kod wykonywany w każdej iteracji
Pętla while – „dopóki”
Pętla while to najprostsza forma pętli. Wykonuje kod dopóki warunek jest prawdziwy.
Składnia pętli while
while (warunek)
{
// kod do wykonania
// pamiętaj o zmianie warunku!
}Jak działa pętla while – krok po kroku
int licznik = 1;
while (licznik <= 5)
{
Console.WriteLine($"Iteracja numer: {licznik}");
licznik++; // BARDZO WAŻNE - zwiększ licznik!
}
Console.WriteLine("Koniec pętli");Przebieg wykonania:
- Sprawdź warunek:
licznik <= 5→1 <= 5→true - Wykonaj ciało pętli: wyświetl „Iteracja numer: 1”
- Zwiększ licznik:
licznik++→licznik = 2 - Sprawdź warunek:
2 <= 5→true - Wykonaj ciało pętli: wyświetl „Iteracja numer: 2”
- …kontynuuj aż
licznik = 6 - Sprawdź warunek:
6 <= 5→false - Wyjdź z pętli i kontynuuj program
Praktyczne przykłady pętli while
Przykład 1: Odliczanie
int odliczanie = 10;
Console.WriteLine("Start odliczania:");
while (odliczanie > 0)
{
Console.WriteLine(odliczanie);
odliczanie--;
}
Console.WriteLine("ZERO! Koniec odliczania!");
// Wynik: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ZERO!Przykład 2: Pobieranie danych od użytkownika
string odpowiedz = "";
Console.WriteLine("Zgaduję Twoją ulubioną liczbę!");
while (odpowiedz != "tak")
{
Console.Write("Czy Twoja ulubiona liczba to 42? (tak/nie): ");
odpowiedz = Console.ReadLine().ToLower();
if (odpowiedz == "nie")
{
Console.WriteLine("Hmm, spróbuję jeszcze raz...");
}
else if (odpowiedz != "tak")
{
Console.WriteLine("Proszę odpowiedz 'tak' lub 'nie'");
}
}
Console.WriteLine("Wiedziałem! 42 to odpowiedź na wszystko!");Przykład 3: Sumowanie liczb
int suma = 0;
int liczba = 1;
while (liczba <= 10)
{
suma = suma + liczba; // lub: suma += liczba;
Console.WriteLine($"Dodaję {liczba}, suma = {suma}");
liczba++;
}
Console.WriteLine($"Końcowa suma liczb 1-10: {suma}");
// Wynik: 55Ważne ostrzeżenie – pętla nieskończona!
int i = 1;
while (i <= 5)
{
Console.WriteLine($"To jest iteracja {i}");
// BŁĄD! Brak zwiększenia i - pętla nigdy się nie skończy!
}
// POPRAWKA:
int j = 1;
while (j <= 5)
{
Console.WriteLine($"To jest iteracja {j}");
j++; // Zwiększenie licznika - KLUCZOWE!
}Pętla do-while – „wykonaj, a potem sprawdź”
Pętla do-while to odmiana pętli while, która zawsze wykonuje się przynajmniej raz, bo warunek sprawdzany jest na końcu.
Składnia pętli do-while
do
{
// kod do wykonania
} while (warunek);Różnica między while a do-while
// Pętla while - może się wcale nie wykonać
int a = 10;
while (a < 5) // Warunek od razu false
{
Console.WriteLine("To się nie wykona");
}
// Pętla do-while - wykona się przynajmniej raz
int b = 10;
do
{
Console.WriteLine("To się wykona raz, mimo że warunek jest false");
} while (b < 5); // Warunek sprawdzany na końcuPraktyczne przykłady do-while
Przykład 1: Menu programu
string wybor;
do
{
Console.WriteLine("\n=== MENU GŁÓWNE ===");
Console.WriteLine("1. Opcja pierwsza");
Console.WriteLine("2. Opcja druga");
Console.WriteLine("3. Opcja trzecia");
Console.WriteLine("0. Wyjście");
Console.Write("Twój wybór: ");
wybor = Console.ReadLine();
switch (wybor)
{
case "1":
Console.WriteLine("Wybrałeś opcję 1");
break;
case "2":
Console.WriteLine("Wybrałeś opcję 2");
break;
case "3":
Console.WriteLine("Wybrałeś opcję 3");
break;
case "0":
Console.WriteLine("Do widzenia!");
break;
default:
Console.WriteLine("Nieprawidłowy wybór, spróbuj ponownie.");
break;
}
} while (wybor != "0");Przykład 2: Walidacja danych
int wiek;
bool poprawnyWiek;
do
{
Console.Write("Podaj swój wiek (1-120): ");
string input = Console.ReadLine();
poprawnyWiek = int.TryParse(input, out wiek) && wiek >= 1 && wiek <= 120;
if (!poprawnyWiek)
{
Console.WriteLine("Nieprawidłowy wiek! Spróbuj ponownie.");
}
} while (!poprawnyWiek);
Console.WriteLine($"Twój wiek: {wiek} lat");Przykład 3: Gra w zgadywanie liczby
Random random = new Random();
int sekretnaLiczba = random.Next(1, 11); // 1-10
int proba;
int liczbaProb = 0;
Console.WriteLine("Zgadnij liczbę od 1 do 10!");
do
{
liczbaProb++;
Console.Write($"Próba {liczbaProb}: ");
while (!int.TryParse(Console.ReadLine(), out proba) || proba < 1 || proba > 10)
{
Console.Write("Podaj liczbę od 1 do 10: ");
}
if (proba < sekretnaLiczba)
{
Console.WriteLine("Za mało!");
}
else if (proba > sekretnaLiczba)
{
Console.WriteLine("Za dużo!");
}
else
{
Console.WriteLine($"Brawo! Zgadłeś w {liczbaProb} próbach!");
}
} while (proba != sekretnaLiczba);Pętla for – „od-do z krokiem”
Pętla for to najbardziej strukturalna forma pętli. Idealnie nadaje się gdy z góry wiesz ile razy pętla ma się wykonać.
Składnia pętli for
for (inicjalizacja; warunek; aktualizacja)
{
// kod do wykonania
}Anatomia pętli for
for (int i = 1; i <= 5; i++)
{
Console.WriteLine($"i = {i}");
}
// │ │ │ │
// │ │ │ └── Aktualizacja (po każdej iteracji)
// │ │ └──────── Warunek (sprawdzany przed każdą iteracją)
// │ └─────────────── Inicjalizacja (wykonana raz na początku)
// └──────────────────── Typ i nazwa zmiennej licznikaJak działa pętla for – szczegółowo
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"Wartość i: {i}");
}Krok po kroku:
- Inicjalizacja:
int i = 0(wykonane raz na początku) - Sprawdzenie warunku:
i < 3→0 < 3→true - Wykonanie ciała: wyświetl „Wartość i: 0”
- Aktualizacja:
i++→i = 1 - Sprawdzenie warunku:
i < 3→1 < 3→true - Wykonanie ciała: wyświetl „Wartość i: 1”
- Aktualizacja:
i++→i = 2 - Sprawdzenie warunku:
i < 3→2 < 3→true - Wykonanie ciała: wyświetl „Wartość i: 2”
- Aktualizacja:
i++→i = 3 - Sprawdzenie warunku:
i < 3→3 < 3→false - Wyjście z pętli
Różne warianty pętli for
1. Klasyczna pętla rosnąca
// Liczby od 1 do 10
for (int i = 1; i <= 10; i++)
{
Console.Write(i + " ");
}
// Wynik: 1 2 3 4 5 6 7 8 9 102. Pętla malejąca
// Odliczanie od 10 do 1
for (int i = 10; i >= 1; i--)
{
Console.Write(i + " ");
}
// Wynik: 10 9 8 7 6 5 4 3 2 13. Pętla z krokiem innym niż 1
// Co druga liczba
for (int i = 0; i <= 20; i += 2)
{
Console.Write(i + " ");
}
// Wynik: 0 2 4 6 8 10 12 14 16 18 20
// Co trzecia liczba wstecz
for (int i = 30; i >= 0; i -= 3)
{
Console.Write(i + " ");
}
// Wynik: 30 27 24 21 18 15 12 9 6 3 04. Zagnieżdżone pętle for
Console.WriteLine("Tabela mnożenia 3x3:");
for (int wiersz = 1; wiersz <= 3; wiersz++)
{
for (int kolumna = 1; kolumna <= 3; kolumna++)
{
int wynik = wiersz * kolumna;
Console.Write($"{wynik}\t"); // \t to tabulator
}
Console.WriteLine(); // Nowa linia po każdym wierszu
}
/* Wynik:
1 2 3
2 4 6
3 6 9
*/Przykład 1: Kalkulator silnia
Console.Write("Podaj liczbę do obliczenia silni");
int n = int.Parse(Console.ReadLine());
long faktorial = 1;
for (int i = 1; i <= n; i++)
{
faktorial *= i;
Console.WriteLine($"{i}! = {faktorial}");
}
Console.WriteLine($"Końcowy wynik: {n}! = {faktorial}");
// Dla n=5: 5! = 1×2×3×4×5 = 120Przykład 2: Rysowanie wzorów
Console.Write("Podaj wysokość trójkąta: ");
int wysokosc = int.Parse(Console.ReadLine());
Console.WriteLine("Trójkąt z gwiazdek:");
for (int i = 1; i <= wysokosc; i++)
{
// Wyświetl spacje (dla centrowania)
for (int spacje = 1; spacje <= wysokosc - i; spacje++)
{
Console.Write(" ");
}
// Wyświetl gwiazdki
for (int gwiazdki = 1; gwiazdki <= i; gwiazdki++)
{
Console.Write("* ");
}
Console.WriteLine(); // Nowa linia
}
/* Dla wysokości 4:
*
* *
* * *
* * * *
*/Pętla foreach – „dla każdego elementu”
Pętla foreach to specjalna forma pętli przeznaczona do iterowania przez kolekcje (tablice, listy). Jest najwygodniejsza gdy chcemy przejrzeć wszystkie elementy bez potrzeby znania indeksów.
Składnia pętli foreach
foreach (typ nazwaZmiennej in kolekcja)
{
// kod używający nazwaZmiennej
}Podstawowe przykłady foreach
Iterowanie przez tablicę liczb
int[] liczby = {10, 20, 30, 40, 50};
// Sposób tradycyjny z for
Console.WriteLine("Używając for:");
for (int i = 0; i < liczby.Length; i++)
{
Console.WriteLine($"Liczba: {liczby[i]}");
}
// Sposób z foreach - prostszy!
Console.WriteLine("Używając foreach:");
foreach (int liczba in liczby)
{
Console.WriteLine($"Liczba: {liczba}");
}Iterowanie przez tablicę stringów
string[] owoce = {"jabłko", "banan", "pomarańcza", "kiwi", "mango"};
Console.WriteLine("Lista owoców:");
foreach (string owoc in owoce)
{
Console.WriteLine($"- {owoc}");
}
// Możemy też użyć var - kompilator automatycznie rozpozna typ
foreach (var owoc in owoce)
{
Console.WriteLine($"Owoc: {owoc}, długość nazwy: {owoc.Length}");
}Zalety i ograniczenia foreach
Zalety:
- Prostota – nie musisz zarządzać indeksami
- Bezpieczeństwo – nie ma ryzyka wyjścia poza zakres tablicy
- Czytelność – kod jest bardziej zrozumiały
Ograniczenia:
- Brak dostępu do indeksu – nie wiesz na której pozycji jesteś
- Tylko do odczytu – nie możesz modyfikować elementów tablicy
- Tylko do przodu – nie możesz iterować wstecz
int[] liczby = {1, 2, 3, 4, 5};
foreach (int liczba in liczby)
{
Console.WriteLine(liczba);
// BŁĄD! Nie możesz modyfikować elementu w foreach
// liczba = liczba * 2; // To zmieni tylko lokalną kopię
}
// Jeśli chcesz modyfikować, użyj for:
for (int i = 0; i < liczby.Length; i++)
{
liczby[i] = liczby[i] * 2; // To zmieni element w tablicy
}Praktyczne przykłady foreach
Przykład 1: Analiza tekstów
string[] zdania = {
"To jest pierwsze zdanie.",
"Drugie zdanie jest dłuższe niż pierwsze.",
"Trzecie.",
"Ostatnie zdanie kończy nasz przykład."
};
Console.WriteLine("Analiza zdań:");
int numerZdania = 1;
int calkowitaLiczbaSlów = 0;
foreach (string zdanie in zdania)
{
string[] slowa = zdanie.Split(' ', '.', ',', '!', '?');
int liczbaSlowWZdaniu = 0;
foreach (string slowo in slowa)
{
if (!string.IsNullOrEmpty(slowo))
{
liczbaSlowWZdaniu++;
}
}
Console.WriteLine($"Zdanie {numerZdania}: {liczbaSlowWZdaniu} słów");
calkowitaLiczbaSlów += liczbaSlowWZdaniu;
numerZdania++;
}
Console.WriteLine($"Łącznie słów: {calkowitaLiczbaSlów}");
double srednia = calkowitaLiczbaSlów / (double)zdania.Length;
Console.WriteLine($"Średnia słów na zdanie: {srednia:F1}");Przykład 2: Przetwarzanie danych uczniów
string[] uczniowie = {"Anna Kowalska", "Piotr Nowak", "Maria Wiśniewska", "Jan Kowalski"};
int[] oceny = {4, 5, 3, 4};
Console.WriteLine("Lista uczniów z ocenami:");
int indeks = 0;
foreach (string uczen in uczniowie)
{
string[] imieNazwisko = uczen.Split(' ');
string imie = imieNazwisko[0];
string nazwisko = imieNazwisko[1];
int ocena = oceny[indeks];
string komentarz = ocena switch
{
5 => "Bardzo dobrze!",
4 => "Dobrze",
3 => "Dostatecznie",
2 => "Słabo",
1 => "Bardzo słabo",
_ => "Nieznana ocena"
};
Console.WriteLine($"{imie} {nazwisko}: {ocena} - {komentarz}");
indeks++;
}Przykład 3: Walidacja danych
string[] adresy = {
"anna@email.com",
"piotr@firma.pl",
"nieprawidlowy-email",
"maria@test.org",
"jan.kowalski@example.com"
};
Console.WriteLine("Sprawdzanie poprawności adresów email:");
int prawidlowe = 0;
int nieprawidlowe = 0;
foreach (string adres in adresy)
{
// Prosta walidacja - sprawdza czy zawiera @ i .
bool czyPoprawny = adres.Contains("@") &&
adres.Contains(".") &&
adres.IndexOf("@") < adres.LastIndexOf(".");
if (czyPoprawny)
{
Console.WriteLine($"✓ {adres} - poprawny");
prawidlowe++;
}
else
{
Console.WriteLine($"✗ {adres} - niepoprawny");
nieprawidlowe++;
}
}
Console.WriteLine($"\nPodsumowanie: {prawidlowe} poprawnych, {nieprawidlowe} niepoprawnych");Porównanie wszystkich rodzajów pętli
Kiedy użyć której pętli?
| Rodzaj pętli | Kiedy używać | Przykład zastosowania |
|---|---|---|
| while | Gdy nie wiesz ile razy pętla się wykona | Pobieranie danych od użytkownika do momentu podania prawidłowej wartości |
| do-while | Gdy pętla musi wykonać się przynajmniej raz | Menu programu, walidacja danych |
| for | Gdy z góry wiesz ile iteracji | Iterowanie przez tablicę po indeksach, liczenie od 1 do N |
| foreach | Gdy chcesz przejść przez wszystkie elementy kolekcji | Wyświetlanie zawartości tablicy, przetwarzanie listy |
Praktyczne porównanie – to samo zadanie różnymi pętlami
Zadanie: Wyświetl wszystkie elementy tablicy z numerami pozycji.
string[] kolory = {"czerwony", "zielony", "niebieski", "żółty"};
// 1. PĘTLA FOR - najlepsza do tego zadania
Console.WriteLine("Używając for:");
for (int i = 0; i < kolory.Length; i++)
{
Console.WriteLine($"{i + 1}. {kolory[i]}");
}
// 2. PĘTLA WHILE - możliwa, ale bardziej skomplikowana
Console.WriteLine("\nUżywając while:");
int indeks = 0;
while (indeks < kolory.Length)
{
Console.WriteLine($"{indeks + 1}. {kolory[indeks]}");
indeks++;
}
// 3. PĘTLA FOREACH - prosta, ale bez numerów pozycji
Console.WriteLine("\nUżywając foreach:");
int licznik = 1;
foreach (string kolor in kolory)
{
Console.WriteLine($"{licznik}. {kolor}");
licznik++;
}Kontrola przepływu pętli
Czasami w trakcie wykonywania pętli chcemy zmienić naturalny przepływ – przerwać pętlę wcześniej lub pominąć część iteracji. Do tego służą instrukcje break i continue.
Instrukcja break – „przerwij pętlę”
Instrukcja break natychmiast kończy wykonywanie pętli i przechodzi do pierwszej instrukcji za pętlą.
Do czego służy break:
- Przedwczesne zakończenie pętli gdy znajdziemy to czego szukamy
- Wyjście z pętli gdy nastąpi błąd lub nietypowa sytuacja
- Optymalizacja – nie ma sensu kontynuować gdy zadanie zostało wykonane
Jak działa break – wizualizacja
for (int i = 1; i <= 10; i++)
{
Console.WriteLine($"Iteracja: {i}");
if (i == 5)
{
Console.WriteLine("Przerywam pętlę!");
break; // Koniec pętli - przeskoczy do instrukcji za pętlą
}
Console.WriteLine("Koniec iteracji");
}
Console.WriteLine("To się wykona po break");Przebieg wykonania:
- Iteracja 1: wyświetla „Iteracja: 1”, potem „Koniec iteracji”
- Iteracja 2: wyświetla „Iteracja: 2”, potem „Koniec iteracji”
- Iteracja 3: wyświetla „Iteracja: 3”, potem „Koniec iteracji”
- Iteracja 4: wyświetla „Iteracja: 4”, potem „Koniec iteracji”
- Iteracja 5: wyświetla „Iteracja: 5”, potem „Przerywam pętlę!”, break kończy pętlę
- Wyświetla „To się wykona po break”
Praktyczne przykłady break
Przykład 1: Wyszukiwanie pierwszego wystąpienia
Console.WriteLine("Szukam pierwszej liczby większej od 50:");
int[] liczby = {10, 25, 35, 60, 45, 80, 15};
int pozycja = -1;
for (int i = 0; i < liczby.Length; i++)
{
Console.WriteLine($"Sprawdzam pozycję {i}: {liczby[i]}");
if (liczby[i] > 50)
{
Console.WriteLine($"Znaleziono! Pierwsza liczba > 50 to: {liczby[i]} na pozycji {i}");
pozycja = i;
break; // Nie szukamy dalej - znaleźliśmy pierwszą
}
}
if (pozycja == -1)
{
Console.WriteLine("Nie znaleziono liczby większej od 50");
}
Console.WriteLine("Koniec wyszukiwania");Przykład 2: Walidacja hasła z przerwaniem
Console.WriteLine("Sprawdzanie czy hasło zawiera cyfry:");
string haslo = "MyPassword123";
bool zawieraCyfre = false;
foreach (char znak in haslo)
{
Console.WriteLine($"Sprawdzam znak: '{znak}'");
if (char.IsDigit(znak))
{
Console.WriteLine($"Znaleziono cyfrę: {znak}");
zawieraCyfre = true;
break; // Nie sprawdzamy dalszych znaków
}
}
Console.WriteLine($"Hasło zawiera cyfry: {zawieraCyfre}");Przykład 3: Menu z wyjściem
while (true) // Pętla nieskończona
{
Console.WriteLine("\n=== MENU ===");
Console.WriteLine("1. Opcja A");
Console.WriteLine("2. Opcja B");
Console.WriteLine("0. Wyjście");
Console.Write("Wybór: ");
string wybor = Console.ReadLine();
switch (wybor)
{
case "1":
Console.WriteLine("Wybrałeś opcję A");
break; // break tylko z switch, nie z pętli while!
case "2":
Console.WriteLine("Wybrałeś opcję B");
break; // break tylko z switch, nie z pętli while!
case "0":
Console.WriteLine("Do widzenia!");
return; // Lub można użyć break dla całej pętli while
default:
Console.WriteLine("Nieprawidłowy wybór");
break; // break tylko z switch, nie z pętli while!
}
}Instrukcja continue – „pomiń resztę iteracji”
Instrukcja continue pomija pozostałą część bieżącej iteracji i przechodzi bezpośrednio do następnej iteracji pętli.
Do czego służy continue:
- Pomijanie niepożądanych wartości bez przerywania całej pętli
- Filtrowanie danych w trakcie przetwarzania
- Upraszczanie logiki – zamiast zagnieżdżonych if-ów
Jak działa continue – wizualizacja
for (int i = 1; i <= 6; i++)
{
Console.WriteLine($"Początek iteracji {i}");
if (i == 3 || i == 5)
{
Console.WriteLine($"Pomijam iterację {i}");
continue; // Przeskoczy do następnej iteracji (i++)
}
Console.WriteLine($"Przetwarzam liczbę: {i}");
Console.WriteLine($"Koniec iteracji {i}");
}
Console.WriteLine("Koniec pętli");Przebieg wykonania:
- i=1: „Początek iteracji 1”, „Przetwarzam liczbę: 1”, „Koniec iteracji 1”
- i=2: „Początek iteracji 2”, „Przetwarzam liczbę: 2”, „Koniec iteracji 2”
- i=3: „Początek iteracji 3”, „Pomijam iterację 3”, continue (pomija resztę)
- i=4: „Początek iteracji 4”, „Przetwarzam liczbę: 4”, „Koniec iteracji 4”
- i=5: „Początek iteracji 5”, „Pomijam iterację 5”, continue (pomija resztę)
- i=6: „Początek iteracji 6”, „Przetwarzam liczbę: 6”, „Koniec iteracji 6”
- „Koniec pętli”
Praktyczne przykłady continue
Przykład 1: Filtrowanie liczb parzystych
Console.WriteLine("Liczby nieparzyste od 1 do 10:");
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 0) // Jeśli liczba parzysta
{
continue; // Pomiń - nie wyświetlaj liczb parzystych
}
Console.WriteLine(i); // To się wykona tylko dla liczb nieparzystych
}
// Wynik: 1, 3, 5, 7, 9Przykład 2: Przetwarzanie plików z pomijaniem błędnych
string[] nazwyPlikow = {"dokument.txt", "", "raport.pdf", null, "dane.csv", " "};
Console.WriteLine("Przetwarzanie plików:");
foreach (string nazwa in nazwyPlikow)
{
// Pomiń puste lub null nazwy
if (string.IsNullOrWhiteSpace(nazwa))
{
Console.WriteLine("Pomijam pusty wpis");
continue;
}
// Pomiń pliki PDF (przykładowo)
if (nazwa.EndsWith(".pdf"))
{
Console.WriteLine($"Pomijam plik PDF: {nazwa}");
continue;
}
Console.WriteLine($"✓ Przetwarzam plik: {nazwa}");
// Tutaj byłaby logika przetwarzania pliku
Console.WriteLine($" - Rozmiar nazwy: {nazwa.Length} znaków");
Console.WriteLine($" - Rozszerzenie: {nazwa.Substring(nazwa.LastIndexOf('.') + 1)}");
}
Console.WriteLine("Zakończono przetwarzanie");Przykład 3: Pomijanie niewłaściwych danych wejściowych
int[] wyniki = {85, -5, 92, 150, 78, -10, 88, 200, 91};
Console.WriteLine("Analiza wyników (pomijam nieprawidłowe wartości):");
int suma = 0;
int liczbaPoprawnych = 0;
foreach (int wynik in wyniki)
{
// Pomiń wyniki poza zakresem 0-100
if (wynik < 0 || wynik > 100)
{
Console.WriteLine($"⚠️ Pomijam nieprawidłowy wynik: {wynik}");
continue;
}
Console.WriteLine($"✓ Prawidłowy wynik: {wynik}");
suma += wynik;
liczbaPoprawnych++;
}
if (liczbaPoprawnych > 0)
{
double srednia = suma / (double)liczbaPoprawnych;
Console.WriteLine($"\nStatystyki z {liczbaPoprawnych} prawidłowych wyników:");
Console.WriteLine($"Suma: {suma}");
Console.WriteLine($"Średnia: {srednia:F2}");
}Połączenie break i continue w jednej pętli
Console.WriteLine("Analiza ocen - przerywam przy ocenie 1, pomijam ocenę 2:");
int[] oceny = {4, 5, 3, 2, 4, 1, 5}; // Oceny uczniów
int suma = 0;
int liczbaPrzetworzonych = 0;
for (int i = 0; i < oceny.Length; i++)
{
int ocena = oceny[i];
Console.WriteLine($"\nSprawdzam ocenę {i + 1}: {ocena}");
if (ocena == 1) // Ocena niedostateczna - przerwij całą analizę
{
Console.WriteLine($"❌ Znaleziono ocenę niedostateczną: {ocena}. Przerywam analizę.");
break; // Koniec pętli
}
if (ocena == 2) // Ocena dopuszczająca - pomiń w obliczeniach
{
Console.WriteLine($"⚠️ Pomijam ocenę dopuszczającą: {ocena} (nie liczy się do średniej)");
continue; // Przejdź do następnej iteracji
}
// Ta część wykonuje się tylko dla ocen 3, 4, 5
suma += ocena;
liczbaPrzetworzonych++;
Console.WriteLine($"✓ Przetworzona ocena: {ocena} (suma: {suma})");
}
Console.WriteLine($"\n=== WYNIKI ANALIZY ===");
if (liczbaPrzetworzonych > 0)
{
double srednia = suma / (double)liczbaPrzetworzonych;
Console.WriteLine($"Liczba ocen do średniej: {liczbaPrzetworzonych}");
Console.WriteLine($"Suma ocen: {suma}");
Console.WriteLine($"Średnia: {srednia:F2}");
}
else
{
Console.WriteLine("Nie przetworzono żadnych ocen do obliczenia średniej");
}Różnice między break a continue
| Aspekt | break | continue |
|---|---|---|
| Działanie | Kończy całą pętlę | Kończy tylko bieżącą iterację |
| Co się dzieje dalej | Przechodzi do kodu za pętlą | Przechodzi do następnej iteracji |
| Kiedy używać | Gdy znalazłeś to czego szukasz lub wystąpił błąd | Gdy chcesz pominąć niektóre wartości |
| Wpływ na licznik | Zatrzymuje licznik | Licznik kontynuuje (i++, następny element) |
Porównanie na przykładzie:
Console.WriteLine("=== DEMO BREAK ===");
for (int i = 1; i <= 5; i++)
{
if (i == 3)
{
Console.WriteLine("Break na 3 - koniec pętli");
break;
}
Console.WriteLine($"i = {i}");
}
Console.WriteLine("Po pętli z break\n");
Console.WriteLine("=== DEMO CONTINUE ===");
for (int i = 1; i <= 5; i++)
{
if (i == 3)
{
Console.WriteLine("Continue na 3 - pomiń resztę iteracji");
continue;
}
Console.WriteLine($"i = {i}");
}
Console.WriteLine("Po pętli z continue");
/* Wynik:
=== DEMO BREAK ===
i = 1
i = 2
Break na 3 - koniec pętli
Po pętli z break
=== DEMO CONTINUE ===
i = 1
i = 2
Continue na 3 - pomiń resztę iteracji
i = 4
i = 5
Po pętli z continue
*/Zagnieżdżone pętle – break i continue
Ważne: break i continue działają tylko na najbliższą otaczającą pętlę!
Console.WriteLine("Break w zagnieżdżonych pętlach:");
for (int i = 1; i <= 3; i++)
{
Console.WriteLine($"Pętla zewnętrzna: i = {i}");
for (int j = 1; j <= 5; j++)
{
if (j == 3)
{
Console.WriteLine($" Break w pętli wewnętrznej przy j = {j}");
break; // Przerywa tylko pętlę wewnętrzną (j)
}
Console.WriteLine($" Pętla wewnętrzna: j = {j}");
}
Console.WriteLine($"Koniec iteracji i = {i}\n");
}
/* Wynik:
Pętla zewnętrzna: i = 1
Pętla wewnętrzna: j = 1
Pętla wewnętrzna: j = 2
Break w pętli wewnętrznej przy j = 3
Koniec iteracji i = 1
Pętla zewnętrzna: i = 2
Pętla wewnętrzna: j = 1
Pętla wewnętrzna: j = 2
Break w pętli wewnętrznej przy j = 3
Koniec iteracji i = 2
Pętla zewnętrzna: i = 3
Pętla wewnętrzna: j = 1
Pętla wewnętrzna: j = 2
Break w pętli wewnętrznej przy j = 3
Koniec iteracji i = 3
*/Kiedy NIE używać break i continue
1. Gdy można użyć prostszego warunku
// ❌ Niepotrzebnie skomplikowane z continue
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 0)
{
continue;
}
Console.WriteLine(i);
}
// ✅ Prostsze bez continue
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 1) // lub (i % 2 != 0)
{
Console.WriteLine(i);
}
}2. Gdy break można zastąpić lepszym warunkiem pętli
// ❌ Niejasny warunek z break
for (int i = 0; i < 100; i++)
{
if (i > 10)
{
break;
}
Console.WriteLine(i);
}
// ✅ Jaśniejszy warunek pętli
for (int i = 0; i <= 10; i++)
{
Console.WriteLine(i);
}Najczęstsze błędy z break i continue
1. Break w switch vs break w pętli
for (int i = 1; i <= 5; i++)
{
switch (i)
{
case 3:
Console.WriteLine("Znaleziono 3");
break; // To przerywa tylko switch, NIE pętlę for!
default:
Console.WriteLine($"Liczba: {i}");
break;
}
}
// Pętla for będzie działać dalej po switchNiepotrzebne używanie w foreach
string[] imiona = {"Anna", "Piotr", "Maria"};
// Często niepotrzebne - foreach i tak przejdzie przez wszystkie elementy
foreach (string imie in imiona)
{
Console.WriteLine(imie);
// continue tutaj nie ma sensu - i tak przejdzie do następnego elementu
}Podsumowanie break i continue
Break używamy gdy:
- Szukamy pierwszego wystąpienia czegoś
- Chcemy przerwać pętlę przy błędzie
- Znaleźliśmy wynik i nie ma sensu szukać dalej
- Implementujemy menu z opcją wyjścia
Continue używamy gdy:
- Chcemy pominąć nieprawidłowe dane
- Filtrujemy elementy w trakcie przetwarzania
- Chcemy uprościć zagnieżdżone warunki if
- Pomijamy puste lub null wartości
Pamiętaj:
- break = koniec całej pętli
- continue = koniec bieżącej iteracji, przejdź do następnej
- Działają tylko na najbliższą otaczającą pętlę
- Używaj rozważnie – czasem prostszy warunek jest lepszy
Najczęstsze błędy z pętlami
1. Pętla nieskończona
// BŁĄD! Pętla nieskończona
int i = 0;
while (i < 10)
{
Console.WriteLine(i);
// Brak zwiększenia i - pętla nigdy się nie skończy!
}
// POPRAWKA:
int j = 0;
while (j < 10)
{
Console.WriteLine(j);
j++; // Pamiętaj o zmianie warunku!
}2. Błąd off-by-one (o jeden za dużo/mało)
int[] tablica = {10, 20, 30, 40, 50}; // Indeksy: 0, 1, 2, 3, 4
// BŁĄD! Wyjście poza zakres tablicy
for (int i = 0; i <= tablica.Length; i++) // <= zamiast <
{
Console.WriteLine(tablica[i]); // Błąd przy i=5!
}
// POPRAWKA:
for (int i = 0; i < tablica.Length; i++) // < zamiast <=
{
Console.WriteLine(tablica[i]);
}3. Modyfikowanie kolekcji w foreach
int[] liczby = {1, 2, 3, 4, 5};
// BŁĄD! Próba modyfikowania w foreach
foreach (int liczba in liczby)
{
liczba = liczba * 2; // To nie zmieni elementu w tablicy!
}
// POPRAWKA: Użyj for do modyfikacji
for (int i = 0; i < liczby.Length; i++)
{
liczby[i] = liczby[i] * 2; // To rzeczywiście zmieni element
}4. Niewłaściwy warunek w while
Console.Write("Podaj liczbę dodatnią: ");
int liczba = int.Parse(Console.ReadLine());
// BŁĄD! Warunek może być spełniony od początku
while (liczba < 0)
{
}