Strona 1
[lekcja] Operacje porównania | Kurs C++ » Poziom 1
2011-11-12 15:34:35
http://cpp0x.pl/kursy/Kurs-C++/Poziom-1/Operacje-porownania/14
Darmowe kursy Online
»
Kurs C++
»
Poziom 1
Autor: Piotr Szawdyński
Operacje porównania
[lekcja]
Rozdział 11. Operatory porównania; co jest prawdą, a co fałszem w C++ i wielokrotne przypisanie.
Kolejnym łatwym zagadnieniem, które powinniśmy znać ze szkoły podstawowej jest porównywanie wartości. Zacznijmy najpierw od
poznania operatorów porównania (nazywanych również operatorami relacji):
Operator Krótki opis
>
... jest większe od ...
>=
... jest większe lub równe niż ...
<
... jest mniejsze od ...
<=
... jest mniejsze lub równe niż ...
==
... jest równe ...
!=
... jest różne od ...
Wynikiem operacji porównania jest prawda albo fałsz, czyli warunek jest spełniony albo nie. Słowa kluczowe, które opisują te stany w
języku C++ to odpowiednio true i false. Tak samo jak w przypadku operacji arytmetycznych, operacje porównania możemy
wykonywać bezpośrednio na wartościach jak i zmiennych. Przejdźmy teraz do przykładowego kodu źródłowego:
C/C++
#include <iostream>
int
main
(
void
)
{
bool
porownanie
=
123
>=
321
;
std
::
cout
<<
"porownanie = "
<<
porownanie
<<
std
::
endl
;
std
::
cout
<<
"porownanie = "
<<(
111
!=
222
) <<
std
::
endl
;
std
::
cout
<<
"porownanie = "
<<(
777
==
777
) <<
std
::
endl
;
std
::
cout
<<
"porownanie = "
<<(
777
<
777
) <<
std
::
endl
;
return
0
;
}
Powyższy program wyświetli nam następujący tekst:
porownanie = 0
porownanie = 1
porownanie = 1
porownanie = 0
Zauważ, że w przypadku gdy wartość logiczną zapisywaliśmy do zmiennej to nawiasy zaokrąglone nie były nam potrzebne. W przypadku,
gdy chcemy wypisać wynik porównania na ekran za pomocą strumienia std::cout, są one konieczne. W przypadku braku nawiasów
otrzymamy następujący komunikat:
error: invalid operands of types 'int' and '<unresolved overloaded function type>' to binary 'operator<<'
Błąd ten nie wynika z tego, że kompilator jest źle napisany tylko z faktu, że operatory mają różne priorytety. Operacja porównania
posiada niższy priorytet niż operator <<, co prowadzi do błędu, który naprawić możemy poprzez wymuszenie kolejności wykonania
operacji za pomocą zaokrąglonych nawiasów. Poniżej zamieszczam kod, który powinien Ci lepiej zobrazować opisany problem:
C/C++
#include <iostream>
int
main
(
void
)
{
int
zmienna
=
5
;
bool
popatrzNaTo
=
10
*
4
+
zmienna
/
2
<=
zmienna
*
8
;
std
::
cout
<<
"popatrzNaTo = "
<<
popatrzNaTo
<<
std
::
endl
;
return
0
;
}
Aby dokonać porównania dwóch wartości, należy najpierw wykonać wszystkie działania. Kompilator przekształci więc ten kod tak, aby
najpierw zostały wykonane obliczenia lewej i prawej części nierówności, a następnie porówna wartości obu stron równania i zwróci
interesujący nas wynik.
Strona 2
[lekcja] Operacje porównania | Kurs C++ » Poziom 1
2011-11-12 15:34:35
http://cpp0x.pl/kursy/Kurs-C++/Poziom-1/Operacje-porownania/14
Co jest prawdą, a co fałszem?
Odejdźmy na chwilę od zagadnienia porównywania wartości. Wiemy, że istnieje coś takiego jak zmienna typu bool i przyjmuje ona dwie
wartości: true i false. Wyświetlając jednak zawartość zmiennej bool dostajemy wartość 0 lub 1. Nasuwa się więc następujące pytanie:
jak to jest z tym typem w rzeczywistości ?
. Aby to wyjaśnić posłużę się kolejnym przykładem:
C/C++
#include <iostream>
int
main
(
void
)
{
bool
eksperymentujemy
=
12312
;
std
::
cout
<<
"eksperymentujemy = "
<<
eksperymentujemy
<<
std
::
endl
;
eksperymentujemy
=
0
;
std
::
cout
<<
"eksperymentujemy = "
<<
eksperymentujemy
<<
std
::
endl
;
eksperymentujemy
= -
123.0
;
std
::
cout
<<
"eksperymentujemy = "
<<
eksperymentujemy
<<
std
::
endl
;
return
0
;
}
Powyższy program wygląda na pierwszy rzut oka absurdalnie. Co więcej prawdopodobnie nie wiesz co się wyświetli na ekranie konsoli.
Zobaczmy więc efekt działania programu:
eksperymentujemy = 1
eksperymentujemy = 0
eksperymentujemy = 1
Kolejne pytanie jakie już Ci się na język ciśnie to:
"Dlaczego otrzymałem takie wartości?!"
. Możesz zacząć się zastanawiać nad regułą
kiedy się pojawia jedynka, a kiedy zero. Być może tworzysz teraz jakieś dziwne teorie kiedy jaką wartość otrzymamy, albo że trudno
będzie zapamiętać kiedy jakie wartości się otrzymuje. Jeśli tak już zaczynasz myśleć - jesteś w błędzie. Reguła w C++ jest prosta: jeśli
wartość jest różna od zera to prawda - w przeciwnym wypadku fałsz.
Często popełniany błąd przez początkujących
Po krótkim wywodzie na temat wartości logicznych w C++ pora przejść do bardzo ważnego tematu, czyli do często popełnianych
błędów przez początkujących programistów . Spójrzmy teraz na następujący program:
C/C++
#include <iostream>
int
main
(
void
)
{
int
xyz
=
321
;
bool
wynik
=
xyz
=
123
;
std
::
cout
<<
"xyz = "
<<
xyz
<<
std
::
endl
;
std
::
cout
<<
"wynik = "
<<
wynik
<<
std
::
endl
;
return
0
;
}
Powyższy program może na pierwszy rzut oka wyglądać prawidłowo. Kompilator grzecznie go skompiluje i program się uruchomi, jednak
nie otrzymamy oczekiwanego wyniku. Na ekranie zastaniemy natomiast następujący tekst:
xyz = 123
wynik = 1
Zamiast operacji porównania została wykonana operacja przypisania. W konsekwencji kompilator najpierw przypisał wartość 123 do
zmiennej o nazwie xyz, a następnie xyz przypisał do zmiennej wynik, którą uznał za prawdę, ponieważ wartość xyz jest różna od zera.
Zauważmy też, że w powyższym programie stosunkowo łatwo było namierzyć ten błąd dlatego, że wartości wypisywaliśmy na ekran.
Pisząc programy nie wypisujemy jednak prawie nigdy wyniku porównania tak więc pamiętaj, żeby zwracać szczególną uwagę na
wszystkie warunki, w których ma występować porównanie wartości ==. Nie jednemu programiście taki błąd krwi napsuł i nie raz patrzył
on w kod szukając błędu wszędzie dookoła tylko nie w tej prostej operacji porównania.
Wielokrotneprzypisanie
Skoro już użyliśmy w poprzednim programie 'niechcący' wielokrotnego przypisania, warto w tym miejscu wspomnieć co to jest i jak to
działa. Wielokrotne przypisanie służy do przypisywania kilku zmiennym tej samej wartości. Przykładowo: chcemy mieć trzy wyniki
obliczeń i wszystkie wyniki mają mieć początkową wartość równą 0. Przypisanie takie możemy wykonać na trzy sposoby. Pierwszym z
nich jest przypisanie wartości odrazu przy tworzeniu zmiennej. Drugi i trzeci sposób przedstawiam poniżej:
C/C++
//Sposób drugi:
int
x1
,
y1
,
z1
;
x1
=
0
;
y1
=
0
;
z1
=
0
;
Strona 3
[lekcja] Operacje porównania | Kurs C++ » Poziom 1
2011-11-12 15:34:35
http://cpp0x.pl/kursy/Kurs-C++/Poziom-1/Operacje-porownania/14
Architektserwisu: Piotr Szawdyński
© Wszelkieprawa zastrzeżone2005-2011
//Sposób trzeci:
int
x2
,
y2
,
z2
;
x2
=
y2
=
z2
=
0
;
Efekt działania zarówno sposobu drugiego jak i trzeciego będzie taki sam. Różnicą jest tu jednak kolejność przypisania w przypadku
trzecim, tj. kolejność wykonywanych operacji przebiegnie od prawej do lewej, czyli:
C/C++
z2
=
0
;
y2
=
z2
;
x2
=
y2
;
Dodatkową zaletą tego rozwiązania jest fakt, że kompilator będzie mógł trochę ten kod zoptymalizować i przypisać zmiennym nowe
wartości szybciej, niż w przypadku wystąpienia trzech osobnych operacji. Wadą tego rozwiązania dla początkujących może być jednak
zmniejszenie czytelności kodu. Dobrze wiedzieć, że coś takiego istnieje, ale stosować na siłę tego nie ma co głównie ze względu na to,
że obecne PC'ty i kompilatory są na tyle dobre, że nie zauważyłbyś różnicy nawet dla miliona takich przypisań. Ponadto w większości
przypadków kompilatory same z siebie wygenerują taki sam kod dla obu fragmentów kodu, tak więc traktuj tą informację raczej jako
ciekawostkę, którą można sobie stosować, a nie jako coś z czego trzeba korzystać. Innymi słowy: da się bez tego obyć i ja właśnie takie
zapisy omijam szerokim łukiem po to, żeby kod był bardziej przyjazny programiście.
Zadanie domowe
Napisz krótki program, wykorzystujący wielokrotne przypisanie.
Wszystkieteksty są chronioneprawami autorskimi. Kopiowanielub rozpowszechnianietreści poza niniejszymserwisem jest
zabronione.
Powyższe ograniczenie nie dotyczy autora opracowania, któremu przysługuje prawo do rozpowszechnianiawłasnego tekstu wedle własnego uznania.