Kontynuacją notatek o instrukcjach sterujących oraz instrukcji switch
, a zarazem wstępem do tablic, są pętle. Te ostatnie udostępniają mechanizm iteracji, znany z innych języków programowania.
Zacznijmy od pętli while
, której budowa przypomina wcześniej poznaną instrukcję if
. Po słowie kluczowym, w nawiasach, występuje wyrażenie. Jeśli przyjmie ono wartość true
, zostanie wykonany blok kodu. W naszym przykładzie blok kodu wyświetla informacje o aktualnej liczbie przejść, a w następnej linii następuje inkrementacja zmiennej idx
. Po zakończeniu bloku kodu pętla wraca do warunku, weryfikując czy jest on prawdziwy, i tak aż do momentu, gdy warunek przyjmie wartość false
.
using System;
namespace HelloWorld
{
public static class Program
{
public static void Main()
{
int idx = 0;
while (idx <= 7)
{
Console.WriteLine("{0} of the 7", idx);
idx++;
}
Console.ReadKey();
}
}
}
Pętla while
sprawdza warunek przed każdą iteracją. W sytuacji, gdy zainicjalizujemy zmienną idx
wartością 9, warunek nie będzie prawdziwy, co sprawi, że blok kodu nie zostanie wykonany. Gwarantem wykonania bloku kodu co najmniej raz jest pętla do...while
, której warunek sprawdzany jest na końcu iteracji.
using System;
namespace HelloWorld
{
public static class Program
{
public static void Main()
{
int idx = 9;
do
{
Console.WriteLine("{0} of the 7", idx);
idx++;
}
while (idx <= 7);
Console.ReadKey();
}
}
}
Bardziej spostrzegawczy czytelnicy zapewne zauważyli średnik, który występuje po warunku pętli do...while
, a którego nie ma za warunkiem pętli while
. Obie instrukcje, podobnie jak if
, nie wymagają bloku kodu, przez co mogą wykonywać jedną linię polecenia. Jeżeli w przykładzie dla pętli while
za warunkiem wstawimy średnik, doprowadzimy do pustej pętli. Instrukcje umieszczone za średnikiem zostaną potraktowane jako niezależne linie kodu, przeznaczone do wykonania po zakończeniu pętli (do którego nigdy nie dojdzie). Uruchomienie pustej pętli doprowadzi do znacznego obciążenia procesora. Prezentuje to animacja poniżej, na której wyświetlone zostało okno Diagnostic Tools.
Kolejna pętla, for
, została odziedziczona z języka C. Wewnątrz nawiasów umieszczone zostały 3 elementy rozdzielone średnikami:
using System;
namespace HelloWorld
{
public static class Program
{
public static void Main()
{
for (int idx = 0; idx <= 7; idx++)
{
Console.WriteLine("{0} of the 7", idx);
}
Console.ReadKey();
}
}
}
Powyższy przykład użycia pętli for
to modyfikacja wcześniejszego kodu pętli while
. Deklaracja zmiennej idx
oraz jej inkrementacja zostały przesunięte do deklaracji pętli, dzięki czemu w jednym miejscu znajdują się wszystkie potrzebne informacje o warunkach wykonania pętli. Dobrą praktyką jest modyfikacja zmiennych biorących udział w warunku pętli wewnątrz jej deklaracji, dzięki czemu analizując jej działanie nie musimy szukać inkrementacji zmiennej w bloku kodu pętli.
Inicjalizator pętli uruchomiony zostaje wyłącznie raz przed sprawdzeniem warunku, ciągłe nadawanie wartości początkowej byłoby mało przydatne. Iterator wykonywany jest na samym końcu po każdej iteracji pętli, a przed ponownym sprawdzeniem warunku.
Poniżej przedstawiam przykład pętli for
, iterującej w dwóch wymiarach. Bezpośrednio C# nie udostępnia instrukcji umożliwiającej przejście przez kilka kolekcji, natomiast zagnieżdżenie jednej pętli wewnątrz drugiej pozwala na uzyskanie takiego efektu.
using System;
namespace HelloWorld
{
public static class Program
{
public static void Main()
{
Console.CursorTop = 5;
for (int x = 20, line = 0; x > 0; x -= 2, line++)
{
Console.CursorLeft = 20 + line;
for (int y = 0; y < x; y++)
{
Console.Write("X");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
Efektem wykonania przykładu będzie narysowanie trójkąta. W linii 5 ustawiamy właściwość CursorTop
klasy Console
, odpowiadającej za przesunięcie kursora konsoli do piątego wiersza. Pierwsza pętla przechodzi po wierszach. Inicjalizator ustawia wartość 20 dla zmiennej x
oraz 0 dla zmiennej line
. Kod pętli będzie przetwarzany do chwili, gdy zmienna x
będzie większa od zera. Iterator po każdym przejściu zmniejsza wartość zmiennej x
o 2 oraz zwiększa zmienną line
. Blok kodu pętli rozpoczyna się od ustawienia właściwości CursorLeft
klasy Console
, odpowiadającej za przesunięcie kursora konsoli do określonej kolumny. Następnie umieszczona jest druga pętla, która odpowiada za rysowanie znaku ""X"", dopóki wartość zmiennej y
będzie mniejsza od zmiennej x
. Po zakończeniu wewnętrznej pętli przechodzimy do nowego wiersza poprzez użycie metody WriteLine
.
Ostatnim rodzajem pętli udostępnionym przez język C# jest foreach
. Pętla została zaprojektowana do przeglądania kolekcji. W odróżnieniu od wcześniejszych pętli, foreach
nie występuje w innych językach rodziny C. Programiści, którzy nie spotkali się jeszcze z pojęciem kolekcji, na chwilę obecną powinni wiedzieć, że jest to obiekt reprezentujący zbiór obiektów określonego typu wraz z mechanizmem umożliwiającym przeglądanie zbioru. Definicja pętli ogranicza się do podania typu obiektu wraz z nazwą reprezentującą element wewnątrz ciała pętli oraz podania kolekcji po słowie kluczowym in
.
using System;
namespace HelloWorld
{
public static class Program
{
public static void Main()
{
string sentence = "Ala ma kota.";
foreach(char c in sentence)
{
Console.WriteLine(c);
}
Console.ReadKey();
}
}
}
Powyższy przykład użycia pętli foreach
przechodzi przez kolekcję obiektów typu char
, reprezentowaną przez zmienną sentence
typu string
(łańcuch znaków). Blok kodu pętli ogranicza się do wyświetlenia znaku w nowej linii i zostanie wykonany dokładnie raz dla każdego elementu kolekcji. Ograniczeniem pętli jest brak możliwości modyfikacji kolekcji (dodanie nowego lub usunięcie istniejącego elementu) podczas jej przeglądania.
Język C# udostępnia instrukcje, które pozwalają pominąć daną iterację lub przerwać wykonywanie pętli. Instrukcja continue
wychodzi z bloku kodu pętli, przechodząc do sekcji iterator, a następnie weryfikacji warunku. Użycie instrukcji break
powoduje zakończenie pętli. Również return
kończy działanie pętli, doprowadzając do wyjścia z metody.
using System;
namespace HelloWorld
{
public static class Program
{
public static void Main()
{
for (int idx = 0; idx <= 7; idx++)
{
if (idx % 2 == 0)
continue;
Console.WriteLine("{0} of the 7", idx);
if (idx == 5)
break;
}
Console.ReadKey();
}
}
}
Pętlami kończymy serię wpisów dotyczącą instrukcji sterujących oraz "przełączników", po przeczytaniu których powinniśmy mieć podstawową wiedzę dotyczącą sterowania przepływem działania aplikacji. Wpis jest również wprowadzeniem do tablic, gdzie będziemy korzystać z pętli w celu iteracji.
Troska Robert