Sunteți pe pagina 1din 44

OPERATORI ŞI EXPRESII

Curs 4
CUPRINS

1. Noţiuni introductive
2. Operatori aritmetici
3. Operatori relaţionali
4. Operatori logici
5. Operatori de atribuire
6. Operatorul de conversie explicită
7. Operatorul de determinare a dimensiunii
8. Operatori paranteză
9. Operatorul condiţional
10. Operatorul virgulă
11. Expresii
2
1. NOŢIUNI INTRODUCTIVE
 Expresie: unul sau mai mulţi operanzi legaţi prin operatori

 Operanzii: nume de constante, de constante simbolice, de


variabile simple, de tablouri, de structuri, de tipuri de date,
de funcţii, elemente de tablou, elemente de structuri,
expresii incluse între paranteze rotunde
 unui operand îi corespunde un anumit tip şi o anumită valoare

 Operatorii: simboluri ce specifică operaţiile de efectuat


asupra operanzilor
 în urma aplicării unui operator se obţine un rezultat
 pot fi :
 unari: se aplică unui singur operand

 binari: implică doi operanzi

 ternar: trei operanzi 3


 pot fi: aritmetici, relaţionali, logici, etc.
 C++ permite supraîncărcarea operatorilor

 O expresie poate folosi operatori din clase diferite. In


evaluarea lor se ține cont de:
 Precedență (prioritate) – ordinea de efectuare a
operațiilor într-o expresie cu diverși operatori
 Asociativitate – ordinea de efectuare a operațiilor într-
o secvență de operații cu aceiași prioritate
 Regula conversiilor implicite – la operator binar
operand de tip inferior convertit la tip superior

4
2. OPERATORI ARITMETICI
 Operatori unari :
 + : fără efect
 - : negativare
 exemple : -123.45; -a; -(a+b);

 Operatori binari :
 multiplicativi: * (înmulţire), /(împărţire), %(modulo)
 aditivi: +(adunare), -(scădere)
Observaţii:
 nu există operatori diferiți pentru tipuri diferite (int, float,
double)
 operatorul modulo (%) se foloseşte numai cu tipul int -
restul împărţirii întregi
 operatorul div (/) aplicat între operanzi de tip întreg are ca
rezultat partea întreagă a rezultatului împărțirii (câtul
împărțirii întregi) 5
Exemple :
int a=7, b=2;

int c=a/b; // c=3


int r=a%b; // r=1;

float f=1.234f;
float rez= f / b; // rez= 0.617
float fr= f%b; // EROARE, operanzii nu sunt intregi

6
3. OPERATORI RELAŢIONALI
 Sunt operatori binari
 Testează relaţia dintre operanzi:
operand1 operator_relational operand2

 Operanzii pot fi aritmetici sau pointeri

 Tipul rezultatului are tipul int(C) sau int-bool (C++):


 dacă relaţia este adevărată (!=0) rezultatul este 1 (True)
 în caz contrar rezultatul este 0 (False)

 Tipuri: <, <=, >, >=, ==, !=

7
OPERATORI RELAŢIONALI

 Exemple:

int x, y;
x = 0; y = 0;
// bool ok=true;

cout << "x < y: " << (x < y) << '\n’; // x<y: 0 (false)
cout << "x > y: " << (x > y) << '\n'; // x>y: 0 (false)
cout << "x <= y: " << (x <= y) << '\n’; // x<=y: 1 (true)
cout << "x == y: " << (x == y) << '\n’; // x==y: 1 (true)

// cout<<ok<< "\n"; // 1
//cout<<boolalpha<<ok<< "\n"; // true

8
4. OPERATORI LOGICI
 Operatori logici pe operand

 negaţie logică ‘!’ (unar):


 !operand
 !operand = 0 (false) dacă operand != 0 (true)

 !operand = 1 (true) dacă operand == 0 (false)

Obs: In C++ exista ca alternativa la folosirea operatorului ! cuvantul


cheie not

 SI logic ‘&&’ (binar):


 operand1 && operand2
 are valoarea 1 (true) dacă ambii operanzi sunt nenuli
(true),
 altfel are valoarea 0 (false) 9
 SAU logic ‘||’ (binar):
 operand1 || operand2
 are valoarea 0 (false) dacă ambii operanzi au valoarea zero
(false),
 altfel are valoarea 1 (true)

 Exemplu :
int x = 7, y = 0;
printf("!x: %d\n" , !x) ; // !x=0
printf(" x && y: %d\n", x && y); // x && y: 0
printf(" x || y: %d\n", x || y); // x || y: 1
printf("x>y: %d\n", x>y); // x>y: 1
printf("!(x>y): %d\n", !(x > y)); // !(x>y):0

Obs: 1) operatorul && este mai prioritar decat ||


2) In C++ exista ca alternativa la folosirea operatorului && cuvantul
10
cheie and si pentru folosirea operatorului || cuvantul cheie or
 Operatori logici pe biţi
 se aplică datelor de tip întreg, bit cu bit

 complement faţă de unu (C1) ‘~’


 ~operand

Exemplu:
int x= 51;
Reprezentarea in binar: x = 00110011
atunci ~x= 11001100 (-52)

Obs: In C++ exista ca alternativa la folosirea


11
operatorului ~ cuvantul cheie compl
 deplasare stânga ‘<<‘
operand1 << operand2
 deplasare stânga a valorii primului operand cu un

nr. de poziţii egal cu valoarea celui de-al doilea


operand
 pe poziţiile libere din dreapta se introduc biţi 0, iar

biţii din stânga, corespunzători valorii deplasării, se


pierd
 echivalent cu o înmulţire cu o putere a lui 2 :

a << 2 → a*4
a = 10 = 00001010
a<< 2 = 00101000 = 40 = 10*22

12
 Observaţie: se pot pierde sau altera date
a = 42 = 00101010
• (considerând valoarea întreagă
reprezentată pe un octet)

a<< 3 = 01010000 = 70 ( ≠ 336) !!!

13
 deplasare dreapta ‘>>’
 operand1 >> operand2

 deplasarea dreapta a valorii primului operand cu un


nr. de poziţii egal cu valoarea celui de-al doilea
operand
 pentru biţii din stânga se face extensie de semn:

 pentru numere pozitive se introduc biţi 0


 pentru numere negative se introduc biţi 1
 biţii din dreapta se pierd

 echivalent cu o împărţire cu o putere a lui 2 :

a >> 3 → a/8

14
Exemple:
a = 24 = 00011000
a>> 2 = 00000110 = 6 = 24/22

 a =-88 = 10101000
 a>>3 = 11110101 = -11 = 88/ 23

15
 ŞI pe biţi ‘&’:
 operand1 & operand2

 se execută operaţia logică ŞI, bit cu bit

 se foloseşte la operaţia de "mascare"

 Exemple: & 0 1
n =0x5a 0 0 0
n & 0x02
1 0 1
01011010 &
00000010 (masca)
-------------
00000010
 Păstrează bitul 1, restul sunt șterși în rezultat
16
n =0x5a
n & 0x0f
01011010 &
00001111 (masca)
-------------
00001010
şterge (semi)octetul mai semnificativ şi
păstrează neschimbat (semi)octetul cel
mai puţin semnificativ

Obs: In C++ exista ca alternativa la folosirea


operatorului & cuvantul cheie bitand

17
 SAU pe biţi ‘|’: | 0 1
 operand1 | operand2

 se execută operaţia logică SAU bit cu 0 0 1


bit;
1 1 1
 se foloseşte pentru a seta diferiţi biţi
n = 0x5a
n|1
01011010 |
00000001
-------------
01011011

pune valoarea 1 pe bitul 0 indiferent


de starea biţilor din n
18
n = 0x5a
n|5
01011010 |
00000101 (masca)
-------------
01011111

pune valoarea 1 pe biţii corespunzători


măştii, indiferent de starea biţilor din n

Obs: In C++ exista ca alternativa la folosirea


operatorului | cuvantul cheie bitor

19
 SAU EXCLUSIV pe biţi ‘^’
 operand1 ^ operand2

 se execută operaţia logică SAU EXCUSIV, bit cu bit

 se foloseşte pentru a anula sau seta diferiţi biţi


n = 0x5a
n^1
^ 0 1
01011010 ^
00000001 0 0 1
-------------
1 1 0
010110112 = 0x5b

20
n = 0x5b 01011011 ^
00000001
-------------
010110102 = 0x5a

 pune pe 0 ultimul bit dacă n este impar (rezultat par) şi


pune pe 1 utimul bit dacă n este par (rezultat impar)

Obs: In C++ exista ca alternativa la folosirea


operatorului ^ cuvantul cheie xor

21
5. OPERATORI DE ATRIBUIRE (ASIGNARE)
 Atribuirea sau înscrierea unei valori într-o variabilă este
operaţia care apare cel mai des

 Acest lucru se face cu operatorul de atribuire (=)

22
 Atribuire simplă
 Forma:
var = expresie;
unde var poate fi o variabilă simplă sau o referinţă

 Efect:
 valoarea expresiei este înscrisă în variabilă

înlocuind valoarea veche

 Atribuirea are ca rezultat valoarea variabilei după


înscriere:
 ca urmare este posibilă atribuirea multiplă ( D → S):

varn = varn-1 = ... = var2 = var1 = expresie;


 mai întâi : var1 = expresie, apoi var2 = var1 ... 23
 Valoarea expresiei se converteşte la tipul variabilei:
 în unele cazuri, aceste conversii determină pierderi

de informaţie (conversii degradante) şi anume atunci


când domeniul de valori al expresiei este mai mare
decât domeniul de valori al tipului variabilei

 Exemplu:
 de la int la char: se pierde octetul (octetii) m.s.,

ramane octetul cel mai putin semnificativ


 de la float la int: se face trunchiere

24
 Atribuire compusă:
 Forma: operator=
 unde operatorul poate fi unul aritmetic binar sau unul

logic pe biţi

 Tipuri:
/=, %=, *=, -=, +=, <<=, >>=, &=, |=, ^=

 Structura:
var operator= expresie; <=> var = var operator expresie;

 Motivaţie:
 cod generat mai eficient prin eliminarea unui acces la
memorie
25
 Exemple: n += 9; <=> n = n + 9
n *= 5; <=> n = n * 5

// Interschimbarea valorilor a 2 variabile intregi


int x=4, y=10;
x^=y^=x^=y; // x=10, y=4, evaluare D → S
x^=y; // x=x^y= 4^10= 14 ( 11102 )
y^=x; // y=y^x= 10^14= 4 ( 01002 )
x^=y; // x=x^y= 14 ^ 4= 10 (10102 )

Cerința: scrieti o aplicatie C in care interschimbati valorile a doua


variabile de tip intreg prin urmatoarele metode: metoda celor 3
26
pahare, operatorul sau-exclusiv si operatii artitmetice (+ si -).
 Incrementare şi decrementare
 Forme: ++, -- (unari)
 Modifică operandul asupra căruia acţionează
 Variante:
 prefixaţi (++op, --op):

 operaţia de incrementare/decrementare se aplică


înainte de folosirea operandului în contextul curent

 postfixaţi (op++, op--):


 operaţia specificată se aplică după folosirea
operandului în contextul curent

 Exemplu:
int x, y;
y = 4;
x = ++y; // x=5; y=5; 27

x = y--; // x=5, y=4;


 Motivaţie:
 compilatorul generează cod mai eficient pentru acest

tip de operaţie decât pentru o operaţie de


adunare/scădere echivalentă, datorită existenţei unor
instrucţiuni dedicate (inc/dec) în setul de instrucţiuni al
procesoarelor (i++ comparativ cu i=i+1 sau cu i+=1)

28
6. OPERATORUL DE CONVERSIE EXPLICITĂ (CAST)
 Forma:
(tip)operand
 Rezultat:
 valoarea operandului convertită la noul tip în operația
curentă
 nu se modifică tipul sau valoarea operandului
 Exemplu:
int i;
float a, r;
...
i = 5;
a = 2.0f;
r = i/(int)a; // r=2.0; !!! Variabila a ramane de tip
29
float si valoare 2.0;
7. OPERATORUL DE DETERMINARE A DIMENSIUNII

 Forma:
sizeof(tip) - dimensiunea în octeți a tipului respectiv
sizeof expresie sau sizeof(expresie)
 dacă expresie este numele unei variabile, rezultatul
este numărul de octeţi alocaţi pentru variabila
respectivă
 dacă expresie este numele unui tablou, rezultatul este
numărul de octeţi alocaţi pentru tablou
 dacă expresie este numele unei structuri, rezultatul
este numărul de octeţi alocaţi pentru structură
30
 Exemplu:
// in Visual Studio tipul int si tipul float sunt reprezentate
pe 4 octeti
int i, n;
float tab[10];
...
i = sizeof(int); // i va avea valoarea 4
i = sizeof n; // i = 4
i = sizeof tab[5]; // i = 4
i = sizeof tab; // i = 40
n = sizeof(tab)/sizeof(float) // n = 10

31
8. OPERATORI DE ADRESARE(&, REFERENTIERE)
SI DE INDIRECTARE (*, DEREFERENTIERE)

& operator de adresare, se aplică pentru a determina


adresa de început a zonei de memorie alocate unei date.
(Rezultatul e un pointer la operand)
* operator de indirectare, permite accesarea unei valori
indirect prin intermediul unui pointer. Tipul rezultatului este
tipul adresat de operandul pointer
 - cei doi operatori se anulează reciproc unul după altul
 Exemplu:
int x, *pa;
int a[20];
pa=&a[5];
x=*pa; echivalent cu x=a[5];
32
9. OPERATORI PARANTEZĂ
 Paranteze rotunde ( )
 Se folosesc pentru:
 a include o expresie care urmează a fi evaluată

 rezultatului evaluării nu i se pot aplica operanzi de


incrementare, decrementare, adresare;
 apel de funcţii
 Exemplu: int i, j, k;
...
i = (j+k) - 5;
suma(i, j);
 Paranteze pătrate [ ]
 Se mai numesc şi operatori de indexare
 Se folosesc la declararea unui tablou şi la referirea
unui element de tablou
 Exemplu: tab[i]; //elem. de pe pozitia i din tablou 33
tab[3];
tab[i*j - k];
9. OPERATORUL CONDIŢIONAL (? ŞI :)
 Permit construirea de expresii a căror valoare să depindă
de valoarea unei condiţii
 Condiţia este tot o expresie care poate avea o valoare
nenulă (true) sau poate avea valoarea zero (false)
 Forma: operand1 ? operand2 : operand3
 Evaluare:
 se determină valoarea pentru operand1;
 rezultatul poate fi de tipuri diferite
 dacă operand1 != 0 atunci valoarea şi tipul expresiei
condiţionale coincide cu operand2
 altfel coincide cu operand3

34
 Exemplu:
int i, j, k;
...
i = (j < 0) ? (-j) : (j); // i = abs(j);
k = (i >= j) ? i : j; // k = max(i,j)

35
10. OPERATORUL VIRGULĂ
 Virgula este un simbol cu dublă semnificaţie în limbajul
C/C++:
 cel mai frecvent apare ca delimitator în declaraţii de
date sau în lista de parametri a unei funcţii

 Ca operator, leagă două expresii în una singură, astfel:


expr1, expr2
 !!! valoarea şi tipul rezultatului coincide cu valoarea şi
tipul ultimei expresii

 Se foloseşte la calcule complexe exprimate prin mai


multe expresii 36
 Exemplu:
int a, b, c;
a = 10;
c = (b = a-6, a/2); // b=4, c=5
cout << "b = "<< b << "\n ";
cout << "c = " << c << "\n ";

 Dacă pot apărea ambiguităţi se recomandă folosirea


parantezelor

 Mai sunt şi alţi operatori care vor fi introduşi în alte


capitole

37
11. EXPRESII
 Expresiile se evaluează pe baza unui set de reguli, care
precizează:
 precedenţa
 asociativitatea operatorilor
 conversiile aplicate operanzilor

 Precedenţa (prioritatea) dă ordinea de efectuare a


operaţiilor

 Asociativitatea indică ordinea de efectuare a operaţiilor


care au aceeaşi precedenţă
38
 Regulile de conversie asigură stabilirea unui tip comun
pentru ambii operanzi, la fiecare operaţie care solicită
acest lucru şi în care tipurile diferă

 Ordinea de evaluare dată de precedenţă şi asociativitate


poate fi modificată grupând operaţiile cu ajutorul
parantezelor

 Spaţiile din interiorul expresiilor şi parantezele


redundante sunt ignorate, dar folosesc la creşterea
clarităţii programelor

39
ORDINEA DE EVALUARE A EXPRESIILOR
 Operatori Asociativitate
( ), [ ] S->D
!, ~, +, -, ++, --, &, *, cast, sizeof D->S
*, /, % S->D
+, - S->D
<<, >> S->D
<, <=, >, >= S->D
==, != S->D
& S->D
^ S->D
| S->D
&& S->D
|| S->D
?: D->S
40
=, *=, /=, %=, +=, -=, &=, ^=, |=, <<=, >>= D->S
, S->D
CONVERSII DE TIP ÎN EXPRESII (IMPLICITE)
 Regula de bază:
 se promovează tipul cu domeniu de valori mai mic
către tipul cu domeniul de valori mai mare

 Pentru tipurile întregi:


char -> int octet m.s. 0 sau extensie
de semn
unsigned char -> int octet m.s. 0
signed char -> int octet m.s. cu extensie de
semn
short -> int aceeaşi valoare
unsigned short -> int aceeaşi valoare
41
 Pentru tipurile reale:
 Dacă unul din operanzi este de tip float și celălalt
este de tip întreg, ultimul este convertit convertit la
tipul float

 Dacă unul din operanzi este de tip double, iar celălalt


este de tip float sau un tip întreg, ultimul este
convertit convertit la tipul double

 Dacă unul din operanzi este de tip long double, iar


celălalt este de tip float, double sau un tip întreg,
ultimul este convertit convertit la tipul long double

42
DUPA ACEST CURS STIM…

 Care sunt operanzii C/C++


 Cum se utilizează fiecare operand şi care este
efectul lui
 Ce este o expresie in C/C++

 Regulile de evaluare a expresiilor C/C++

 Regulile de conversie implicită în C/C++

43
44

S-ar putea să vă placă și