Sunteți pe pagina 1din 12

Programarea calculatoarelor și limbaje de programare – notițe de curs/ Curs 6

Programarea calculatoarelor și limbaje de programare – Curs 6

IV. LIMBAJELE C și C++


IV.10 Operatori și expresii în limbajele C/C++……………….…….1

IV.10. Operatori și expresii în limbajele C/C++

Un operator este un simbol care arată ce operații se execută asupra unor


operanzi (termeni).
Un operand este o constantă, o variabilă, un nume de funcție sau o subexpresie
a cărei valoare este prelucrată direct de operator sau suportă în prealabil o conversie de
tip.
Operatorii, după numărul de operanzi asupra cărora se aplică pot fi: unari, binari
și ternari.
În funcție de tipul operanzilor asupra cărora se aplică, operatorii pot fi:
aritmetici, relaționali, binari, logici, etc.
Operatorii sunt împărțiți în clase de precedență (sau de prioritate). În fiecare
clasă de precedență este stabilită o regulă de asociativitate, care indică ordinea de
aplicare a operatorilor din clasa respectivă: de la stânga la dreapta sau de la dreapta la
stânga.
O expresie este o combinație validă de operatori și operanzi (constante,
variabile, apeluri de funcții, subexpresii). Prin evaluarea unei expresii se obține o
valoare rezultat. Tipul valorii rezultat depinde de tipul operanzilor și a operatorilor
folosiți.
Evaluarea unei expresii poate avea efecte colaterale, manifestate prin
modificarea valorii unor variabile.

1
Mădălina Roxana. Buneci

Conversii de tip.

Valorile pot fi convertite de la un tip la altul. Conversia poate fi implicită sau


realizată în mod explicit de către programator.

Conversii implicite de tip.


Conversiile implicite au loc atunci când este necesar ca operatorii și
argumentele funcțiilor să corespundă cu valorile așteptate pentru acestea.
Conversii aritmetice.

Când un operator binar se aplică între doi operanzi de tip diferit, are loc o
conversie implicită a tipului unuia dintre ei, și anume, operandul de tip “mai restrâns”
este convertit la tipul “mai larg” al celuilalt operand. Astfel în expresia f + i, operandul
int este convertit în float.

Operatorii aritmetici convertesc automat operanzii la un anumit tip, dacă


operanzii sunt de tip diferit. Se aplică următoarele reguli:

• operanzii char și short int se convertesc în int; operanzii float se convertesc în


double.

• dacă unul din operanzi este double restul operanzilor se convertesc în double
iar rezultatul este tot double.

• dacă unul din operanzi este long restul operanzilor se convertesc în long , iar
rezultatul este tot long.

• dacă unul din operanzi este unsigned restul operanzilor se convertesc în


unsigned , iar rezultatul este tot unsigned.

• dacă nu se aplică ultimele 3 reguli, atunci operanzii vor fi de tip int și rezultatul
de asemeni de tip int.

2
Programarea calculatoarelor și limbaje de programare – notițe de curs/ Curs 6

Operatori și expresii
Operatori
unari
binari
ternari
- precedență operatorilor
poate fi modificată prin utilizarea ( )
- asociativitate : la stânga, la dreapta
- conversii de tip : conversii implicite sau conversii explicite
promovare la tipul cu domeniul de valori mai mare

Operatorul de atribuire =

v = expresie;
(v variabila, v refera un obiect din memorie)
Rezultatul expresiei de atribuire este dat de valoarea înscrisă la adresa lui v.
Asociativitatea – la dreapta
Instrucțiunea expresie: expresie;
Se pot face atribuiri succesive:
a = b =… = x =expresie;
a = (b =… = (x = expresie))…);
a = (b = (c =1));
Operatori de atribuire combinați: op =
v op = expresie echivalentă cu : v = v op expresie
(de exemplu, v += 8  v = v + 8)

Operatorul cast (de conversie explicită) - C

(tip) operand
tip (operand)

3
Mădălina Roxana. Buneci

Operatori aritmetici

++ -- incrementare, decrementare (notație postfixată)


++ -- incrementare, decrementare (prefixată), - minus unar + plus unar (pentru
promovare)
* / % înmulțire, împărțire, rest împărțire întregi
+ - adunare, scădere

a/b
1/3 == 0
1.0/3 == 0.333…. == 1./3 == 1/3 Th: m, nN, m = n q + r, r{0, 1, …, n-1}

a % b a, b tip intreg

a, b sunt de tip întreg, atunci a/b este întreg și de obține prin trunchierea numărului a:b.
(a/b)*b + a%b == a.
-5/2 = -2 5/-2 =-2
-2*2 + (-5)%2 = -5 -2*(-2) +5 % (-2) = 5
++x x++ x=x+1
--x x-- x = x-1

Exemplu
int x, y;
x = 1;
y = x ++; //y = 1, x= 2
int x, y;
x = 1;
y = ++x; //x = 2, y = 2

4
Programarea calculatoarelor și limbaje de programare – notițe de curs/ Curs 6

Operatori relaționali
>
>=
<
<=
== egal
!= diferit de
rezultatul este de tip logic
Inițial în limbajul C nu a existat un tip de date logice. Orice dată de tip scalar era
interpretată de tip logic după următoarea regulă:
nenul  adevăr
nul  fals
Rezultatul de tip logic al unei expresii era considerat a fi
1 pentru adevăr
0 pentru fals
C _Bool bool
C++ bool

Operatori logici
! not
&& și logic
|| sau logic
a < b || a > c
(a < b) || (a > c)

Operatorul virgulă:
expr1, expr2
expr1, expr2, … , exprn
, operator
, separator f(a, b, c) f funcție

5
Mădălina Roxana. Buneci

x[i]
x[(i,j)]

Operatorul dimensiune:
sizeof(tip) sau sizeof expresie
numărul de bytes (1 byte = CHAR_BIT)
sizeof(char) == 1

Operatorul condițional: ?:
expr1 ? expr2 : expr3;
Exemplu
(a < b) ? a : b // min{a,b}

Operator rezoluție :: (doar C++)


Spații nume
tip1 x;
{ tip2 x ;
:: x
}

Pentru a accesa o variabilă globală atunci când există o variabilă locală cu același nume
Pentru a defini o funcție în afara unei clase. În caz de moștenire multiplă

Operatori pe biți în C/C++.


Operatorii pe biți se aplică numai datelor de tip întreg. și presupun manipularea
directă a biților din reprezentarea în memorie a operanzilor. Ei se aplică fiecărui bit din
reprezentarea în memorie a operanzilor. În ordinea descrescătoare a priorității,
operatorii pe biți sunt:

~ complementare

<< deplasare la stânga (left shift), >> deplasare la dreapta (right shift)

6
Programarea calculatoarelor și limbaje de programare – notițe de curs/ Curs 6

& și (conjuncție)

^ sau exclusiv

| sau (disjuncție)
Operatorul ~ transforma fiecare bit din reprezentarea operandului în
complementarul său, adică biții 1in 0 și biții 0 în 1:
b ~b
0 1
1 0

Operatorii &, ^, | realizează operațiile corespunzătoare între toate perechile de


biți de pe poziții identice în reprezentările în memorie ale operanzilor. Dacă b1 și b2
reprezintă o astfel de pereche, în tabelul următor sunt indicate valorile obținute prin
aplicarea operatorilor: &, ^, |.
b1 b2 b1 & b2 b1^ b2 b1 | b2
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 0 1

Exemplu: Programul de mai jos


#include <iostream>
int main() {
unsigned int x = 0xffa1, y = 0xe213;
std::cout << std::hex << std::showbase;
std::cout << x << " & " << y
<< " = " << (x & y) << std::endl;
std::cout << x << " ^ " << y
<< " = " << (x ^ y) << std::endl;
std::cout << x << " | " << y
<< " = " << (x | y) << std::endl;
std::cout << "~ " << x << " = " << (~x) << std::endl;
std::cout << "~ " << y << " = " << (~y) << std::endl;

7
Mădălina Roxana. Buneci

return 0;
}
afișează
0xffa1 & 0xe213 = 0xe201
0xffa1 ^ 0xe213 = 0x1db2
0xffa1 | 0xe213 = 0xffb3
~ 0xffa1 = 0xffff005e
~ 0xe213 = 0xffff1dec

0xef1a 0xba8e
0xef1a == 0b1110111100011010
0xba8e == 0b1011101010001110
1110111100011010 &
1011101010001110
---------------------------
1010 1010 0000 1010
a 0 a
0xef1a & 0xba8e = 0xaa0a

Operatorul de deplasare la stânga (left shift) << este un operator binar care are
ca rezultat numărul obținut prin deplasare spre stânga a biților din reprezentarea în
memorie a primului operand cu un număr de poziții egal cu al doilea operand.
Operatorul de deplasare la dreapta (right shift) >> este un operator binar care
are ca rezultat numărul obținut prin deplasare spre dreapta a biților din reprezentarea
în memorie a primului operand cu un număr de poziții egal cu al doilea operand.
Deci operatorii de deplasare sunt binari, primul operand este cel ai cărui biți
sunt deplasați, iar al doilea indică numărul de biți cu care se face deplasarea.
a<<n
a>>n

8
Programarea calculatoarelor și limbaje de programare – notițe de curs/ Curs 6

La deplasarea la stânga cu o poziție, bitul cel mai semnificativ se pierde, iar în


dreapta se completează cu bitul 0. La deplasarea la dreapta cu o poziție, bitul cel mai
puțin semnificativ se pierde, iar în stânga se completează cu 0 (pentru operanzi fără
semn sau cu semn nenegativi). În cazul în care operandul din stânga este negativ,
completarea bitului din stânga (cel mai semnificativ) depinde de implementare (de
obicei se adaugă un bit identic cu cel de semn).
Pentru operanzi fără semn sau cu semn nenegativi, cu excepția cazurilor când
se produce depășire, deplasarea la stânga cu n biți echivalează cu înmulțirea cu 2n.
Deplasarea la dreapta cu n biți echivalează cu împărțirea la 2n.
Începând cu standardul C++20, valoarea expresiei a << n este egală cu a*2n
modulo 2N, unde N este numărul de biți asociat tipului rezultatului. Valoarea expresiei
a >> n este partea întreagă a a/2n.
Dacă valoarea operandului drept este negativă sau este mai mare sau egală cu
numărul de biți din operandul stâng (promovat), comportamentul operatorilor de
deplasare este nedefinit.

Conversiile de tip explicite (cast).

Conversiile explicite de tip (numite și cast) pot fi forțate în orice expresie


folosind un operator unar (cast) într-o construcție de forma:
(tip) expresie
în care expresia este convertită la tipul numit.
Limbajul C++ standard conține patru operatori de cast care sunt de preferat
celor folosiți de versiunile mai vechi ale limbajelor C și C++
static_cast
const_cast
reinterpret_cast
dynamic_cast
Acești operatori dau programatorului un control mai precis asupra operațiilor
de cast care se știe că sunt adeseori o sursă de erori în timpul rulării unui program
Acești operatori de cast se folosesc în contexte bine definite

9
Mădălina Roxana. Buneci

Vechii operatori sunt universali


Operatorul static_cast permite conversiile standard, de exemplu void* la char* sau int
la double, și inversele lor.

Precedența și asociativitatea operatorilor în C


https://en.cppreference.com/w/c/language/operator_precedence

Precedence Operator Description Associativity


++ -- Suffix/postfix increment and decrement Left-to-right
() Function call
[] Array subscripting
1 . Structure and union member access
->
Structure and union member access
through pointer
(type){list} Compound literal(C99)
++ -- Prefix increment and decrement Right-to-left
+- Unary plus and minus
!~ Logical NOT and bitwise NOT
(type) Cast
2
* Indirection (dereference)
& Address-of
sizeof Size-of
_Alignof Alignment requirement(C11)
3 */% Multiplication, division, and remainder Left-to-right
4 +- Addition and subtraction
5 << >> Bitwise left shift and right shift
< <=
For relational operators < and ≤
respectively
6
> >=
For relational operators > and ≥
respectively
7 == != For relational = and ≠ respectively
8 & Bitwise AND
9 ^ Bitwise XOR (exclusive or)
10 | Bitwise OR (inclusive or)
11 && Logical AND
12 || Logical OR
13 ?: Ternary conditional Right-to-left

10
Programarea calculatoarelor și limbaje de programare – notițe de curs/ Curs 6

= Simple assignment
+= -= Assignment by sum and difference
*= /= %=
Assignment by product, quotient, and
remainder
14
<<= >>=
Assignment by bitwise left shift and right
shift
&= ^= |=
Assignment by bitwise AND, XOR, and
OR
15 , Comma Left-to-right

Precedența și asociativitatea operatorilor în C++


https://en.cppreference.com/w/cpp/language/operator_precedence

Precedence Operator Description Associativity


1 :: Scope resolution Left-to-right
Suffix/postfix increment and
a++ a--
decrement
type() type{} Functional cast
2 a() Function call
a[] Subscript
. -> Member access
++a --a Prefix increment and decrement Right-to-left
+a -a Unary plus and minus
! ~ Logical NOT and bitwise NOT
(type) C-style cast
*a Indirection (dereference)
3
&a Address-of
sizeof Size-of[note 1]
co_await await-expression (C++20)
new new[] Dynamic memory allocation
delete delete[] Dynamic memory deallocation
4 .* ->* Pointer-to-member Left-to-right
Multiplication, division, and
5 a*b a/b a%b
remainder

11
Mădălina Roxana. Buneci

6 a+b a-b Addition and subtraction


7 << >> Bitwise left shift and right shift
<=>
Three-way comparison operator
8
(since C++20)
For relational operators < and ≤ and
9 < <= > >=
> and ≥ respectively
For equality operators = and ≠
10 == !=
respectively
11 & Bitwise AND
12 ^ Bitwise XOR (exclusive or)
13 | Bitwise OR (inclusive or)
14 && Logical AND
15 || Logical OR
a?b:c Ternary conditional[note 2] Right-to-left
throw throw operator
co_yield yield-expression (C++20)
=
Direct assignment (provided by
default for C++ classes)
Compound assignment by sum and
+= -=
16 difference
Compound assignment by product,
*= /= %=
quotient, and remainder
Compound assignment by bitwise
<<= >>=
left shift and right shift
Compound assignment by bitwise
&= ^= |=
AND, XOR, and OR
17 , Comma Left-to-right

12

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