4.4. Instructiunea if

2019/02/09 in Programare in C

Instructiunea if are urmatoarele formate:

(1)

if(expresie)
instructiune

(2)

if(expresie)
instructiune1
else
instructiune2

La intalnirea instructiunii if intai se evalueaza expresia dintre paranteze.

Apoi, in cazul formatului (1), daca expresia are valoarea diferita de 0 (are valoarea adevarat), atunci se executa instructiune; altfel, se trece in secventa la instructiunea urmatoare instructiunii if.

In cazul formatului (2), daca expresia are o valoare diferita de 0 se executa instructiune1 si apoi se trece in secventa (adica la instructiunea aflata dupa instructiune2); altfel se executa instructiune2.

In mod normal, in ambele formate dupa executia instructiunii if se ajunge la instructiunea urmatoare ei. Cu toate acestea este posibila si o alta situatie cand instructiunile din compunerea lui if, definesc ele insele un alt mod de continuare a executiei programului.

Deoarece o instructiune compusa este considerata ca fiind un caz particular de instructiune, rezulta ca instructiunile din compunerea lui if pot fi instructiuni compuse. De asemenea, instructiunile respective pot fi chiar noi instructiuni if. In acest caz, se spune ca instructiunile if sunt imbricate.

Exercitii:

4.3. Se da functia y = 3x2 + 2x - 10, pentru x > 0 si y = 5x + 10. pentru x <= 0.

Sa se scrie un program care citeste valoarea lui x, calculeaza si afiseaza valoarea lui y.

Acest proces de calcul implica doua alternative, in functie de valoarea lui x:

Acelasi proces de calcul se poate realiza cu ajutorul expresiei de atribuire:

y = (x > 0) ? 3*x*x + 2*x - 10 : y = 5x + 10;

care utilizeaza in partea dreapta o expresie conditionala. Aceasta este o scriere mai compacta, dar nu atat de evidenta, ca si instructiunea if de mai sus.

#include <stdio.h>

main()
{
    float x, y;
	
    scanf("%f", &x);
    if (x > 0)
        y = 3*x*x + 3*x - 10;
    else
        y = 3*x + 10;	
    printf("x = %f\ty = %f\n", x, y);
}

4.4. Sa se scrie un program care citeste valoarea lui x, calculeaza si afiseaza valoarea lui y definita ca mai jos:

Acest proces de calcul implica urmatoarele alternative:

El se transcrie imediat printr-o instructiune if imbricata:

if (x < 0)
  y = 4*x*x*x + 5*x*x - 2x + 1;
else
  if (x == 0)
      y = 100;
  else
      y = 2*x*x + 8*x + 1;

Acelasi proces de calcul se poate scrie folosind instructiunea expresie de atribuire:

y = (x < 0) ? 4*x*x*x + 5*x*x - 2*x + 1 : x == 0 ? 100 : 2*x*x + 8*x + 1;
#include <stdio.h>

main()
{
    float x, y;
	
    scanf("%f", &x);
    if (x < 0)
      y = 4*x*x*x + 5*x*x - 2x + 1;
    else
      if (x == 0)
        y = 100;
      else
        y = 2*x*x + 8*x + 1;	
    printf("x = %f\ty = %f\n", x, y);
}

4.5. Sa se scrie un program care citeste valoarile variabilelor neintregi a si b, calculeaza radacina ecuatiei:

a*x + b = 0

si afiseaza rezultatul.

Procesul de calcul al radacinii ecuatiei de mai sus trebuie sa verifice existenta ei:

#include <stdio.h>

main()
{
    double a, b;
	
    if (scanf("%lf %lf", &a, &b) != 2)
      printf ("coeficienti eronati\n");
    else
      if (a != 0)
        printf("a = %g\tb = %g\tx = %g", a, b, -b / a);
      else
        if (b == 0)
            printf("ecuatia este nedeterminata\n");
        else
            printf("ecuatia nu are solutie\n");
}

Observatii:

  1. Programul de fata contine o instructiune if imbricata;
  2. Pentru a mari claritatea programelor, se obisnuieste sa se decaleze spre dreapta (cu un tabulator) instructiunile din compunerea unei instructiuni if;
  3. In acest program s-a realizat test relativ la valorile tastate pentru a si b. Daca scanf nu returneaza valoarea 2, inseamna ca nu s-au tastat doua numere de la terminal. De aceea, intr-o astfel de situatie se afiseaza mesajul: coeficienti eronati.

4.6. Sa se scrie un program care citeste coeficientii a, b, c, d, e, f, ai unui sistem de doua ecuatii liniare cu doua necunoscute, determina si afiseaza solutia acestuia cand are o solutie unica.

Fie sistemul de ecuatii liniare:

a*x + b*y = c
d*x + e*y = f

Notam cu det determinantul coeficientilor necunoscutelor. Acesta se calculeaza cu relatia:

det = a*e - b*d

Notam cu det1 determinantul obtinut din det prin inlocuirea primei coloane cu coloana termenului liber si cu det2 determinantul obtinut din det prin inlocuirea coloanei a doua cu coloana termenului liber. Atunci:
det1 = c*e - b*f si det2 = a*f - c*d.

Procesul de calcul al valorilor lui x si y se face urmand pasii:

  1. se citesc valorile coeficientilor a, b, c, d, e si f;
  2. det = a*e - b*d;
  3. daca det = 0, atunci sistemul nu are solutie unica (este nedeterminat sau incompatibil). Se afiseaza un mesaj corespunzator si se intrerupe executia programului. Altfel se continua cu punctul 4.
  4. det1 = c*e - b*f;
  5. det2 = a*f - c*d;
  6. x = det1/det2;
  7. y = det2/det1;
  8. se afiseaza valorile lui x si y.
#include <stdio.h>

main()
{
    double a, b, c, d, e, f, x, y, det, det1, det2;
	
    if (scanf("%lf %lf %lf %lf %lf %lf", &a, &b, &c, &d, &e, &f) != 6)
      printf ("coeficienti eronati\n");
    else
      if ((det = a*e - b*d) == 0)
        printf("sistemul are determinantul nul\n");
      else
        {
           det1 = c*e - b*f;
           det2 = a*f - c*d;
           x = det1/det2;
           y = det2/det1;
           printf("x = %g\ty = %g\n", x, y);
        }
}

Observatii:

  1. Expresia (1) (det = a*e - b*d) == 0 se evalueaza astfel:
    • se calculeaza a*e - b*d si valoarea respectiva se atribuie lui det;
    • se compara valoarea atribuita lui det cu 0. Daca valoarea lui det este zero, atunci expresia (1) are valoarea adevarat. In caz contrar, expresia (1) are valoarea 0, aica fals.
  2. Parantezele din expresia (1) sunt obligatorii. In lipsa lor, expresia (1) devine (2) det = a*e - b*d == 0. Aceasta se evalueaza astfel:
    • se calculeaza valoarea expresiei a*e - b*d;
    • deoarece operatorul == este mai prioritar decat = se compara valoarea expresiei respective cu zero. Daca expresia respectiva are valoarea zero, atunci expresia (3) a*e - b*d == 0 are valoarea 1 (adevarat), altfel are valoarea 0 (fals);
    • se compara valoarea atribuita lui det cu 0. Daca valoarea lui det este zero, atunci expresia (1) are valoarea adevarat. In caz contrar, expresia (1) are valoarea 0, aica fals.
    • se atribuie lui det valoarea expresiei (3), adica 0 sau 1.

4.7. Sa se scrie un program care citeste valorile variabilelor a, b, c, calculeaza si afiseaza radacinile ecuatiei de gradul 2: ax2 + bx + c = 0.

Pasii procesului de calcul sunt:

  1. se citesc valorile variabilelor a, b, c;
  2. daca a = b = c = 0, ecuatia este nedeterminata.
    Se afiseaza un mesaj corespunzator si se intrerupe executia programului;
  3. daca a = b = 0 si c este diferit de 0, ecuatia nu are solutie.
    Se afiseaza un mesaj corespunzator si se intrerupe executia programului;
  4. daca a = 0 si b este diferit de 0, ecuatia se reduce la o ecuatie de gradul intai, a carei solutie este:
    x = -c / b.
    Se afiseaza un mesaj corespunzator, solutia x si se intrerupe executia programului;
  5. daca a este diferit de 0, se calculeaza: delta = b*b - 4*a*c si d = 2*a;
  6. daca delta > 0, atunci delta = sqrt(delta). Se determina si se afiseaza radacinile:
    x1 = ( -b + delta) / d
    si
    x2 = ( -b - delta) / d
    si se intrerupe executia programului;
  7. daca delta = 0, atunci se determina si se afiseaza radacina dubla:
    x = -b / d
    si se intrerupe executia programului;
  8. altfel, ecuatia are radacini complexe conjugate. Se calculeaza: delta = sqrt(-delta).
    Se determina si afiseaza radacinile:
    x1 = -b / d + i*delta / d
    si
    x2 = -b / d - i*delta / d
    Se intrerupe executia programului
#include <stdio.h>
#include <math.h>

main()
{
    double a, b, c, d, delta;

    printf("coeficientul lui x patrat:", &a);
    if (scanf("%lf", &a) != 1)
        printf ("coeficientul lui x patrat eronat\n");
    else {
        printf("coeficientul lui x:", &b);
        if (scanf("%lf", &b) != 1)
            printf ("coeficientul lui x eronat\n");
        else {
            printf("termenul liber:", &c);
            if (scanf("%lf", &c) != 1)
                printf ("termenul liber eronat\n");
            else {
                printf("a = %g\tb = %g\t c = %g\n", a, b, c);
                if (a == 0 && b == 0 && c == 0)
                    printf ("ecuatie nedeterminata\n");
                else
                    if (a == 0 && b == 0)
                        printf ("ecuatia nu are solutie\n");
                    else
                        if (a == 0) {
                            printf ("ecuatie de gradul 1\n");
                            printf ("x = %g\n", -c / b);
                        }
                        else {
                            delta = b*b - 4*a*c;
                            d = 2*a;
                            if (delta > 0) {
                                printf ("ecuatia are doua radacini reale si distincte\n");
                                delta = sqrt(delta);
                                printf ("x1 = %g\tx2 = %g\n", (-b + delta)/d, (-b - delta)/d);
                            }
                            else {
                                if (delta == 0) {
                                    printf ("ecuatia are radacina dubla\n");
                                    printf ("x = %g\n", -b / d);
                                }
                                else {
                                    printf ("radacini complexe\n");
                                    delta = sqrt(-delta);
                                    d = -b / d;
                                    printf ("x1 = %g + i(%g)\n", d, delta);
                                    printf ("x2 = %g - i(%g)\n", d, delta);
                                }
                            }
                        }
            }
        }
    }
}

Observatie: Programul de fata utilizeaza instructiunea if cu nivel de imbricare relativ mare. Programele care folosesc instructiuni if cu nivele mari de imbricare sunt greu de urmarit. Adesea se uita inchiderea tuturor acoladelor. De aceea se recomanda reducerea, pe cat posibil, a nivelelor de imbricare ale instructiunilor if. In multe cazuri, nivelul de imbricare al unei instructiuni if se poate reduce folosind functia exit (vezi pagina urmatoare).

4.5. Functia standard exit