Autor: Dondu
Kurs języka C: Spis treści
Operatory logiczne działają jak operatory bitowe, ale dotyczą wartości logicznej argumentów. Innymi słowy służą do porównywania, a nie wykonywania operacji.
Symbol | Znaczenie | Przykład |
---|---|---|
|| | Alternatywa | a || b |
&& | Koniunkcja | a && b |
! | Negacja | !a |
Operatory logiczne przetwarzane są od lewej do prawej
To bardzo istotna właściwość operatorów logicznych. Brak świadomości tej właściwości może w pewnych sytuacjach prowadzić do nieprawidłowego działania programu. Szczegóły w opisach poszczególnych operatorów logicznych poniżej.
Operator alternatywy: ||
Zapis operatora:
lewy || prawy
Operator alternatywy (inaczej OR) przyjmuje wartości:
- 0 - gdy po obu stronach operatora wartość logiczna jest równa zero
- 1 - gdy co najmniej jedna ze stron operatora jest różna od zero.
Zobacz przykład i eksperymentuj z nimi w kompilatorze CManiak zmieniając wartość zmiennej a.
Przykład 1 (w kompilatorze)
int a=5; //definicja zmiennej //przykładowe przypadki printf("%d \n", a>3 || a<10 ); //a spełnia oba warunki printf("%d \n", a<3 || a<10 ); //a spełnia prawy warunek printf("%d \n", a>3 || a>10 ); //a spełnia lewy warunek printf("%d \n", a<3 || a>10 ); //a nie spełnia żadnego warunku
Operator ten przetwarzany jest od lewej do prawej. Jeżeli lewy argument będzie różny od zera, to sprawdzanie jest zatrzymywane, a wynikiem operatora || będzie jeden.
Takie podejście przyspiesza działanie programu, eliminując sprawdzanie prawego argumentu, który i tak już nie będzie miał wpływu na wynik całego warunku.
UWAGA!
Z tym związane jest pewne niebezpieczeństwo dla początkujących. W przypadku gdy częścią warunku jest funkcja lub działanie arytmetyczne np. ++ lub --, to nie zostanie zrealizowane .
Przykład 2 (w kompilatorze)
int a=5; //definicja zmiennej printf("na początku a=%d \n", a); //a spełnia lewy warunek, więc prawy nie jest badany, //stąd nie zostanie wykonana dekrementacja --a printf("a>3 || --a<2 wynik=%d \n", a>3 || --a<2 ); printf("na końcu a=%d", a);
Sprawdź co się stanie, gdy zmienną a ustawisz na wartość, która nie będzie spełniać lewej strony warunku, czyli np. a=1 i skompiluj przykład w kompilatorze CManiak. Zauważysz wtedy, że prawy warunek będzie analizowany, co stwierdzisz na podstawie wykonania dekrementacji --a.
Podobnie gdy np. prawym argumentem jest funkcja. Trzeba być świadomym, że może nie zostać wykonana, jeżeli lewy argument będzie różny od zera.
Przykład 3 (w kompilatorze)
int podaj_ilosc(){ printf("byłem w funkcji podaj_ilosc() \n"); return 2; //zwracamy jakąś wartość } int main(void) { int a=5; //definicja zmiennej //a spełnia lewy warunek, więc prawy nie jest badany //stąd funkcja podaj_ilosc() nie zostanie wykonana printf("a>3 || podaj_ilosc()<2 wynik=%d", a>3 || podaj_ilosc()<2 ); return 0; //zakończ wykonywanie programu }Sprawdź co się stanie, jeżeli zmienną a ustawisz na wartość, która nie będzie spełniać lewej strony warunku, czyli np. a=1 i skompiluj przykład w kompilatorze CManiak. Zauważysz wtedy, że prawy warunek będzie analizowany, co stwierdzisz na podstawie napisu: Byłem w funkcji podaj_ilosc()
Operator koniunkcji: &&
Zapis operatora:
lewy && prawy
Operator koniunkcji (inaczej AND) przyjmuje wartości:
- 0 - gdy co najmniej po jednej stronie operatora wartość logiczna jest równa zero,
- 1 - gdy po obu stronach operatora wartość logiczna jest różna od zera.
Zobacz przykład i eksperymentuj z nimi w kompilatorze CManiak zmieniając wartość zmiennej a.
Przykład 4 (w kompilatorze)
int a=5; //definicja zmiennej //cztery możliwe przypadki printf("%d \n", a>3 && a<10 ); //a spełnia oba warunki printf("%d \n", a<3 && a<10 ); //a nie spełnia lewego warunku printf("%d \n", a>3 && a>10 ); //a nie spełnia prawego warunku printf("%d \n", a<3 && a>10 ); //a nie spełnia żadnego warunku
Takie podejście przyspiesza działanie programu, eliminując sprawdzanie prawego argumentu, który i tak już nie będzie miał wpływu na wynik całego warunku.
UWAGA!
Z tym związane jest pewne niebezpieczeństwo dla początkujących. W przypadku gdy częścią warunku jest funkcja lub działanie arytmetyczne np. ++ lub --, to nie zostanie zrealizowane.
Przykład 5 (w kompilatorze)
int a=1; //definicja zmiennej printf("na początku a=%d \n", a); //a nie spełnia lewego warunku, więc prawy nie jest badany, //stąd nie zostanie wykonana dekrementacja --a printf("a>3 && --a<2 wynik=%d \n", a>3 && --a<2 ); printf("na końcu a=%d", a);
Sprawdź co się stanie, jeżeli zmienną a ustawisz na wartość, która będzie spełniać lewą stronę warunku, czyli np. a=5 i skompiluj przykład w kompilatorze CManiak. Zauważysz wtedy, że prawy warunek będzie analizowany, co stwierdzisz na podstawie wykonania dekrementacji --a.
Podobnie gdy np. prawym argumentem jest funkcja. Trzeba być świadomym, że może nie zostać wykonana, jeżeli lewy argument będzie różny od zera.
Przykład 6 (w kompilatorze)
int podaj_ilosc(){ printf("byłem w funkcji podaj_ilosc() \n"); return 2; //zwracamy jakąś wartość } int main(void) { int a=1; //definicja zmiennej //a nie spełnia lewego warunku, więc prawy nie jest badany //stąd funkcja podaj_ilosc() nie zostanie wykonana printf("a>3 && podaj_ilosc()<2 wynik=%d", a>3 && podaj_ilosc()<2 ); return 0; //zakończ wykonywanie programu }Sprawdź co się stanie, jeżeli zmienną a ustawisz na wartość, która będzie spełniać lewą stronę warunku, czyli np. a=5 i skompiluj przykład w kompilatorze CManiak. Zauważysz wtedy, że prawy warunek będzie analizowany, co stwierdzisz na podstawie napisu: Byłem w funkcji podaj_ilosc()
Operator negacji: !
Zapis operatora:
!warunek
Operator negacji (inaczej NOT) przyjmuje wartości:
- 0 - gdy warunek jest różny od zera,
- 1 - gdy warunek jest równy zero.
Innymi słowy zmienia stan warunku na przeciwny.
Przykład 7 (w kompilatorze)
int a=5; //definicja zmiennej //a spełnia warunek printf("a>3 wynik bez negacji = %d \n", a>3 ); printf("!(a>3) wynik zanegowany = %d \n", !(a>3) );
Spróbuj zmienić zmienną a na wartość 1 i sprawdź działanie programu w kompilatorze CManiak.
Kurs języka C: Spis treści
21
W przypadku koniunkcji błędne jest zdanie:
OdpowiedzUsuń"Podobnie gdy np. prawym argumentem jest funkcja. Trzeba być świadomym, że może nie zostać wykonana, jeżeli lewy argument będzie różny od zera."
Powinno być: "jeżeli lewy argument będzie równy zero".
Pozdrawiam!