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

Pierwszym rodzajem pętli, który poznamy, jest pętla while.

Pętla ta wykonuje przyporządkowane jej instrukcje, nazywane ciałem pętli, zawarte w nawiasach klamrowych { }, dopóki warunek pętli jest spełniony, to znaczy ma wartość true. Jej składnia jest następująca:

while (warunek) {
  instrukcja1;
  instrukcja2;
  // ...
  instrukcjaN;
}
Zauważmy, że instrukcje, które pętla ma wykonywać (ciało pętli), mają wcięcie.

Pętla rozpoczyna się od słowa kluczowego while, po którym, w nawiasach, należy zawrzeć warunek wykonywania pętli, np. x <= 5. W nawiasach klamrowych należy umieścić instrukcje (bądź instrukcję), które mają się wykonać w każdym obiegu pętli (w każdej iteracji pętli). Dopóki warunek pętli będzie spełniony (będzie prawdą), instrukcje objęte w klamry będą wykonywane.

Pętla while działa w następujący sposób:

  1. Sprawdzany jest warunek pętli – jeżeli jest spełniony, tzn. jego wartość to true, to przechodzimy do punktu 2. Jeżeli warunek nie jest spełniony, tzn. jego wartość to false, to przechodzimy do punktu 3.
  2. Wykonywane są instrukcje przyporządkowane do pętli (ciało pętli), czyli instrukcje zawarte w nawiasach klamrowych { }. Po wykonaniu wszystkich instrukcji, wracamy do punktu 1.
  3. Pętla kończy działanie.

Bardzo ważnym aspektem działania pętli while jest to, że pętla while może nigdy nie wykonać swoich instrukcji, jeżeli już przy pierwszym sprawdzeniu jej warunek będzie miał wartość false – z drugiej jednak strony, jeżeli warunek będzie zawsze spełniony, to program się zawiesi – za chwilę zobaczymy przykłady z takimi przypadkami.

Tak samo, jak w przypadku instrukcji warunkowych, jeżeli pętla ma wykonywać tylko jedną instrukcję, to nie musi ona być otoczona nawiasami klamrowymi { }. Jednak, podobnie, jak w przypadku instrukcji warunkowych, zawsze powinniśmy stosować klamry { } nawet w przypadku jednej instrukcji – taka konwencja jest zazwyczaj stosowana wśród programistów.

Przykład: wypisywanie ciągu liczb

Po teorii, czas na praktykę. Spójrzmy na przykład programu, który korzysta z pętli while do wypisania na ekran liczb od 1 do 5:

Nazwa pliku: WypiszLiczbyOd1Do5.java
public class WypiszLiczbyOd1Do5 {
  public static void main(String[] args) {
    int x = 1;

    while (x <= 5) {
      System.out.println(x);
      x++;
    }
  }
}

W wyniku działania tego programu, na ekranie zobaczymy:

1 2 3 4 5

Na początku programu definiujemy zmienną x – będziemy sprawdzać jej wartość w warunku pętli. Inicjalizujemy ją wartością 1.

Warunek pętli while jest następujący:

x <= 5

Naszą pętla będzie wykonywać się dopóki wartość zmiennej x będzie mniejsza bądź równa 5. Zmienna x ma na początku wartość 1, więc powyższe wyrażenie ma wartość true.

Pętla ma za zadanie wykonywać dwie następujące instrukcje:

System.out.println(x);
x++;

W każdej iteracji pętli (w każdym jej obiegu), najpierw wypisana zostanie na ekran wartość zmiennej x, a następnie wartość x zostanie zwiększona o 1 za pomocą jednoargumentowego operatora inkrementacji ++ (operator ten, jak dowiedzieliśmy się w rozdziale o zmiennych, zwiększa wartość swojego argumentu o 1).

Po każdej iteracji pętli, wartość zmiennej x będzie o 1 większa niż podczas poprzedniej iteracji. W końcu, gdy wartość zmiennej x będzie wynosić 6, wyrażenie w warunku pętli:

x <= 5

będzie miało wartość false, więc nastąpi koniec pętli. Program zakończy działanie, ponieważ po pętli nie ma już żadnych instrukcji do wykonania.

Prześledźmy jeszcze raz proces wykonywania się pętli w powyższym programie:

  1. Sprawdzany jest warunek x <= 5 dla x mającego wartość 1. Warunek jest spełniony.
  2. Wykonywane jest ciało pętli:
    1. Na ekran wypisywana jest wartość zmiennej x, czyli 1.
    2. Wartość zmiennej x zwiększana jest o 1 – będzie teraz miała wartość 2.
  3. Ponownie sprawdzany jest warunek x <= 5, tym razem dla mającego wartość 2. Warunek jest spełniony.
  4. Wykonywane jest ciało pętli:
    1. Na ekran wypisywana jest wartość zmiennej , czyli 2.
    2. Wartość zmiennej x <= 5 zwiększana jest o 1 – będzie teraz miała wartość 3.
  5. Ponownie sprawdzany jest warunek x <= 5, tym razem dla x mającego wartość 3. Warunek jest spełniony.
  6. Wykonywane jest ciało pętli:
    1. Na ekran wypisywana jest wartość zmiennej , czyli 3.
    2. Wartość zmiennej x <= 5 zwiększana jest o 1 – będzie teraz miała wartość 4.
  7. Ponownie sprawdzany jest warunek x <= 5, tym razem dla x mającego wartość 4. Warunek jest spełniony.
  8. Wykonywane jest ciało pętli:
    1. Na ekran wypisywana jest wartość zmiennej , czyli 4.
    2. Wartość zmiennej x <= 5 zwiększana jest o 1 – będzie teraz miała wartość 5.
  9. Ponownie sprawdzany jest warunek x <= 5, tym razem dla x mającego wartość 5. Warunek jest spełniony.
  10. Wykonywane jest ciało pętli:
    1. Na ekran wypisywana jest wartość zmiennej x, czyli 5.
    2. Wartość zmiennej x zwiększana jest o 1 – będzie teraz miała wartość 6.
  11. Ponownie sprawdzany jest warunek x <= 5, tym razem dla x mającego wartość 6. Tym razem jednak warunek nie jest spełniony – ma wartość false. Pętla kończy działanie.

W naszym przykładowym programie, chociaż nie jest on skomplikowany, moglibyśmy wykorzystać funkcjonalność operatora ++, aby skrócić go jedną linię. Zauważmy, że operator postfixowy ++ najpierw zwraca wartość zmiennej, którą ma zmodyfikować, a dopiero potem zwiększa wartość tej zmiennej o 1. Oznacza to, że wartością wyrażenia:

x++;

jest aktualna wartość zmiennej x. Moglibyśmy w takim razie skorzystać z tego operatora wewnątrz instrukcji System.out.println:

System.out.println(x++);

W tej jednej linii kodu wypisujemy wartość wyrażenia x++ – ma ono wartość zmiennej x sprzed inkrementacji o 1 (z powodu użycia operatora postfixowego ++, a nie prefixowego). Ponadto, operator ++ zwiększa wartość zmiennej x o 1. Finalnie, linia:

System.out.println(x++);

jest równoważna instrukcjom:

System.out.println(x);
x++;

Cały program mógłby zatem wyglądać następująco:

Nazwa pliku: WypiszLiczbyOd1Do5Skrocony.java
public class WypiszLiczbyOd1Do5Skrocony {
  public static void main(String[] args) {
    int x = 1;

    while (x <= 5) {
      System.out.println(x++);
    }
  }
}

Ten program działa tak samo, jak jego pierwsza wersja – w wyniku jego uruchomienia zobaczymy na ekranie wypisane liczby od 1 do 5.

Przykład: wypisywanie gwiazdek

W kolejnym przykładzie użycia pętli while wyświetlamy na ekranie tyle gwiazdek (znaków * ), ile zażyczy sobie użytkownik.

Od użytkownika pobierzemy liczbę za pomocą poznanej w trzecim rozdziale metody getInt:

Nazwa pliku: WypiszGwiazdki.java
import java.util.Scanner;

public class WypiszGwiazdki {
  public static void main(String[] args) {
    System.out.println("Ile gwiazdek wypisac?");
    int liczbaGwiazdek = getInt();

    // dopoki liczba gwiazdek jest wieksza od zera...
    while (liczbaGwiazdek > 0) {
      // ...wypisz na ekran gwiazdke
      System.out.print("*");
      liczbaGwiazdek--;
    }
  }

  public static int getInt() {
    return new Scanner(System.in).nextInt();
  }
}
W powyższym przykładzie wypisaliśmy na ekran tekst używając nie metody println, lecz print – różnią się one tym, że print nie dodaje znaku końca linii na końcu tekstu – dzięki temu, każda z gwiazdek będzie wypisana w tej samej linii na ekranie.

W tym programie, warunkiem wykonania pętli jest prawdziwość wyrażenia liczbaGwiazdek > 0. W każdej iteracji pętli wypisujemy na ekran jedną gwiazdkę (znak * ), po czym zmniejszamy wartość zmiennej liczbaGwiazdek o 1 za pomocą operatora dekrementacji --. Tak zapisany warunek pętli spowoduje, że wypiszemy na ekran dokładnie tyle gwiazdek, ile podał użytkownik.

Przykładowe pierwsze uruchomienia tego programu:

Ile gwiazdek wypisac? 5 *****

Wynik drugiego uruchomienia:

Ile gwiazdek wypisac? 0

W pierwszym uruchomieniu, ciało pętli wykonało się pięć razy. Drugie uruchomienie programu z podaniem liczby 0 pokazuje, że jeżeli warunek na wstępie pętli while nie jest prawdziwy, to ciało pętli nie wykona się ani razu.

Pętle mogą działać w nieskończoność, jeżeli ich warunek nigdy nie osiągnie wartości false. Jedyne, co można wtedy zrobić, to wymusić zakończenie programu za pomocą skrótu Ctrl + c. W jednym z kolejnych podrozdziałów zobaczymy, jakie zastosowanie mają nieskończone pętle.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Nie musisz podawać swojego imienia, e-mailu, ani strony www, aby opublikować komentarz. Komentarze muszą zostać zatwierdzone, aby były widoczne na stronie.