3.2.2. Regula conversiilor implicite

2019/01/22 in Programare in C

Aceasta regula se aplica la evaluarea expresiilor. Ea actioneaza atunci cand un operator binar se aplica la doi operanzi de tipuri diferite.

In cazul in care un operator binar se aplica la doi operanzi de tipuri diferite, operandul de tip "inferior" se converteste spre tipul "superior" al celuilalt operand, iar rezultatul este de tipul "superior".

Regula conversiilor implicite are in vedere niste conversii generale independente de operatori. Ea se aplica in mai multi pasi, in ordinea indicata mai jos.

Inainte de toate, se convertesc operatorii de tip char si enum in tipul int.

Daca operatorul curent se aplica la operanzi de acelasi tip, atunci se executa operatorul respectiv, iar tipul rezultatului coincide cu tipul comun al operanzilor. Daca rezultatul aplicarii operatorului reprezinta o valoare in afara limitelor tipului respectiv, atunci rezultatul este eronat (are loc o "depasire", eng. overflow).

Daca operatorul binar curent se aplica la operanzi diferiti, atunci se face o conversie inainte de executia operatorului, conform pasilor:

  1. daca unul din operanzi este de tip long double, atunci celalalt operand se converteste spre tipul long double si rezultatul aplicarii operatorului este de tip long double.
  2. daca unul din operanzi este de tip double, atunci celalalt operand se converteste spre tipul double si rezultatul aplicarii operatorului este de tip double.
  3. daca unul din operanzi este de tip float, atunci celalalt operand se converteste spre tipul float si rezultatul aplicarii operatorului este de tip float.
  4. daca unul din operanzi este de tip unsigned long, atunci celalalt operand se converteste spre tipul unsigned long si rezultatul aplicarii operatorului este de tip unsigned long.
  5. daca unul din operanzi este de tip long, atunci celalalt operand se converteste spre tipul long si rezultatul aplicarii operatorului este de tip long.
  6. daca unul din operanzi este de tip unsigned, iar celalalt operand este de tip int atunci acest operand se converteste spre tipul unsigned si rezultatul aplicarii operatorului este de tip unsigned.

Aplicand regula de mai sus, la fiecare operator curent, in procesul de evaluare a unei expreasii, se determina in final tipul expresiei respective.

Exemple:

1.

int c;
...
c-'a'+'A'

Constantele caracter 'a' si 'A' sunt de tip int, deci toti operanzii sunt de tip int. Nu este necesara nicio conversie pentru evaluarea expresiei.

2.

int i;
...
1234*i

Operanzii sunt de tip int, expresia este de tip int. Rezultatul inmultirii este eronat daca este in afara intervalului [-32768, 32767].

3.

int i;
long double a;
...
a*3+i

Tinand seama de prioritatea operatorilor, intai se executa inmultirea, apoi adunarea. Expresia se evalueaza astfel:

Exercitii:

3.8. Sa se scrie un program care citeste doi intregi de la intrarea standard si afiseaza media lor cu o zecimala.

#include <stdio.h>

main()
{
     int a, b;

     scanf("%d %d", &a, &b);
     printf("a = %d\t b = %d\t media = %.1f\n", a, b, (a+b)/2.0f);
}

Observatii:

  1. Pentru calculul mediei se foloseste expresia: (a+b)/2.0f. Ea se evalueaza astfel:
    • se calculeaza suma a+b; rezultatul este de tip int, deoarece ambii operanzi sunt de tip int. Daca suma nu apartine intervalului [-32768, 32767], atunci rezultatul este eronat.
    • rezultatul adunarii se converteste spre float, deoarece celalalt operand este de tip float, apoi se face impartirea, iar rezultatul este de tip float.
  2. Daca s-ar fi utilizat expresia: (a+b)/2.0, suma a+b s-ar fi convertit spre double, deoarece impartitorul este de tip double. In acest caz, rezultatul este de tip double.
  3. Expresia: (a+b)/2 realizeaza impartirea intreaga dintre operatorii a+b si 2, care sunt de tip int. De aceea, pentru a si b de paritati diferite, expresia de mai sus nu da rezultatul corect (care trebuie sa fie afisat cu o zecimala).

3.9. Sa se scrie un program care citeste masura unui unghi in grade sexazecimale si afiseaza valoarea functiei sinus pentru unghiul respectiv.

Masura unghiului in grade sexazecimale se tasteaza sub forma: g m s, unde:

Pentru calculul functiei sinus se apeleaza functia sin aflata in biblioteca limbajului C, cu prototipul in fisierul math.h:

double sin(double);

Parametrul functiei este masura unghiului in radiani pentru care se calculeaza valoarea functiei sin. Conversia masurii unghiului din grade sexazecimale in radiani se realizeaza folosind expresia:

(g+m/60.0+s/3600.0)*PI/180.0

unde PI=3,14159265358979

#include <stdio.h>
#include <math.h>

#define PI 3.14159265358979

main()
{
    int g, m, s;

    scanf("%d\n %d\n %d\n", &g, &m, &s);
    printf("grade:%d\tminute:%d\tsecunde:%d\n", g, m, s);
    printf("sin=%.13f\n", sin((g+m/60.0+s/3600.0)*PI/180.0));
}

3.2.3. Operatori de relatie