Spis treści
- Rozdział 4 - Instrukcje warunkowe
- Podstawy instrukcji warunkowych
- Operatory relacyjne
- Typ boolean
- Warunki instrukcji if
- Operatory warunkowe i operator logiczny !
- Tablica prawdy operatorów warunkowych
- Nawiasy i priorytety operatorów warunkowych
- Short-circuit evaluation
- Zagnieżdżanie instrukcji warunkowych
- Bloki kodu i zakresy zmiennych
- Instrukcja switch
- Trój-argumentowy operator logiczny
- Podsumowanie
- Pytania
- Zadania
Gdy będziemy pisać bardziej złożone programy, będzie się zdarzało, że warunki w instrukcjach if będą skomplikowane i będą składały się z wielu mniejszych warunków, złączonych ze sobą za pomocą operatorów warunkowych && oraz ||.
Podczas omawiania operatorów arytmetycznych dowiedzieliśmy się, że różne operatory mają różne priorytety, które wpływają na kolejność ich wykonywania. Kolejność ta może zostać zmieniona przy użyciu nawiasów – wyrażenie 2 + 2 * 2 ma inną wartość, niż wyrażenie (2 + 2) * 2.
Spójrzmy na poniższy przykład instrukcji if, w której korzystamy z obu operatorów warunkowych: && oraz ||:
public class OperatoryWarunkowePriorytety { public static void main(String[] args) { int x = -5; int y = -10; int z = 20; if (x > 0 && y > 0 || z > 0) { System.out.println("Warunek spelniony."); } else { System.out.println("Warunek NIE jest spelniony."); } } }
Pytanie: czy warunek:
x > 0 && y > 0 || z > 0
jest równoznaczny z:
(x > 0 && y > 0) || z > 0
czy może z:
x > 0 && (y > 0 || z > 0)
Czy ma to w ogóle znaczenie?
Tak – powyższe warunki z dodanymi nawiasami to dwa zupełnie rożne wyrażenia – spójrzmy, jaką wartość będzie miało każde z tych wyrażeń dla podanych wyżej wartości zmiennych x, y, z:
x = -5; y = -10; z = 20;
Zastąpmy w pierwszym warunku zmienne liczbami, a następnie obliczmy wartość każdego z porównań i zastąpmy je wartościami true/false:
( x > 0 && y > 0) || z > 0 (-5 > 0 && -10 > 0) || 20 > 0 ( false && false ) || true false || true true
Po obliczeniu wszystkich wyrażeń, całe wyrażenie ma wartość true, ponieważ na końcu zostaliśmy z wyrażeniem false || true – co najmniej jeden z argumentów operatora || ma wartość true, więc całe wyrażenie będzie miało wartość true.
Sprawdźmy teraz tym samym sposobem drugie wyrażenie:
x > 0 && ( y > 0 || z > 0) -5 > 0 && (-10 > 0 || 20 > 0) false && ( false || true ) false && true false
Objęcie nawiasami dwóch ostatnich członów wyrażenia sprawiło, że wynik całego wyrażenia jest inny, niż pierwszym przypadku.
Jak w takim razie zachowa się nasz program?
public class OperatoryWarunkowePriorytety { public static void main(String[] args) { int x = -5; int y = -10; int z = 20; if (x > 0 && y > 0 || z > 0) { System.out.println("Warunek spelniony."); } else { System.out.println("Warunek NIE jest spelniony."); } } }
Po uruchomieniu tego programu, na ekranie zobaczymy:
Wynika więc z tego, że warunek:
x > 0 && y > 0 || z > 0
Jest równoznaczny z warunkiem:
(x > 0 && y > 0) || z > 0
Wynika to z faktu, że operator && ma wyższy priorytet, niż operator || – należy o tym pamiętać pisząc instrukcje warunkowe, a najlepiej – stosować nawiasy w celu poprawy czytelności naszego kodu, by nie było niejasności – nigdy nie powinniśmy pisać warunków w stylu:
// brakuje nawiasow! x > 0 && y > 0 || z > 0
zamiast tego, powinniśmy ująć w nawiasy odpowiednie wyrażenia, by było jasne, jakie są nasze intencje:
(x > 0 && y > 0) || z > 0 // lub x > 0 && (y > 0 || z > 0)
Z nawiasów będziemy także korzystać przy skomplikowanych wyrażeniach w instrukcjach warunkowych:
if ((czyUzytkownikZalogowany && (uzytkownikMaRoleDoZapisu || uzytkownikMaRoleAdministratora)) || czySrodowiskoDeveloperskie) { // ... }
Zauważmy jeszcze, że przy mniej złożonych warunkach, nawiasy nie są potrzebne:
if (x > 0 && y > 0) { System.out.println("Poprawne boki prostokata!"); }