Operatori

Odată lămurită discuţia despre variabile şi constante, este cazul să vorbit şi despre operaţiile care pot fi realizate cu acestea. Pentru simplificare, operaţiile uzuale au asociaţi diferiţi operatori. Limbajul C++ are mai multe categorii de operatori, în funcţie de specificul lor, astfel:

* Operatorul de atribuire ( = )
* Operatori Aritmetici ( +, -, \*, /, % )
* Operatori relaţionali ( ==, !=, >, <, >=, <= )
* Operatori  logici ( !, &&, || )
* Operatori pe biţi ( &, |, ^, ~, <<, >> )
* Operatori speciali
* Operatorul condiţional ( ? )
* Operatorul virgulă ( , )
* Operatori compuşi (+=, -=, \*=, /=, %=, >>=, <<=, &=, ^=, |=)
* Operatorii de incrementare / decrementare (++, --)
* Operatorii de conversie explicită
* Operatorul sizeof

### **Operatorul de atribuire**

Acest operator are rolul de a furniza o valoare unei variabile. Spre exemplu, **x = 5;**va face ca variabila x să primească valoarea 5.
De reţinut este că acest operator acţionează de la dreapta la stânga şi nu invers. Astfel, a=b este complet diferit de b=a.
Forma generală a acestui operator este

```
varibilă=expresie;
```

unde expresie poate fi o simplă constantă, o altă variabilă, sau o expresie în care sunt folosiţi diferiţi alţi operatori şi care va furniza valoarea varibilei după evaluarea ei.
Un caz special este cel în care operanzii nu sunt de acelaşi tip, ca în exemplul următor:

```
float a=6.5;
int b;
b=a;
```

În acest caz se produce o conversie implicită, iar valoarea pe care variabila b o va avea se obţine prin rotunjirea valorii variabilei a. Acest lucru nu este posibil între toate tipurile.
Un alt exemplu remarcabil de conversii implicite apare în cazul utilizării tipului de date char.

```
char a=’a’, c;
int i=1, b;
c=a+i;
b=a+i;
cout<<b;
cout<<c;
```

Deşi expresia din dreapta este aceeaşi, evaluarea ei este diferită, în funcţie de tipul variabilei căreia îi este transmisă. Astfel, pentru c se va afişa valoarea ‘b’, pe când, pentru b se va afişa valoarea 98, corespunzătoare codului ASCII asociat caracterului ‘a’ la care s-a adăugat valoarea 1. Menţionăm că, dacă în exemplul de mai sus am face afişarea directă a expresiei, am obţine o valoare numerică, adică 98.

### Operatori aritmetici ( +, -, \*, /, % )

Semnificaţia acestor operatori este, în mare măsură cunoscută de la matematică. Evident, „+” semnifică adunarea, „- ” scăderea, „\*”  înmulţirea, iar „/” împărţirea.
Putem scrie cu ajutorul lor expresii de forma:

 suma=termen1+termen2;

```
dif=term_1+term+2
e= ((a+b)*3-5)/10;

```

se impune o precizare în cazul a doi operatori mai puţin uzuali, anume / şi %. Semnificaţiile lor sunt: / reprezintă câtul împărţirii întregi, iar % restul acesteia. Utilizarea lor este permisă doar în cazul tipurilor întregi.
Să analizăm următoarele exemple !

 int a=10, b=3, c, d;

```
c=a/b;
d=a%b;

```

În acest caz, valoarea variabilei c va fi 3, iar a variabilei d va fi 1. În următorul exemplu, însă, c va avea valoarea 3.33333, pentru că oepratorul / se va comporta ca operator de împărţire reală, iar d nu va fi calculat, deoarece operatorul % nu este definit în tipurile întregi, iar compilatorul va ridica eroare.

 float a=10, c;

```
int b=3, d;
c=a/b;
d=a%b;

```

operaţia de atribuire poate fi evaluată. Acest lucru înseamnă că expresia în care aceasta apare este echivalentă cu valoarea atribuită. Spre exemplu, în construcţia:

 x=10;

```
z=x+(y=5);

```

variabila z va avea valoarea 15.  Desigur, secvența poate fi scrisă ca:

 x=10;

```
y=5;
z=x+10;

```

O  formă aparte a acestui operator permite atribuirea acceleaşi valori mai multor variabile, într-o construcţie de forma:

 a=b=expresie;

##### **Operatori relaţionali ( ==, !=, >, <, >=, <= )**

Acest tip de operatori produce, la evaluare, valorile numerice 0 sau 1, după cum expresia are valoarea de adevăr false sau true. Iată câteva exemple de utilizare a lor:

 int a=6, b=4;

```
bool c;
c=(a==b);

```

În urma execuţiei, variabila c va avea valoarea 0.

 int a=6, b=4, c=24;

```
cout<<(a*b>=c);

```

Rezultatul executării acestei secvenţe ar fi, evident 1, deoarece produsul a\*b este mai mare sau egal cu 24, adic[ valoarea variabilei c. Următorul exemplu ar putea să vă deruteze:

 int a=6, b=4;

```
cout<<((a=4)==b);

```

Rezultatul execuţiei este 1. Amintiţi-vă că atribuirea este evaluată prin valoarea expresiei din dreapta. Deci, termenul stâng al expresiei va avea valoarea 4, fiind egal cu valoarea lui b.

##### **Operatori  logici ( !, &&, || )**

Operatorii logici codifică operaţiile logice: negaţie, conjuncţie şi disjuncţie.  Înainte de a stabili modul de lucru al acestor operatori trebuie să precizăm că, în expresii, valoarea 0 este asociată cu valoarea de adevăr false, iar orice valoare diferită de 0 cu true. Astfel, spre exemplu, !(7) va avea valoarea 0.

După cum ziceam, ! corespunde operaţiei logice de negaţie, astfel că putem întocmi următoarea tabelă de adevăr:
Asemănător, && corespunde operaţiei de conjuncţie (AND) şi are următoarea tabelă de adevăr:

Operatorul || corespunde operaţiei de disjuncţie (OR) şi are, la rândul său, tabela de adevăr asociată:

Trebuie precizat că atât operatorl de conjucţie, cât şi cel de disjuncţie evaluează de la stânga la dreapta şi, în cazul în care se poate decide valoarea expresiei doar din evaluarea primului termen, acest proces este întrerupt. Situaţia poate duce la numite complicaţii dacă, spre exemplu, al doilea termen conţine o secvenţa de incrementare a unei variabile. Mai precis, dacă termenul stâng are valoarea 0, operatorul && va evalua direct expresia ca fiind 0. Tot astfel, operatorul|| va evalua 1, dacă termenul din stânga este 1. În exemplul următor am construit o situaţie în care acest mecanism produce un scurt-circuit, oprind evaluarea termenului din dreapta.

 if ( (i<10) && (++i<n) ) {… }

##### **Operatori pe biţi ( &, |, ^, ~, <<, >> )**

Asemănători operatorilor logici, aceşti operatori acţionează asupra reprezentărilor binare ale variabilelor din tipurile întregi, producând efectul operaţiilor logice la nivelul biţilor omologi. Pentru a exemplifica, precizăm mai întâi semnificaţiile lor.

Vom folosi pentru exemplificare o reprezentare în tipul de date unsigned int, deoarece codul de reprezentare este unul simplu, de convertire directă în baza 2. Să considerăm declarările:
unsigned int a=2, b=3;
Conform codului de reprezentare, a va fi memorat sub forma 000…10, iar b sub forma 000…11. Reamintim că tipul unsigned int are dimensiunea 4, deci înainte de cifrele 10, în reprezentarea lui a, respectiv 11, din reprezentarea lui b, sunt 30 de cifre 0.

Aplicarea operatorului ~ unei variabile duce la transformarea în complementar a tuturor cifrelor din reprezentarea sa binară. Astfel, ~a duce la crearea reprezentării 111...101, corespunzătoare numărului 4294967293.

##### **Operatori speciali**

###### **a. operatorul condiţional ?**

Este folosit pentru a evalua o expresie şi a returna, în funcţie de rezultatul evaluării, o anumită valoare. Forma generală este:

<expresie> ? <valoare 1 > :  <valoare 2>
Dacă expresia este evaluată la TRUE, atunci se va returna valoarea 1, altfel va fi returnată valoarea 2.
Iată câteva exemple:

 **2>5 ? 2 : 5;** // întreaga sintaxă va fi înlocuită prin 5, deoarece 2>5 este evaluată prin fals, ceea ce duce la înlocuirea prin termenul aflat în dreapta

```
**4==2+2 ? “da”: “nu”;** //se va evalua prin “da”, deoarece expresia 4==2+2 este evaluată ca adevărată şi, deci, toată sintaxa va fi înlocuită prin stringul “da”
**x>y ? x :y;** // va fi înlocuită prin maximul dintre valorile celor două variabile

```

În funcţie de tipul valorii prin care va fi înlocuită expresia, aceasta va putea fi folosită în varii operaţii, precum atribuire, afişare etc.
În următorul exemplu, variabila c va primi valoarea variabile b, care este de acelaşi tip cu ea:

 int a=5,  b=7, c;

```
 c = (a>b) ? a : b;
În exemplul:
char x;
x=(4==2+2 ? 'y': 'n');
cout<<x;

```

expresia este înlocuită prin caracterul ‘y’ care va fi atribuit variabilei y.

###### **b. Operatorul virgulă ( , )**

Este utilizat acolo unde, în mod normal, se foloseşte o singură expresie. Prin utilizarea lui, este considerată expresia cea mai din dreapta. Spre exemplu, în construcţia x=(y=1. y+2); , rezultatul este, evident, atribuirea unei valori variabilei x. Aceasta este obţinută plecând de la vaoarea 1, a variabilei y, căreia i se adaugă 2 prin expresia y+2.

###### **c. Operatori compuşi (+=, -=, \*=, /=, %=, >>=, <<=, &=, ^=, |=)**

Aceşti operatori “prescurtează” sintaxe mai elaborate, după cum urmează:
x+=2 este echivalentul lui x=x+2, y-=5 este echivalentul lui y=y-5 şamd.

###### **d. Operatorii de incrementare / decrementare (++, --)**

Expresiile de incrementare / decrementare pot fi scurtate prin folosirea acestor operatori, după cum urmează: pentru incrementare (creşterea cu o unitate a valorii unei variabile) se poate folosi operatorul ++, iar pentru decrementare, operatorul --, ca în exemplul:

 int x=1, y=5;

```
x++;
y--;

```

În urma executării codului, variabila x va avea valoarea 2, iar variabila y, valoarea 4.
Un aspect particular trebuie subliniat pentru cazurile în care aceşti operatori sunt utilizaţi în construcţii mai elaborate. Spre exemplu, în urma executării secvenţei de cod:

 int x=10, y;

```
y=x++;

```

variabila x va avea valoarea 11, iar variabila y va lua valoarea 10.
Prin construcţia

 int x=10, y;

```
y=++x;

```

variabila x va avea valoarea 11, iar variabila y va lua valoarea 11.

###### **e. Operatorii de conversie explicită**

Operatorii de conversie explicită permit convertirea unei valori de la un tip la altul. Desigur, acest lucru este posibil şi prin conversii implicite, dar în situaţia în care dorim un control mai bun asupra tipurilor de date vom folosi aceşti operatori.

Pentru utilizarea lor e posibilă sintaxa prin care expresia ce se doreşte convertită este cuprinsă între paranteze şi precedată de numele tipului la care se doreşte conversia.

 int n;

```
float p=3.1415;
n=int (p);

```

Desigur, în exemplul anterior valoarea variabilei p este truchiată la 3 şi atribuită, astfel, varibilei n.
Este acceptată, de asemenea, şi sintaxa n=(int) p; preluată din limbajul C.

###### **f. Operatorul sizeof**

Acest operator acceptă un singur operand, care poate fi numele unui tip sau al unei variabile şi returnează dimensiunea memoriei, în octeţi, pe care acesta o ocupă.
Spre exemplu, sintaxa:

 cout<<sizeof(char);

va duce la afişarea cifrei 1, care reprezintă dimensiunea tipului de date char.