Spis treści
Pętla for jest często używaną pętlą. Jej składnia jest trochę bardziej skomplikowana, niż poznane do tej pory pętle while oraz do..while:
for (instrukcja_inicjalizująca; warunek; instrukcja_kroku) { instrukcja1; instrukcja2; }
Spójrzmy najpierw na przykład pętli for w programie, który wypisuje liczby od 1 do 5:
public class WypiszLiczbyOd1Do5For { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { System.out.println(i); } } }
W wyniku działania tego programu zobaczymy na ekranie liczby od 1 do 5.
Przeanalizujmy teraz poszczególne elementy pętli for:
- instrukcja_inicjalizująca – jest to instrukcja (bądź instrukcje rozdzielone przecinkami) wykonywana jednorazowo, jeszcze przed rozpoczęciem pętli – w naszym przykładzie jest to utworzenie zmiennej o nazwie i typu int, oraz zainicjalizowanie jej wartością 1.
- warunek – jest to wyrażenie obliczane przed każdą iteracją pętli – jeżeli jest spełnione (jego wartość to true), to wykonane zostanie ciało pętli. W naszym przykładzie porównujemy zmienną i z liczbą 5 – jeżeli zmienna i jest mniejsza bądź równa 5, to warunek będzie spełniony, a co za tym idzie, wykona się ciało pętli.
- instrukcja_kroku – jest to instrukcja (bądź instrukcje rozdzielone przecinkami) wykonywana zaraz po zakończeniu każdego obiegu pętli. W naszym przykładzie zwiększamy (używając postfixowego operatora inkrementacji) wartość zmiennej i o 1.
Prześledźmy działanie pętli for w powyższym programie:
- Wykonywana jest instrukcja inicjalizująca pętli for – definiowana jest zmienna i o początkowej wartości 1.
- Sprawdzany jest warunek pętli i <= 5 dla i mającego wartość 1. Wyrażenie to ma wartość true, więc przechodzimy dalej.
- Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 1.
- Na końcu iteracji pętli, wykonywana jest instrukcja kroku – w tym przypadku, zwiększamy wartość zmiennej i o 1 – zmienna i będzie teraz miała wartość 2.
- Ponownie sprawdzany jest warunek, ale dla i równego 2. Ponownie wartością jest true.
- Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 2.
- Ponownie wykonujemy instrukcję kroku – i będzie teraz miało wartość 3.
- Ponownie sprawdzany jest warunek, ale dla i równego 3. Ponownie wartością jest true.
- Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 3.
- Ponownie wykonujemy instrukcję kroku – i będzie teraz miało wartość 4.
- Ponownie sprawdzany jest warunek, ale dla i równego 4. Ponownie wartością jest true.
- Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 4.
- Ponownie wykonujemy instrukcję kroku – i będzie teraz miało wartość 5.
- Ponownie sprawdzany jest warunek, ale dla i równego 5. Ponownie wartością jest true.
- Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 5.
- Ponownie wykonujemy instrukcję kroku – i będzie teraz miało wartość 6.
- Ponownie sprawdzany jest warunek, ale dla i równego 6. Tym razem, wartość wyrażenia i <= 5 ma wartość false. Następuje koniec pętli.
Zasadę działania pętli for można uogólnić w następujący sposób:
- Wykonaj wszystkie instrukcje inicjalizujące.
- Sprawdź warunek pętli:
- Jeżeli jest prawdziwy, wykonaj ciało pętli.
- Jeżeli jest nieprawdziwy, przerwij działanie pętli, pomijając kolejne kroki.
- Po wykonaniu ciała pętli, wykonaj instrukcje kroku i przejdź do kroku 2.
Pętla while i pętla for mają wspólną cechę – jeżeli ich warunek nie będzie spełniony już na początku wykonywania pętli, to ciało pętli nie wykona się ani razu. Spójrzmy na przykład z wypisywaniem gwiazdek:
import java.util.Scanner; public class WypiszGwiazdkiFor { public static void main(String[] args) { System.out.println("Ile gwiazdek wypisac?"); int liczbaGwiazdek = getInt(); for (int i = 0; i < liczbaGwiazdek; i++) { System.out.print("*"); } } public static int getInt() { return new Scanner(System.in).nextInt(); } }
Spróbujmy uruchomić program dwa razy – raz podamy 3 gwiazdki do wypisania, a drugi raz 0:
Program działa poprawnie, gdy podamy do wypisania 0 gwiazdek, ponieważ, w takim przypadku, warunek pętli i < liczbaGwiazdek nie będzie spełniony już na samym początku działania pętli i ciało pętli nie wykona się ani razu.
Instrukcje inicjalizujące i kroku¶
Instrukcje inicjalizujące i instrukcje kroku nie muszą być pojedyncze w pętli for – spójrzmy na poniższy przykład:
public class InstrukcjeInicjalizujacePetlaFor { public static void main(String[] args) { for (int j = 1, k = 1; j < 100 && k < 100; j = j * 2, k = k * 3) { System.out.println("j = " + j + ", k = " + k); } } }
W tej pętli mamy:
- dwie instrukcje inicjalizujące, rozdzielone przecinkami – utworzenie dwóch zmiennych: j oraz k,
- dwie instrukcje kroku – pomnożenie wartości zmiennej j razy 2 oraz zmiennej k razy 3.
Ten program wypisuje na ekran kolejne potęgi liczb 2 oraz 3 do czasu, aż któraś z nich nie przekroczy liczby 100. Zauważmy, że w warunku pętli mamy dwuczłonowe wyrażenie, w którym wykorzystujemy operator warunkowy && (and). Wynik działania tego programu to:
Należy jeszcze zwrócić uwagę, iż każdy z elementów pętli for jest opcjonalny – poniższa pętla będzie wykonywać się w nieskończoność:
for (;;) { }
Pętla ta nie zawiera ani instrukcji inicjalizującej, ani warunku pętli, ani instrukcji kroku – widzimy jedynie średniki, które oddzielają od siebie poszczególne elementy pętli for, ponieważ średniki te są one wymagane.
W ramach inicjalizacji powyższej pętli nic się nie zadzieje. Podobnie po każdym obiegu pętli – nie będzie wykonanej żadnej instrukcji kroku. Warunek pętli nie został zdefiniowany, więc pętla będzie działała w nieskończoność.