3.2.5. Operatorii logici

2019/01/23 in Programare in C

Operatorii logici sunt:

Negatia logica are aceeasi prioritate ca si ceilalti operatori unari ai limbajului c. De altfel, toti operatorii unari au aceeasi prioritate, care este imediat mai mare decat cea a operatorilor multiplicativi.

Expresia:

!operand

are valoarea 0 (fals) daca operand are o valoare diferita de zero si valoarea 1 (adevarat) daca operand are valoarea zero.

Operatorul && are prioritatea mai mica decat cei de egalitate. O expresie de forma:

E1&&E2

are valoarea 1 daca expresiile E1 si E2 sunt ambele diferite de zero. In rest, expresia de mai sus are valoarea 0.

Operatorul || are prioritatea imediat mai mica decat operatorul &&. Expresia:

E1||E2

are valoarea 0 daca ambele expresii E1 si E2 la care se aplica operatorul || au valoarea zero. In rest, expresia de mai sus are valoarea 1.

Operatorii logici binari (&& si ||) se evalueaza de la stanga la dreapta. Daca la evaluarea unei expresii se ajunge intr-un punct in care se cunoaste valoarea de adevar (fals sau adevarat) a intregii expresii, atunci restul expresiei, aflata in dreapta punctului respectiv, nu se mai evaluaza.

Exemple:

1.

!a&&b

Daca a are valoarea 0 si b este diferit de 0, atunci expresia de mai sus are valoarea 1 (adevarat).

Intr-adevar, daca a are valoarea 0, atunci !a are valoarea 1.

Daca b este diferit de zero, atunci ambii operanzi ai operatorului && sunt diferiti de 0 si deci intreaga expresie are valoarea 1.

2.

!a||b

Aceasta expresie are valoarea 0 daca a are valoarea diferita de 0, iar b are valoarea 0. In acest caz, !a are valoarea 0 si deci ambii operanzi ai operatorului || au valoarea 0. Conform definitiei operatorului ||, rezulta ca intreaga expresie are valoarea 0.

3.

!a&&b||!b&&a

Aceasta expresie are valoarea 0 daca a si b au ambii valoarea 0, sau ambii sunt diferiti de 0. In caz contrar, expresia are valoarea 1. Acest lucru rezulta din tabela de mai jos:

a b !a !b !a&&b !b&&a !a&&b||!b&&a
0 0 1 1 0 0 0
diferit de zero diferit de zero 0 0 0 0 0
diferit de zero 0 0 1 0 1 1
0 diferit de zero 1 0 1 0 1

Din cele de mai sus rezulta ca expresia !a&&b||!b&&a realizeaza sau logic exclusiv intre a si b.

Pentru a=0 si b diferit de 0, expresia de mai sus se evalueaza astfel:

  1. se evalueaza !a si se obtine valoarea 1;
  2. se aplica operatorul si logic la !a si b si se obtine 1.

Deoarece !a&&b este legat de restul operatiei prin operatorul sau logic, rezulta ca in acest moment se poate afirma ca intreaga expresie este adevarata (are valoarea 1). De aceea, in acest caz nu se mai evalueaza restul expresiei, adica termenul !b&&a.

Exercitii:

3.11. Sa se scrie un program care citeste un numar si afiseaza 1 daca numarul respectiv apartine intervalului [-1000, 1000] si 0 in caz contrar.

Daca notam cu a numarul citit, atunci el trebuie sa satisfaca simultan relatiile: a >= -1000 si a <= 1000.

Acest fapt se poate exprima cu ajutorul expresiei: a >= -1000 && a <= 1000.

#include <stdio.h>

main()
{
    double a;

    scanf("%lf\n", &a);
    printf("a = %g\t%d\n", a, a >= -1000 && a <= 1000);
}

3.12. Sa se scrie un program care citeste un intreg din intervalul [1600, 4900], ce reprezinta un an calendaristic, afiseaza 1 daca anul este bisect si 0 in caz contrar sau daca anul nu apartine intervalului indicat.

Un an din calendarul gregorian este bisect daca este multiplu de 4 si nu este multiplu de 100, sau daca este multiplu de 400. Aceasta regula este valabila pentru anii care nu sunt anteriori anului 1600.

Calendarul gregorian a fost introdus pentru ca anul iulian a fost prea lung.

Conform calendarului iulian, un an era bisect daca era divizibil cu 4. Din aceasta cauza, la 133 de ani se inregistreaza o diferenta de o zi fata de anul tropic. In felul acesta, in anul 1582 s-a constatat o diferenta de 10 zile intarziere si s-a hotarat corectarea diferentei respective convenind ca dupa ziua de joi 4 octomrie 1582 sa urmeze ziua de vineri 15 octombrie 1582. De asemenea, s-a stabilit durata unui an calendaristic sa fie:

365 + 1/4 - 1/100 + 1/400 = 365,2425 zile

In aceasta expresie termenii au semnificatia:

Calendarul gregorian, avand durata anului egala cu 365,2425, are o eroare de aproximativ 26 de secunde. Aceasta inseamna ca regula indicata mai sus pentru a stabili anii bisecti (care au 366 de zile) este valabila pentru anii urmatori anului 1582 si care nu sunt ulteriori anului 4900.

Intr-adevar, eroare de 26 de secunde dintr-un an gregorian devine o zi abia dupa aproximativ 3323 de ani, deci dupa anul 4900 (1582 + 3323 = 4905). De aceea, regula de mai sus se poate aplica pentru anii din intervalul [1600, 4900].

Daca notam cu an anul calendaristic, atunci el este bisect daca de exemplu:

an%4 == 0 (an este multiplu de 4)

si

an%100! = 0 (an nu este multiplu de 100)

Deci anul este bisect daca expresia (1):

an%4 == 0 && an%100 != 0

este adevarata. Deasemenea, anul este bisect si in cazul in care expresia (2):

an%400! == 0 (an este multiplu de 400)

este adevarata. Deci anul este bisect daca este adevarata expresia (1) sau (2), adica daca este adevarata expresia:

an%4 == 0 && an%100 != 0 || an%400 == 0
#include <stdio.h>

main()
{
    int an;

    scanf("%d\n", &an);
    printf("an = %d\t%d\n", an, an >= 1600 && an <= 4900 && an%4 == 0 && an%100 != 0 || an%400 == 0);
}

3.12. Sa se scrie un program care citeste un intreg din intervalul [1600, 4900] ce reprezinta un an calendaristic si afiseaza numarul de zile din anul respectiv.

#include <stdio.h>

main()
{
    int an;

    scanf("%d\n", &an);
    printf("anul = %d are %d zile\n", an, 365 + (an%4 == 0 && an%100 != 0 || an%400 == 0));
}

Observatie: In acest program se considera ca anul tastat la terminalul standard apartine intervalului [1600, 4900].

3.2.6. Operatori logici pe biti