Wszystkie komputery są kompatybilne, ale niektóre są kompatybilniejsze od innych...
Część 3.3. Instrukcje
Pusta  |   Grupująca  |   if  |   switch  |   for  |   while  |   do  |   break  |   continue

Instrukcja pusta

Najprostszą postacią instrukcji jest instrukcja pusta, która posiada następującą postać :
;
Instrukcja ta niczego nie wykonuje. Jest jednak nieraz użyteczna w połączeniu z innymi instrukcjami, co będzi widać w dalszej części kursu.

Instrukcja grupująca

W wielu przypadkach zachodzi konieczność stworzenia bloku zawierającego zestaw instrukcji, np.: w omawianych dalej instrukcjach warunkowych i pętli, podczas tworzenia własnych funkcji i klas. Do tego celu służy instrukcja grupująca - para nawiasów klamrowych - o następującej postaci:
{	instrukcja1;
	instrukcja2;
	...... 
	instrtrukcjaN; 
}
gdzie każda instrukcja może być dowolną instrukcją Javy. Instrukcje grupujące mogą się wewnętrznie zagłębiać, przy czym nie ma ograniczenia ilości zagłębień ani ilości instrukcji wewnątrz pojedynczej instrukcji grupującej.

Należy jednocześnie pamiętać, że instrukcje grupujące nie mogą się "krzyżować": każda klamra zamykająca jest traktowana jako koniec ostatnio użytej klamry otwierającej.

Instrukcja if

Bardzo często zdarza się w programie, że musimy sprawdzić jakiś warunek i wykonać pewną czynność, jeżeli jest on prawdziwy, a w przeciwnym wypadku zrobić coś innego. Do tego typu działań służy instrukcja warunkowa if o następującej składni:

if ( wrażenie_warunkowe ) 
	{ instrukcje wykonywane, gdy warunek jest prawdziwy } 
[ else 
	{ instrukcje wykonywane, gdy warunek jest fałszywy } ] 

W odróżnieniu od C i C++ wrażenie_warunkowe nie może być wyrażeniem numerycznym, ale musi zwracać wartość logiczną true lub false.

Zacznijmy od najprostszego przykładu: programu sprawdzającego, czy zmienna całkowtą jest liczbą parzystą, czy nieparzystą:

public class Przyklad
{  public static void main (String args[])
   {  int x = 1;
      if ( x % 2 == 0)
         { System.out.println (x + " jest liczbą parzystą"); }
      else
         { System.out.println (x + " jest liczbą nieparzystą"); }
  }
}

Powyższy program wyświetli tekst: 1 jest liczbą nieparzystą. Możesz poeksperymentować zmieniając wartość zmiennej x i uruchamiając program ponownie.

Spróbujmy teraz zrobić coś bardziej skomplikowanego: program rozwiązujący równanie kwadratowe. Teraz - po obliczeniu delty trójmianu - będziemy mieli do rozpatrzenia 3 przypadki:

  • delta < 0 - równanie nie posiada pierwiastków rzeczywistych;
     
  • delta = 0 - równanie posiada 1 pierwiastek rzeczywisty;
     
  • delta > 0 - równanie posiada 2 pierwiastki rzeczywiste.
     

Jest to bardzo dobry przykład do zaprezentowania możliwości instrukcji if oraz zagłębiania się instrukcji złożonych. Ponieważ wczytywanie danych z klawiatury jest w Jawie sprawą bardziej skomplikowaną, to odłożymy to na później, korzystając w tym przypadku z inicjacji zmiennych w programie:

public class Przyklad
{  public static void main (String args[])
  { int a = 3, b = 13, c = 1;
    double delta, x;

    System.out.println ("Wspolczynniki rownania:\n");
    System.out.println ("a = " + a + "    b = " + b + "    c = " + c + "\n");

    if (a == 0)                      // sprawdzenie, czy to jest równanie kwadratowe
    {  System.out.println ("To nie jest rownanie kwadratowe: a = 0 !");
    }
    else
    {  delta = b * b - 4 * a * c;    // obliczenie delty równania
       System.out.println ("Delta = " + delta + "\n");
       if (delta < 0)                // delta ujemna - brak rozwiązań
       {  System.out.println ("Rownanie nie ma rozwiazania w zbiorze liczb rzeczywistych");
       }
       else
       {  if (delta == 0)            // delta = 0 - jedno rozwiązanie
          {  x = -b / (2 * a);
             System.out.println ("Rozwiazanie: x0 = " + x);
          }
          else                       // delta dodatnie - 2 rozwiązania
          {  x = (-b + Math.sqrt(delta)) / (2 * a);
             System.out.print ("Rozwiazanie: x1 = " + x);
             x = (- a - Math.sqrt(delta)) / (2 * a);
             System.out.println (",   x2 = " + x);
          }
        }
      }
   }
}

Program pokazuje działanie instrukcji if, z możliwością kolejnych jej zagłębień. Wynik działania programu powinien wyglądać następująco:

W programie Math.sqrt(delta) służy do obliczenia pierwiastka z delty. Zwróć też uwagę na zapis (2 * a). Gdybyśmy nie użyli nawiasów, aby zmienić kolejność wykonywania działań, to licznik najpierw byłby podzielony przez 2, i wynik dzielenia pomnożony przez a: działanie matematycznie poprawne, ale zniekształcające nasze rozwiązanie.

Instrukcja switch

Instrukcja switch stanowi bardzo wygodny i czytelny zamiennik dla rozbudowanej instrukcji if ... else if.... Składnia instrukcji jest następująca:

switch (wyrażenie)
{  case wartość1 :
		instrukcje_1;
		[ break; ]
   case wartość2 :
		instrukcje_2;
		[ break; ] 
    ................. 
   case wartośćN :
		instrukcje_N;
		[ break; ]
   [ default :
		instrukcje_M; ]
} 
Najpierw obliczana jest wartość wyrażenie. Następnie obliczona wartość porównywana jest z kolejnymi wartośćX podanymi po słowie kluczowym case. Jeżeli wyliczona wartość jest równaj, którejś z tych wartości, to wykonywane są instrukcje z tego bloku. Instrukcje wykonywane są do końca bloku switch, chyba że wcześniej wystąpi instrukcja break, która przenosi sterowanie do następnej instrukcji za blokiem switch.

Jeżeli wyliczona wartość nie zostanie odnaleziona, to wykonywany jest blok instrukcji po słowie kluczowym default, oczywiści, o ile ten blok wystąpi (jest opcjonalny).

Zademonstrujemy działanie instrukcji switch na prostym, ale przejrzystym przykładzie: napiszemy program, który dla podanego numeru miesiąca wyświetli, ile ma on dni (dla uproszczenia przyjmiemy, że luty ma zawsze ma 28 dni):

public class Przyklad
{  public static void main (String args[])
   { int mies = 5;
     switch (mies)
     { case 4:
       case 6:
       case 9:
       case 11:
           System.out.println ("Miesiąc " + mies + " ma 30 dni");
           break;
       case 2:
           System.out.println ("Miesiąc " + mies + " ma 28 dni");
           break;
       case 4:
       case 3:
       case 5:
       case 7:
       case 8:
       case 10:
       case 12:
           System.out.println ("Miesiąc " + mies + " ma 31 dni");
           break;
       default:
           System.out.println (mies + " nie jest poprawnym numerem miesiąca");
     }
   }
}

Program będzie działał zależnie od wartości zmiennej mies:

  • dla mies równego 4, 6, 9 i 11 wyświetlony zostanie tekst Miesiąc n ma 30 dni;
     
  • dla mies równego 2 wyświetlony zostanie tekst Miesiąc 2 ma 28 dni;
     
  • dla pozostałych miesięcy: 1, 3, 5, 7, 8, 10 i 12 wyświetlony zostanie tekst Miesiąc n ma 31 dni;
     
  • dla każdej innej wartości mies - default - wyświetlony zostanie tekst n nie jest poprawnym numerem miesiąca.
     
W każdym przypadku pojawi się tylko jeden napis i program się zakończy. Jest to o wiele prostsze i zdecydowanie czytelniejsze, niż gdybyśmy użyli rozbudowanej instrukcji if ... else ...

Pętla for

W przypadku, kiedy jakaś instrukcja lub ich blok mają być wykonywane wielokrotni, używamy instrukcji pętli. Jeżeli np. chcemy wyświetlić liczby od 1 do 20, to prościej będzie zapisać to w pętli, niż pisać 20 instrukcji wyświetlających kolejne liczby naturalne. Jeszcze bardziej oczywiste staje się to w przypadku wyświetlenia np. 1000 kolejnych liczb.

Istnieje kilka instrukcji służących do budowania pętli programowych. My zaczniemy od instrukcji for o następującej składni:

for ( [instrukcje_początkowe] ; [wyrażenie_warunkowe] ; [instrukcje_modyfikujące] )  
{	instrukcje; 
	.........; 
} 
gdzie
  • instrukcje_początkowe to jedno lub kilka (oddzielonych przecinkami) wyrażeń inicjujących zmienne;
     
  • wyrażenie_warunkowe określa warunek logiczny kolejnego wykonania pętli;
     
  • instrukcje_modyfikujące to jedno lub kilka (oddzielonych przecinkami) wyrażeń modyfikujących wartości zmiennych po każdym przejściu pętli.
     
Pętla for działa według następującego algorytmu:
  1. wykonane są instrukcje_początkowe;
     
  2. sprawdzana jest wartości logiczna wyrażenie_warunkowe;
     
  3. jeżeli wyrażenie_warunkowe ma wartość false, to sterowanie przechodzi do następnej instrukcji za petlą;
     
  4. jeżeli wyrażenie_warunkowe ma wartość true, to wykonywane są wszystkie instrukcje;
     
  5. wykonywane są instrukcje_modyfikujące;
     
  6. następuje powrót do punktu 2.
     

Sprawdźmy działanie instrukcji for na wspomnianym na wstępie przykładzie wyświetlania 20 początkowych liczb naturalnych:

public class Przyklad
{  public static void main (String args[])
   { for (int i = 1 ; i<=20 ; i++)
           System.out.print (" " + i);
   }
}

W tym programie zmienną i zadeklarowaliśmy wewnątrz pętli for. Jest to o tyle wygodne, że zmienna tak zadeklarowana, znika z pamięci zaraz po opuszczeniu pętli. Można oczywiście zadeklarować i zainicjować ją poza pętlą. Wtedy nasz program wyglądałby tak:

public class Przyklad
{  public static void main (String args[])
   { int i = 1;
     for ( ; i<=20 ; i++)
           System.out.print (" " + i);
   }
}

Istnieje również możliwość wbudowania wyrażenia modyfikującego do wnętrza pętli i pominięcia go w samej składni instrukcji for. Taki program wyglądałby następująco:

public class Przyklad
{  public static void main (String args[])
   { for (int i = 1 ; i<=20 ; )
           System.out.print (" " + i);
		   i++;
   }
}

korzystając z instrukcji break możemy z naszej pętli usunąć nawet wyrażenie warunkowe. Wtedy nasz program miałby postać:

public class Przyklad
{  public static void main (String args[])
   { int i = 1;
     for ( ;  ; )
        {   System.out.print (" " + i);
            i++;
            if (i>20)  break;
        }
   }
}

Pętla while

Pętla for służy do wykonania z góry znanej ilości powtórzeń. Pętla while służy natomiast do wykonywania pętli tak długo, jak długo będzie prawdziwy pewien warunek logiczny. Oczywiście obie pętle dają się tak skonstruować, aby można je używać wymiennie.

Składnia instrukcji while wygląda następująco:

while (wyrażenie_warunkowe)  
{	instrukcje; 
	..........; 
} 
Jeżeli wyrażenie_warunkowe będzie od razu fałszywe, to pętla while nie wykona się ani razu.

Zbudujmy program wyświetlający liczby od 1 do 20, ale tym razem nie z użyciem pętli for lecz while:

public class Przyklad
{  public static void main (String args[])
   { int i = 1;
     while ( i<=20 )
        {   System.out.print (" " + i);
            i++;
        }
   }
}

Jak widać - nic trudnego.

Pętla do ... while

Pętla do ... while jest odmianą pętli while. Obie działają tak długo, jak długo prawdziwy jest warunek kontrolujący pętlę. Różnica między nimi polega tylko na miejscu, w którym badany jest warunek: pętla while bada go przed rozpoczęciem pętli, a pętla do ... while - po zakończeniu wykonywania pętli. Wynika z tego, że jeżeli warunek jest na wstępie fałszywy, to pętla while nie wykona się ani razu, ale pętla do ... while wykona się 1 raz (i dopiero po wykonaniu stwierdzi, że warunek jest fałszywy).

Nasz dotychczasowy program zrealizowany za pomocą pętli do ... while będzie wyglądał tak:

public class Przyklad
{  public static void main (String args[])
   { int i = 1;
     do
        {   System.out.print (" " + i);
            i++;
        }
     while ( i<=20 );
   }
}

Instrukcje break i continue

Wewnątrz pętli for, while i do możemy użyć instrukcji:
continue;
i
break;

Instrukcja continue powoduje powrót na początek pętli, bez wykonywania wszystkich pozostałych do końca instrukcji.
Instrukcja break powoduje natomiast zakończenie wykonania pętli i przejście do następnej instrukcji poza blok instrukcji pętli.

Zademonstrujmy to na przykładzie. Niech program wyświetla kolejne liczby naturalne podzielne przez 13, a zakończy się po napotkaniu pierwszej takiej liczby większej od 100 i podzielnej przez 17:

public class Przyklad
{  public static void main (String args[])
    { int i = 0;
      while (true)    // pętla nieskończona
      { i++;
        if (i % 13 != 0)  continue;
                      // niepodzielne - wracamy na początek
        System.out.println (" " + i);
         if (i > 100  &&  i % 17 == 0) break;
                      // warunek końca wykonywania pętli
      }
   }
}
« wstecz   dalej »