Rozdział 5 - Pętle - Pętla for

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:

Nazwa pliku: WypiszLiczbyOd1Do5For.java
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ącajest 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.
  • warunekjest 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_krokujest 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:

  1. Wykonywana jest instrukcja inicjalizująca pętli for – definiowana jest zmienna i o początkowej wartości 1.
  2. Sprawdzany jest warunek pętli i <= 5 dla i mającego wartość 1. Wyrażenie to ma wartość true, więc przechodzimy dalej.
  3. Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 1.
  4. 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.
  5. Ponownie sprawdzany jest warunek, ale dla i równego 2. Ponownie wartością jest true.
  6. Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 2.
  7. Ponownie wykonujemy instrukcję krokui będzie teraz miało wartość 3.
  8. Ponownie sprawdzany jest warunek, ale dla i równego 3. Ponownie wartością jest true.
  9. Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 3.
  10. Ponownie wykonujemy instrukcję krokui będzie teraz miało wartość 4.
  11. Ponownie sprawdzany jest warunek, ale dla i równego 4. Ponownie wartością jest true.
  12. Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 4.
  13. Ponownie wykonujemy instrukcję krokui będzie teraz miało wartość 5.
  14. Ponownie sprawdzany jest warunek, ale dla i równego 5. Ponownie wartością jest true.
  15. Wykonywane jest ciało pętli – wypisujemy wartość zmiennej i, czyli 5.
  16. Ponownie wykonujemy instrukcję krokui będzie teraz miało wartość 6.
  17. 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:

  1. Wykonaj wszystkie instrukcje inicjalizujące.
  2. Sprawdź warunek pętli:
    1. Jeżeli jest prawdziwy, wykonaj ciało pętli.
    2. Jeżeli jest nieprawdziwy, przerwij działanie pętli, pomijając kolejne kroki.
  3. Po wykonaniu ciała pętli, wykonaj intrukcje 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:

Nazwa pliku: WypiszGwiazdkiFor.java
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:

Ile gwiazdek wypisac? 3 ***
Ile gwiazdek wypisac? 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:

Nazwa pliku: InstrukcjeInicjalizujacePetlaFor.java
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:

j = 1, k = 1 j = 2, k = 3 j = 4, k = 9 j = 8, k = 27 j = 16, k = 81

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ść.

Instrukcje for, w której nie zdefiniowano któregoś z członów (bądź wszystkich) nie są zbyt często używane – po prostu nie mają zbyt wielu zastosowań.

Dodaj komentarz

Twój adres email nie zostanie opublikowany.