Pentru a opera cu variabile și constante, vom folosi operatori. În funcție de numărul operanzilor, un operator poate fi unar, binar sau ternar. O expresie este o înșiruire de variabile, constante și operatori. Majoritatea expresiilor pot fi evaluate de compilator, returnând o valoare.

Operatorul de atribuire

Operatorul de atribuire (=) are rolul de a atribui o valoare unei variabile. De exemplu, după execuția instrucțiunii de mai jos, variabila x va avea valoarea 618. Întotdeauna operația de atribuire se desfășoară de la dreapta la stânga.

Operandul din dreapta poate fi de asemenea o variabilă, de exemplu:

În cazul acesta, variabila a primește valoarea variabilei b. Așadar, nicio modificare ulterioară a lui b nu va afecta valoarea lui a.

Operatorul de atribuire returnează valoarea atribuită primului operand.

De aceea, putem atribui mai multor variabile aceeași valoare în modul următor:

Operatorul de atribuire se mai numește operator de asignare. A nu se confunda cu operatorul ==, care testează egalitatea dintre operanzi!

Operatori aritmetici

Operatorii aritmetici efectuează operații matematice asupra operanzilor:

Operator Descriere Efect
+ adunare Returnează suma operanzilor.
- scădere Returnează diferența dintre operanzi. Primul este descăzutul, iar al doilea scăzătorul.
* înmulțire Returnează produsul dintre operanzi.
/ împărțire Returnează rezultatul împărțirii primului operand la al doilea. Dacă ambii sunt întregi, se va efectua împărțirea întreagă (se returnează câtul), altfel cea reală.
% modulo Returnează restul împărțirii primului operand la al doilea. Ambii operanzi trebuie să fie întregi.

Cum în matematică împărțirea la 0 nu are sens (nici măcar dacă deîmpărțitul este 0), x / 0 și x % 0 vor genera o eroare.

La fel ca în matematică, în evaluarea unei expresii se ține cont de ordinea efectuării operațiilor. La finalul articolului veți găsi o listă completă cu ordinea evaluării operatorilor din C++.

Tot ca în matematică, putem folosi paranteze rotunde ca să delimităm o parte din expresie pentru a-i crește prioritatea, sau doar pentru a o evidenția. În C++ nu putem folosi decât paranteze rotunde. Exemplu:

Operatori relaționali

Operatorii relaționali sunt folosiți pentru a testa o relație dintre valorile a două expresii. În C++, operatorii relaționali sunt:

Operator Descriere
== egal
!= diferit
< mai mic
> mai mare
<= mai mic sau egal
>= mai mare sau egal

Acești operatori returnează o valoare booleană. Exemple:

Testul de egalitate pentru numere reale

Cum numerele reale sunt stocate folosind virgulă mobilă, de la un anumit punct se pierde precizia. Adică, teste de genul 0.000001 == 0 vor fi evaluate uneori drept true.

Floating point error

De aceea, dacă trebuie să testăm egalitatea dintre două numere reale, e bine să implementăm o funcție de genul:

Operatori logici

În C++ există 3 operatori logici: ! (NOT, negație), && (AND, conjuncție) și || (OR, disjuncție). În evaluarea expresiilor ce conțin acești operatori, operanzii sunt reduși mai întâi la o valoare booleană, adică pentru o valoare nenulă se va folosi true, iar pentru una nulă, false. De ce spun o valoare nulă, și nu 0 direct? Nu pentru toate tipurile de date valoarea nulă este 0; de exemplu, pentru pointeri este nullptr.

Operatorul ! returnează valoarea booleană opusă celei la care se evaluează operandul. Exemple:

Operatorul && returnează true dacă ambii operanzi sunt true, altfel false.

a b a && b
true true true
true false false
false true false
false false false

Exemple:

Operatorul || returnează true dacă cel puțin unul dintre operanzi este true, altfel false.

a b a || b
true true true
true false true
false true true
false false false

Exemple:

Când vrem să testăm dacă trei variabile de același tip sunt egale, folosim operatorul &&:

Pentru a reține și mai ușor valorile returnate de cei doi operatori, putem asimila conjuncția cu înmulțirea dintre 0 și 1, iar disjuncția cu adunarea dintre 0 și 1, unde 0 este false și 1 este true.

Evaluarea expresiilor ce conțin && și || este foarte eficientă în C++. Într-o conjuncție, dacă operandul stâng este false, cel drept este ignorat, deoarece indiferent de valoarea lui, rezultatul va fi false. Similar, dacă într-o disjuncție operandul stâng este true, celălalt este ignorat și se returnează direct valoarea true.

Legile lui De Morgan

De Morgan a enunțat două legi logice foarte simple despre negarea unei propoziții compuse, sau a unei expresii în cazul nostru:

Acestea pot fi demonstrate dând valori binare lui a și b (sunt doar 4 combinații).

Operatorul ternar condițional ?:

Sintaxa unei expresii ce conține acest operator este:

Se evaluează expresie, și dacă aceasta este adevărată, se returnează expresie1, iar dacă nu, expresie2. Exemplu:

Operatori pe biți

Acești operatori lucrează la nivelul biților din reprezentarea întregilor. Operațiile pe biți sunt folosite pentru optimizarea multor algoritmi. Am abordat subiectul pe larg în acest articol.

Operator Descriere
& AND
| OR
^ XOR
~ NOT
<< SHIFT LEFT (SHL)
>> SHIFT RIGHT (SHR)

Operatori compuși de atribuire

Operatorii compuși de atribuire (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=) ne ajută să scriem mai puțin cod, dar și optimizează operațiile efectuate asupra variabilelor. Exemple:

De ce acești operatori sunt eficienți? De exemplu, în x = x + y, întâi se calculează x + y, iar apoi se atribuie această valoare lui x, pe când în x += y, adunarea se efectuează direct pe x.

Operatorii de incrementare și decrementare

Incrementarea reprezintă adunarea lui 1 unui număr, iar decrementarea, scăderea lui 1 din acesta. De multe ori avem nevoie de efectuarea uneia dintre aceste operații înainte sau după altă operație, și de aceea acești operatori pot fi folosiți atât sub formă de prefix, cât și de sufix.

În expresia x = ++a, întâi a se incrementează, iar apoi lui x i se atribuie valoarea lui a. În schimb, în expresia x = a++, întâi x primește valoarea lui a, iar apoi a se incrementează. Similar pentru operatorul de decrementare (--). Exemple:

Dacă vrem să incrementăm variabila a, putem folosi la fel de bine oricare dintre cele 4 instrucțiuni de mai jos, mai ales că de ceva timp compilatoarele sunt atât de inteligente încât înlocuiesc bucăți de cod cu cele mai eficiente variante ale lor din punct de vedere semantic (dar asta nu înseamnă că optimizează și complexitatea algoritmilor).

Operatorul de casting (conversie a tipului)

Operatorul de casting convertește o valoare de un anumit tip în altul. Acest operator se pune înaintea expresiei respective și are sintaxa (tip). Exemple:

Dintr-un tip real într-unul întreg, conversia se face prin trunchiere, nu prin rotunjire. Deci atât 1.99, cât și 1.01, convertite la int, vor deveni 1.

În C++, cast-ul se mai poate efectua folosind notația funcțională tip(expresie).

Operatorul sizeof()

Am întâlnit deja acest operator în Variabile și tipuri de date în C++. Operatorul sizeof() poate lua ca parametru un tip sau o variabilă, și returnează mărimea în bytes a acestuia. Rezultatul este determinat întotdeauna înaintea execuției programului.

Operatorul virgulă

Operatorul virgulă este folosit pentru a separa mai multe expresii, concatenându-le. Operatorul va returna valoarea celei mai din dreapta expresii.

De obicei, acest operator este folosit când vrem să scriem o singură instrucțiune care să facă mai multe operații, într-o structură for de exemplu.

Ordinea evaluării operatorilor

Mai există niște operatori în limbajul C++, dar despre aceștia voi discuta în articolele următoare. Iată lista completă a operatorilor C++, de la cei cu cea mai mare prioritate în jos:

Prioritate Grup Operator Descriere Evaluare
1 Rezoluție :: operatorul de rezoluție stânga-dreapta
2 Sufix ++ -- sufix de incrementare/decrementare stânga-dreapta
() formă funcțională
[] subscript
. -> acces către membru
3 Prefix ++ -- prefix de incrementare/decrementare dreapta-stânga
~ ! NOT pe biți, NOT logic
+ - prefix unar
& * referință, dereferință
new delete alocare/dealocare de memorie
sizeof() sizeof()
(tip) casting
4 Pointer către membru .* ->* access către pointer al membrului stânga-dreapta
5 Înmulțire, împărțire * / % produs, raport, modulo stânga-dreapta
6 Adunare, scădere + - adunare, scădere stânga-dreapta
7 Shift pe biți << >> shift stânga, shift dreapta stânga-dreapta
8 Relațional < > <= >= operatori de comparație stânga-dreapta
9 Egalitate == != egalitate, inegalitate stânga-dreapta
10 AND pe biți & AND pe biți stânga-dreapta
11 XOR pe biți ^ XOR pe biți stânga-dreapta
12 OR pe biți | OR pe biți stânga-dreapta
13 Conjuncție && AND logic stânga-dreapta
14 Disjuncție || OR logic stânga-dreapta
15 Atribuire = *= /= %= += -=
>>= <<= &= ^= |=
operatori de atribuire dreapta-stânga
?: operatorul condițional
16 Concatenare , operatorul virgulă stânga-dreapta

Următorul articol din seria de tutoriale C++ este Citirea datelor din consolă și din fișiere în C++. Dacă aveți întrebări despre operatori și expresii în C++, adresați-le mai jos 🙂

Îți place conținutul acestui site?

Dacă vrei să mă susții în întreținerea server-ului și în a scrie mai multe articole de calitate pe acest blog, mă poți ajuta printr-o mică donație. Află aici cum o poți face!