Rozdział 4 - Instrukcje warunkowe - Nawiasy i priorytety operatorów warunkowych

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 ||:

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

Sprwadź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 ostatanich 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?

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

Warunek spelniony.

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!");
}

Dodaj komentarz

Twój adres email nie zostanie opublikowany.