3.2.17. Operatori - Recapitulare si exercitii

2019/02/04 in Programare in C

Un operator este un simbol care spune compilatorului sa fac anumite operatii matematice sau logice Limbajul C este bogat in operatori predefiniti si ofera urmatoarele tipuri de operatori:


Operatori aritmetici

Tabelul urmator contine toti operatorii aritmetici acceptati in limbajul C. Sa presupunem ca A = 10 si B = 20. In acest caz:

Operator Descriere Exemplu
+ Aduna doi operanzi. A + B = 30
- Scade al doilea operand din primul. A - B = -10
* Inmulteste doi operanzi. A * B = 210
/ Imparte un operand la alt operand. B / A = 2
% Operatorul modulo, are ca rezultat restul impartirii a doi operanzi intregi. B % A = 0
++ Operatorul de incrementare mareste valoarea unui intreg cu 1. A++ = 11
-- Operatorul de decrementare micsoreaza valoarea unui intreg cu 1. A-- = 9

Exercitiu:

3.24. Operatori aritmetici

#include <stdio.h>

main()
{
    int a = 21;
    int b = 10;
    int c;

    c = a + b;
    printf("Linia 1 - valoarea lui c este %d\n", c);
    c = a - b;
    printf("Linia 2 - valoarea lui c este %d\n", c);
    c = a * b;
    printf("Linia 3 - valoarea lui c este %d\n", c);
    c = a / b;
    printf("Linia 4 - valoarea lui c este %d\n", c);
    c = a % b;
    printf("Linia 5 - valoarea lui c este %d\n", c);
    c = a++;
    printf("Linia 6 - valoarea lui c este %d\n", c);
    c = a--;
    printf("Linia 7 - valoarea lui c este %d\n", c);
}

Dupa compilare si executie Programul 049 produce urmatorul rezultat:

Linia 1 - valoarea lui c este 31
Linia 2 - valoarea lui c este 11
Linia 3 - valoarea lui c este 210
Linia 4 - valoarea lui c este 2
Linia 5 - valoarea lui c este 1
Linia 6 - valoarea lui c este 21
Linia 7 - valoarea lui c este 22

Observatie: Expresia de atribuire c = a++ atribuie variabilei c valoarea curenta a variabilei a, care este 21 si nu 22, deoarece operatorul de incrementare este postfixat. In continuare, se aplica operatorul de incrementare variabilei a, care capata valoarea 22. Expresia de atribuire c = a-- atribuie variabilei c valoarea curenta a lui a, care este 22, operatorul de incrementare fiind postfixat, el nu se mai aplica variabilei a.


Operatori de relatie

Tabelul urmator contine toti operatorii de relatie acceptati in limbajul C. Sa presupunem ca A = 10 si B = 20. Atunci:

Operator Descriere Exemplu
== Verifica daca valorile celor doi operanzi sunt egale sau nu. Daca da, conditia devine adevarata. (A == B) nu este adevarata.
!= Verifica daca valorile celor doi operanzi sunt egale sau nu. Daca nu, conditia devine adevarata. (A != B) este adevarata.
> Verifica daca valoarea operatorului stang este mai mare decat cea a operatorului drept. Daca da, conditia devine adevarata. (A > B) nu este adevarata.
< Verifica daca valoarea operatorului stang este mai mica decat cea a operatorului drept. Daca da, conditia devine adevarata. (A < B) este adevarata.
>= Verifica daca valoarea operatorului stang este mai mare sau egala cu cea a operatorului drept. Daca da, conditia devine adevarata. (A >= B) nu este adevarata.
<= Verifica daca valoarea operatorului stang este mai mica sau egala cu cea a operatorului drept. Daca da, conditia devine adevarata. (A <= B) este adevarata.

Exercitiu:

3.25. Operatori de relatie

#include <stdio.h>

main()
{
    int a = 21;
    int b = 10;

    printf("a = %d\n", a);
    printf("b = %d\n\n", b);

    if( a == b ) {
      printf("Linia 1 - a este egal cu b\n" );
    } else {
      printf("Linia 1 - a nu este egal cu b\n" );
    }

    if ( a < b ) {
      printf("Linia 2 - a este mai mic decat b\n" );
    } else {
      printf("Linia 2 - a nu este mai mic decat b\n" );
    }

    if ( a > b ) {
      printf("Linia 3 - a este mai mare decat b\n" );
    } else {
      printf("Linia 3 - a nu este mai mare decat b\n" );
    }

    int c = 5;
    int d = 20;

    printf("\nc = %d\n", c);
    printf("d = %d\n\n", d);

    if ( c <= d ) {
      printf("Linia 4 - c este mai mic sau egal cu d\n" );
    }

    if ( c >= d ) {
      printf("Linia 5 - c este mai mare sau egal cu d\n" );
    }
}

Dupa compilare si executie Programul 050 produce urmatorul rezultat:

a = 21
b = 10

Linia 1 - a nu este egal cu b
Linia 2 - a nu este mai mic decat b
Linia 3 - a este mai mare decat b

c = 5
d = 20

Linia 4 - c este mai mic sau egal cu d

Operatori logici

Tabelul urmator contine toti operatorii logici acceptati in limbajul C. Sa presupunem ca A = 1 si B = 0. Atunci:

Operator Descriere Exemplu
&& Se numeste si logic. Daca ambii operanzi sunt diferiti de zero, conditia devine adevarata. (A && B) este falsa.
|| Se numeste sau logic. Daca unul din operanzi este diferit de zero, conditia devine adevarata. (A || B) este adevarata.
! Se numeste negatie logica. Se foloseste pentru a inversa starea logica a unui operand. Daca o conditie este adevarata, operatorul ! o va face falsa. !(A && B) este adevarata.


Operatori logici pe biti

Operatorii logici pe biti fac operatii bit cu bit. Tabelul adevarului pentru operatorii &, | si ^ este:

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Sa presupunem ca A = 60 si B = 13. In binar, A si B se scriu:

  A = 0011 1100
  B = 0000 1101

Aplicam pe rand operatorii logici pe biti:

  A = 0011 1100
  B = 0000 1101
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
 ~A = 1100 0011

Tabelul de mai jos contine toti operatorii logici pe biti folositi in limbajul C. Presupunem ca A = 60 si B = 13.

Operator Descriere Exemplu
& Operatorul si logic pe biti copiaza un bit in rezultat, daca el exista in ambii operanzi. (A & B) = 12, adica
0000 1100
| Operatorul sau logic pe biti copiaza un bit in rezultat, daca el exista macar intr-unul din operanzi. (A | B) = 61, adica
0011 1101
^ Operatorul sau exclusiv logic pe biti copiaza un bit in rezultat, daca el exista in unul din operanzi, dar nu in ambii operanzi. (A ^ B) = 49, adica
0011 0001
~ Operatorul logic pe biti complement fata de unu este unar si schimba bitii intre ei. (~A) = (~60) = -61, adica
1100 0011
<< Operatorul logic pe biti deplasare la stanga muta spre stanga valoarea operandului stang cu numarul de biti specificat de operandul din dreapta. A << 2 = 240, adica
1111 0000
>> Operatorul logic pe biti deplasare la dreapta muta spre dreapta valoarea operandului stang cu numarul de biti specificat de operandul din dreapta. A >> 2 = 15, adica
1111

Exercitiu:

3.26. Operatori logici pe biti

#include <stdio.h>

main() {

   unsigned int a = 60;	/* 60 = 0011 1100 */  
   unsigned int b = 13;	/* 13 = 0000 1101 */
   int c = 0;           

   c = a & b;       /* 12 = 0000 1100 */ 
   printf("Linia 1 - valoarea lui c este %d\n", c );

   c = a | b;       /* 61 = 0011 1101 */
   printf("Linia 2 - valoarea lui c este %d\n", c );

   c = a ^ b;       /* 49 = 0011 0001 */
   printf("Linia 3 - valoarea lui c este %d\n", c );

   c = ~a;          /*-61 = 1100 0011 */
   printf("Linia 4 - valoarea lui c este %d\n", c );

   c = a << 2;     /* 240 = 1111 0000 */
   printf("Linia 5 - valoarea lui c este %d\n", c );

   c = a >> 2;     /* 15 = 0000 1111 */
   printf("Linia 6 - valoarea lui c este %d\n", c );
}

Dupa compilare si executie Programul 051 produce urmatorul rezultat:

Linia 1 - valoarea lui c este 12
Linia 2 - valoarea lui c este 61
Linia 3 - valoarea lui c este 49
Linia 4 - valoarea lui c este -61
Linia 5 - valoarea lui c este 240
Linia 6 - valoarea lui c este 15

Observatie: Operatorul de complementare fata de unu in C

Complementul fata de unu al lui 60 (~60) este -61 si nu 195, dar de ce?

Pentru orice numar intreg n, complementul fata de unu al lui n va fi -(n+1). Pentru a intelege asta, trebuie inteles complementul fata de 2.

Complementul fata de 2

Complementul fata de 2 este o operatie asupra numerelor binare. Complementul fata de 2 al unui numar este complementul fata de unu al acelui numar plus 1. De exemplu:

Zecimal Binar Complement fata de 2
0 0000 0000 - (1111 1111 + 1) = - 0000 0000 = - 010
1 0000 0001 -(1111 1110 + 1) = - 1111 1111 = - 25610
12 0000 1100 -(1111 0011 + 1) = - 1111 0100 = - 24410
195 1100 0011 -(0011 1100 + 1) = - 0011 1101 = - 6110

Complementul fata de unu al lui 60 este 195 (in zecimal). Complementul fata de doi al lui 195 este -61. De aceea, rezultatul este -61 si nu 195.


Operatori de atribuire

Tabelul de mai jos descrie toti operatorii de atribuire ai limbajului C:

Operator Descriere Exemplu
= Operatorul simplu de atribuire. Atribuie valoarea operandului drept operandului stang. C = A + B atribuie lui C valoarea lui A + B
+= Operatorul plus si atribuire. Aduna operandul drept cu cel stang si atribuie rezultatul operandului stang. C += A este echivalent cu C = C + A
-= Operatorul minus si atribuire. Scade operandul drept din cel stang si atribuie rezultatul operandului stang. C -= A este echivalent cu C = C - A
*= Operatorul inmultire si atribuire. Inmulteste operandul drept cu cel stang si atribuie rezultatul operandului stang. C *= A este echivalent cu C = C * A
/= Operatorul impartire si atribuire. Imparte operandul drept la cel stang si atribuie rezultatul operandului stang. C /= A este echivalent cu C = C / A
%= Operatorul modulo si atribuire. Atribuie restul impartirii operandului drept la cel stang operandului stang. C %= A este echivalent cu C = C % A
<<= Operatorul de deplasare la stanga si atribuire. C <<= 2 este identic cu C = C << 2
>>= Operatorul de deplasare la dreapta si atribuire. C >>= 2 este identic cu C = C >> 2
&= Operatorul si logic pe biti si atribuire. C &= 2 este identic cu C = C & 2
^= Operatorul sau exclusiv logic pe biti si atribuire. C ^= A este identic cu C = C ^ 2
|= Operatorul sau logic pe biti si atribuire. C |= A este identic cu C = C | 2

Exercitiu:

3.27. Operatori de atribuire

#include <stdio.h>

main() {

   int a = 21;
   int c;           

   c = a; 
   printf("Linia 1 - Exemplu operator =, valoarea lui c este c = %d\n", c );
   
   c += a; 
   printf("Linia 2 - Exemplu operator +=, valoarea lui c este c = %d\n", c );
   
   c -= a; 
   printf("Linia 3 - Exemplu operator -=, valoarea lui c este c = %d\n", c );
   
   c *= a; 
   printf("Linia 4 - Exemplu operator *=, valoarea lui c este c = %d\n", c );
   
   c /= a; 
   printf("Linia 5 - Exemplu operator /=, valoarea lui c este c = %d\n", c );
   
   c = 200;
   printf("Valoarea lui c devine c = %d\n", c );
   
   c %= a; 
   printf("Linia 6 - Exemplu operator %=, valoarea lui c este c = %d\n", c );
   
   c <<= 2; 
   printf("Linia 7 - Exemplu operator <<=, valoarea lui c este c = %d\n", c );
   
   c >>= 2; 
   printf("Linia 8 - Exemplu operator >>=, valoarea lui c este c = %d\n", c );
   
   c &= 2; 
   printf("Linia 9 - Exemplu operator &=, valoarea lui c este c = %d\n", c );
   
   c ^= 2; 
   printf("Linia 10 - Exemplu operator ^=, valoarea lui c este c = %d\n", c );
   
   c |= 2; 
   printf("Linia 11 - Exemplu operator |=, valoarea lui c este c = %d\n", c );
}

Dupa compilare si executie Programul 052 produce urmatorul rezultat:

Linia 1 - Exemplu operator =, valoarea lui c este c = 21
Linia 2 - Exemplu operator +=, valoarea lui c este c = 42
Linia 3 - Exemplu operator -=, valoarea lui c este c = 21
Linia 4 - Exemplu operator *=, valoarea lui c este c = 441
Linia 5 - Exemplu operator /=, valoarea lui c este c = 21
Valoarea lui c devine c = 200
Linia 6 - Exemplu operator %=, valoarea lui c este c = 11
Linia 7 - Exemplu operator <<=, valoarea lui c este c = 44
Linia 8 - Exemplu operator >>=, valoarea lui c este c = 11
Linia 9 - Exemplu operator &=, valoarea lui c este c = 2
Linia 10 - Exemplu operator ^=, valoarea lui c este c = 0
Linia 11 - Exemplu operator |=, valoarea lui c este c = 2

Alti operatori

Pe langa operatorii discutati mai sus, in limbajul C mai exista si alti operatori importanti:

Operator Descriere Exemplu
sizeof() Returneaza marimea in byti a unei variabile. sizeof(a), unde a este un intreg, va returna valoarea 4
& Returneaza adresa unei variabile. &a, returneaza adresa efectiva a variabilei a
* Pointer catre o variabila. *a;
? : Expresie conditionala. Conditie?X:Y Daca Conditie este adevarata ? atunci valoarea X : in caz contrar, valoarea Y

Exercitiu:

3.28. Alti operatori

#include <stdio.h>

main()
{
    int a = 4;
    short b;
    double c;
    int* ptr;

    /* Exemple cu operatorul sizeof() */
    printf("Linia 1 - Marimea variabilei a = %d\n", sizeof(a));
    printf("Linia 2 - Marimea variabilei b = %d\n", sizeof(b));
    printf("Linia 3 - Marimea variabilei c = %d\n", sizeof(c));

    /* Exemple cu operatorul & si * */
    ptr = &a; /* ptr contine adresa variabilei a */
    printf("\nValoarea lui a este a = %d\n", a);
    printf("ptr este %d\n", *ptr);

    /* Exemple cu operatorul ternar */
    int x = 10;
    printf("\nValoarea lui x este x = %d\n", x);

    b = (x == 1) ? 20 : 30;
    printf("Valoarea lui b este %d\n", b);

    b = (x == 10) ? 20 : 30;
    printf("Valoarea lui b este %d\n", b);
}

Dupa compilare si executie Programul 053 produce urmatorul rezultat:

Linia 1 - Marimea variabilei a = 4
Linia 2 - Marimea variabilei b = 2
Linia 3 - Marimea variabilei c = 8

Valoarea lui a este a = 4
ptr este 4

Valoarea lui x este x = 10
Valoarea lui b este 30
Valoarea lui b este 20

Prioritatile operatorilor in limbajul C

Prioritatile operatorilor determina gruparea termenilor unei expresii la evaluarea ei. Unii operatori au o prioritate mai mare decat altii; de exemplu, operatorul de multiplicare a re o prioritate mai mare decat cel de adunare.

De exemplu, fie: x = 7 + 3 * 2; aici x va avea valoarea 13 si nu 20, pentru ca operatorul * are o prioritate mai mare decat +, prin urmare mai intai se face inmultirea 3*2 si apoi se aduna 7.

In tabelul urmator, operatorii cu prioritatea cea mai mare apar mai sus in tabel, iar cei cu prioritate mai mica apar mai jos. In expresii, operatorii cu prioritate mai mare sunt evaluati primii.

Categorie Operator Asociativitate
Postfixati () [] -> . ++ -- Stanga spre dreapta
Unari + - ! ~ ++ -- (tip) * & sizeof Dreapta spre stanga
Multiplicativi * / % Stanga spre dreapta
Aditivi + - Stanga spre dreapta
De deplasare << >> Stanga spre dreapta
De relatie < <= > >= Stanga spre dreapta
De egalitate == != Stanga spre dreapta
Si logic pe biti & Stanga spre dreapta
Sau exclusiv logic pe biti ^ Stanga spre dreapta
Sau logic pe biti | Stanga spre dreapta
Si logic & Stanga spre dreapta
Sau logic || Stanga spre dreapta
Conditionali ? : Dreapta spre stanga
De atribuire = += -= *= /= %= <<= >>= &= ^= |= Dreapta spre stanga
Virgula , Stanga spre dreapta

4. Instructiuni