Operatory inkrementacji i dekrementacji, relacji oraz operatory logiczne

Wprowadzenie

W poprzedniej lekcji przedstawiłem podstawowe operatory: operator przypisania, operatory arytmetyczne oraz złożone operatory przypisania. Dzięki tej lekcji poznasz kolejne rodzaje operatorów. Wszystkie przedstawione tutaj operatory są nie mniej przydatne i nie rzadziej używane od tych przedstawionych w poprzedniej lekcji.

Operatory inkrementacji i dekrementacji

Operatory te można nazwać operatorami spokrewnionymi z operatorem przypisania, dodawania i odejmowania, bowiem powodują one zmniejszenie lub zwiększenie wartości zmiennej o 1.


++ zwiększenie wartości o 1, np. i++ to jest to samo co i=i+1
 --  zmniejszenie wartości o 1, np. i-- to jest to samo co i=i-1

Należy jednak zwrócić uwagę, że operatory te można stosować przed i po zmiennej, tzn. liczba++ lub ++liczba. Podobnie jest z operatorem dekrementacji --. Mimo, że działanie operatora w obu przypadkach jest podobne, to nie jest jednak identyczne!


Aby to wyjaśnić, muszę Ci zdradzić, że w języku C/C++ prawie każde wyrażenie zwraca jakąś wartość. Np. operacja 5+6 zwraca liczbę 11, i dzięki temu int liczba=5+6; powoduje przypisanie zmiennej liczba wartości 11.


Operatory ++ i -- również zwracają wartość, z tym tylko, że jeśli operator znajduje się przed zmienną, to zwraca wartość zmiennej po zwiększeniu(zmniejszeniu), a jeśli znajduje się po zmiennej, to zwraca wartość zmiennej przed wykonaniem operacji zwiększenia(zmniejszenia). Jednak wartość zmiennej w obu przypadkach będzie taka sama.


Jeśli nie do końca udało Ci się zrozumieć jaka jest różnica, oto prosty program, który powinien wyjaśnić wszystkie wątpliwości:

#include <iostream>

using namespace std;

int main()
{
  int liczba1;
  int liczba2;
  int liczba3;
  int liczba4;
 
  liczba1=5;
  liczba2=5;
  liczba3=5;
  liczba4=5;
 
  cout <<"Wartosc liczba1++ to "<<liczba1++
       <<" a wartosc zmiennej to "<<liczba1<<endl;
  cout <<"Wartosc ++liczba2 to "<<++liczba2
       <<" a wartosc zmiennej to "<<liczba2<<endl;
  cout <<"Wartosc liczba3-- to "<<liczba3--
       <<" a wartosc zmiennej to "<<liczba3<<endl;
  cout <<"Wartosc --liczba4 to "<<--liczba4
       <<" a wartosc zmiennej to "<<liczba4<<endl;
       
  cout <<endl<<"Nacisnij ENTER aby zakonczyc"<<endl;
  getchar();
  return 0;
}
program nr 8.1

Przy okazji chcę zaznaczyć, że operatorów inkrementacji i dekrementacji nie należy stosować w bardziej skomplikowanych wyrażeniach takich jak na przykład a++ + ++b + 4 + ++a. Wynik takiej operacji będzie zależeć bowiem od kompilatora, czyli tak naprawdę nigdy nie można być pewnym jaka będzie końcowa wartość wyrażenia.

Operatory relacji

Operatory operacji umożliwiają porównaniu różnych wyrażeń. Za ich pomocą możemy sprawdzić czy dwie liczby lub wyrażenia są sobie równe. Podobnie jak wszystkie wymienione do tej pory operatory, są bardzo często stosowane.


Oto operatory relacji:

== równa się (np. 2==3 jest nieprawdziwe, a 5==5 jest prawdziwe)
!=  jest różne (np. 2!=3 jest prawdziwe, a 5!=5 jest nieprawdziwe)
>   jest większe
>= jest większe lub równe
<   jest mniejsze
<= jest mniejsze lub równe


O ile zapamiętanie większości z tych operatorów nie sprawi Ci trudności, to znacznie trudniej jest zapamiętać w jaki sposób używamy operatora równości. Aby sprawdzić czy dwie liczby są jednakowe piszemy liczba1==liczba2.


Łatwo można się pomylić i napisać liczba1=liczba2, co spowoduje przypisanie wartości zmiennej o nazwie liczba1 wartości zmiennej o nazwie liczba2, gdyż operator = jest (jak już wiesz) operatorem przypisania. Przy okazji całe wyrażenie zwróci wartość zmiennej liczba2, co może spowodować, że znalezienie błędu będzie bardzo trudne.


Operatory logiczne

Operatory logiczne umożliwiają łączenie ze sobą kilku wyrażeń. Są bardzo przydatne i bardzo często wykorzystywane, gdy w naszym programie podejmujemy pewne decyzje. W języku C++ występują trzy operatory logiczne.

||   suma logiczna - prawdziwe jeśli ktorekolwiek z wyrażeń jest prawdziwe
&& iloczyn logiczny - prawdziwe jeśli oba wyrażenia są prawdziwe
!    negacja logiczna - powoduje zaprzeczenie wyrażenia


Dla przykładu wyrażenie (3==5) || (2==2) jest prawdziwe, bowiem pierwsza część jest fałszem, a druga prawdą, czyli co najmniej jedno wyrażenie jest prawdziwe. Z kolei (4>=2) && ((8%2)==0) jest również prawdziwe, bowiem zarówno pierwsza, jak i druga część są prawdziwe. Z kolei !(3==5) jest prawdziwe, bo wyrażenie 3==5 jest nieprawdziwe. Podobnie !((3==5) || (2==2)) jest nieprawdziwe, bo samo wyrażenie (3==5) || (2==2) jest prawdziwe.


Warto przy okazji wspomnieć, że przypisanie = zwraca wartość przypisania czyli np. a=3 zwraca wartość 3, a każda liczba różna od zera jest w języku C++ traktowana jako prawda. Tylko wartość 0 jest traktowana jako fałsz.


Ma to bardzo duże znaczenie, bowiem jeśli napiszemy (najprawdopodobniej przez pomyłkę) (a=2) || (3==5), to się okaże, że jest prawdziwe, gdyż a=2 zwraca wartość 2, która zostaje potraktowana jako prawda. Druga część jest oczywiście fałszywa, ale ponieważ pierwsza część była prawdziwa, to całość jest również potraktowana jako prawda.

W poniższym programie wypiszemy wartości kilku przykładowych wyrażeń. Wypisana wartość 0 oznacza, że wyrażenie jest fałszywe, a wartość 1, że wyrażenie jest prawdziwe.

#include <iostream>

using namespace std;

int main()
{
  int a; // zmienna uzyta w 3. przykladzie
 
  cout <<"(3==5) || (2==2) to " <<((3==5) || (2==2))<<endl;
  cout <<"(4>=2) && ((8%2)==0) to "<< ((4>=2) && ((8%2)==0))<<endl;
  cout <<"(a=2) || (3==5) to "<<((a=2) || (3==5))<<endl;
  cout <<"1+1>3 to " << (1+1>3)<<endl;
  cout <<"2+2>2+2 to " << (2+2>2+2)<<endl;
 
  cout <<endl<<"Nacisnij ENTER aby zakonczyc"<<endl;
  getchar();
  return 0;
}
program nr 8.2

W tym momencie zachęcam Cię do wymyślenia kilku przykładowych wyrażeń i przed uruchomieniem programu wypisującego ich wartość zachęcam Cię do przemyślenia, jaką wartość program wypisze. Bardzo ważne jest zrozumieć, jak działają takie wyrażenia.


Zwróć również uwagę, że wszystkie wyrażenia wypisywane są otoczone nawiasami okrągłymi. Kiedy będziesz wymyślać własne przykłady, nie zapomnij ich dodać, bowiem w przeciwnym przypadku otrzymasz nieoczekiwane rezultaty.

Priorytety i łączność operatorów

Jak już wspomniałem w poprzedniej lekcji, o tym które wyrażenia są wykonywane najpierw, decyduje priorytet operatorów.

Żeby udowodnić Ci, jak zgubny skutek ma nieznajomość (lub raczej nieumiejętne posługiwanie się operatorami), zmień w poprzednim przedstawionym programie pierwszą linijkę, w której wypisujemy wynik operacji na taką linijkę:

  cout <<"(3==5) || (2==2) to " <<(3==5) || (2==2)<<'\n';

Skompiluj program i uruchom. Zauważysz, że stało się coś dziwnego - została wypisana wartość 0 (wcześniej była wartość 1), a co najdziwniejsze, nie nastąpiło przejście do nowej linii. Tak właśnie może się skończyć nieumiejętne korzystanie z operatorów. W tym przypadku chodzi o to, że << to również operator (o czym do tej pory nie wspominałem).

Musisz wiedzieć, że wszystkie operatory mają swoje priorytety i łączność. Priorytet oznacza, że jeśli użyjemy dwóch operatorów o różnych priorytetach, to któraś z operacji wykona się najpierw (np. mnożenie wykona się przed dodawaniem w wyrażeniu a=b+c*d).


Łączność określa sposób ustawienia "niewidocznych dla użytkownika nawiasów". Np. operator + jest łączny lewostronnie, zatem a=b+c+d oznacza tak naprawdę a=(b+c)+d.


Mimo że istnieją bardzo długie i trudne do zapamiętania tabelki priorytetów operatorów, ja jednak zrezygnuję na razie z przedstawiania ich tutaj. Myślę, że to w tym momencie i tak niepotrzebne, a poza tym nie chcę Cię zbytnio przerazić.


Jeśli nie wiesz, w jakiej kolejności zostanie przeprowadzone pewne działanie na wyrażeniu użyj nawiasów okrągłych, na przykład a=(b+c)*d lub a=b+(c*d). O ile w pierwszym przypadku użycie nawiasów jest uzasadnione, to w drugim - nawiasy są zbędne. Ale zapamiętaj - jeśli nie wiesz w jakiej kolejności działają operatory, lepiej użyć nawet kilku par nawiasów niż martwić się, że później program nie działa poprawnie.


Podsumowanie

W tym momencie znasz już podstawowe operatory występujące w języku C++. Tak naprawdę operatorów jest co najmniej kilka razy więcej niż znasz ich do tej pory, jednak nie musisz znać wszystkich od razu, a poza tym z niektórych naprawdę rzadko się korzysta.

powrót