Expresii cu date primitive

În programare, expresia este o combinație permisă ("legală", corectă) de simboluri, care reprezintă o valoare. Tipul expresiei este același cu tipul valorii ei. Putem avea, deci, expresii de tip boolean, int, long, float, double etc. Fiecare limbaj de programare are regulile sale, prin care se stabilește ce expresii sunt permise sau nepermise.

În limbajul Java, expresia poate conține literali, variabile, operatori, operanzi, funcții și paranteze și trebuie să poată fi evaluată (calculată), astfel încât să se obțină o valoare.
 
Construirea expresiei se face pas cu pas, având în vedere că:
    - un literal sau o variabilă constituie o expresie; tipul și valoarea acestei expresii sunt cele ale literalului sau variabilei respective; 
 
Exemple de astfel de expresii sunt:
        true
        -176
        1.358746E-12
        "sir de caractere"
        beta

    - un operator împreună cu operanzii lui constituie o expresie. 
 
De exemplu:
        alpha+3.765 (s-a folosit operatorul binar +)
        alpha++  (s-a folosit operatorul unar postfix ++)
        -alpha   (s-a folosit operatorul unar prefix -)

    - o expresie cuprinsă între paranteze constituie o nouă expresie, a cărei valoare este identică cu cea a expresiei din interior;
 
De exemplu:
        (-176)
        (alpha++)
        (alpha+3.765)

    - valoarea unei expresii poate fi folosită ca operand într-o altă expresie.
 
De exemplu:
    (alpha+3.765)*(alpha++)

Se observă că, procedând astfel, se pot construi expresii din ce în ce mai complicate.

Utilizarea funcțiilor în expresii va fi discutată ulterior. Mernționăm însă că și operatorii acționează tot ca niște funcții. De exemplu, evaluarea expresiei alpha+3.765 este, de fapt, calcularea unei funcții, care are ca argumente valorile variabilei alpha și literalului 3.765 și are ca valoare suma acestora.
 
Expresia poate fi reprezentată ca un arbore sintactic, care are ca frunze literali sau variabile, iar ca rădăcină are valoarea expresiei. Fiecare nod al arborelui sintactic conține un operator sau o funcție, care are ca operanzi valorile subexpresiilor din nodurile-fii. De exemplu, expresia
       a*b+3*c
corespunde următorului arbore:

Precedența operatorilor

La evaluarea unei expresii, prezinta o importanță deosebită ordinea în care se aplică operatorii pe care îi conține, deoarece de această ordine poate să depindă valoarea expresiei. În toate limbajele de programare, în care se folosesc expresii, se stabilesc și anumite reguli de precedență și de asociativitate, pe baza cărora se stabilește ordinea de evaluare.

Fiecărui operator i se asociază o precedență, adică un nivel de prioritate în aplicarea operatorului respectiv. De exemplu, în expresia a+b*c operatorul * se va aplica înaintea operatorului +, deoarece are precedența superioară. În consecință, aceasta expresie se va calcula ca și când ar fi scrisă sub forma a+(b*c).

În limbajul Java, la stabilirea ordinii operațiilor se aplica următoarele reguli:

    - operatorii unari se aplică înaintea celor binari;
    - expresiile din interiorul parantezelor se evaluează înaintea celor din exterior;
    - dacă, într-o expresie, toți operatorii au același nivel de precedență, ei se aplică de la stânga la dreapta;
    - operanzii unui operator se evalueaza înainte de a se aplica operatorul respectiv (deci operatorul se aplică întotdeauna asupra valorilor operanzilor săi); dacă operația este binară, operandul din partea stângă se evaluează înaintea celui din partea dreaptă;
    - nivelul de precedență al operatorilor se stabilește conform cu tabela de mai jos, în care:


Tabela de precedență a operatorilor în limbajul Java

.   []   ()
+ unar      - unar
++    --     !     ~      (<tip>)    new
*      /      %
+ binar      - binar
<<       >>       >>>
<      <=      >       >=    instanceof
==       !=
&
^
|
&&
||
?:
=    +=    -=    *=    /=    %=    <<=     >>=     >>>=     &=     |=     ^=
,

 
Exemplu
În programul de mai jos, a cărui sursă se găsește în fișierul EvExpresii.java, se calculează unele expresii cu numere întregi și se afișează rezultatele.
 
/* Evaluarea expresiilor */

class EvExpresii {
  public static void main(String args[]) {
    int a=23, b=500, c=17, d;
    System.out.println((a+b*c)+" "+((a+b)*c)+" "+(b/a*c)+
 " "+(b/(a*c)));
    System.out.println((-a+b*c++/3+(d=c--%4))+" "+c+" "+d);
    System.out.println((d<1 && c--==0)+" "+c+" "+d);
    System.out.println((d<1 & ++d<c)+" "+c+" "+d);
  }
}

La executarea acestui program, se obțin pe ecran următoarele rezultate:
 
8523 8891 357 1
2812 17 2
false 17 2
false 17 3

Sa urmărim acum desfășurarea calculelor care au condus la aceste rezultate.
   - s-a evaluat expresia (a+b*c), efectuându-se mai întâi înmulțirea b*c, deoarece operatorul * are precedența superioară operatorului +, și s-a obținut ca valoare numărul întreg 8523;
   - următorul operator, +, are ca operanzi numărul întreg 8523 și șirul de caractere " ". În consecință, s-a convertit numarul 8523 într-un șir (trecându-se de la forma internă a acestuia la cea externă) și s-a obținut șirul "8523", care s-a concatenat cu șirul " ", obținându-se șirul "8523 ";
  - s-a calculat expresia ((a+b)*c) obținându-se numărul întreg 8891; de data aceasta, s-a calculat mai întâi subexpresia a+b, deoarece este între paranteze;
  - s-a convertit numărul 8891 din forma internă în cea externă și s-a concatenat cu șirul obtinut anterior și cu sirul " ",  rezultând șirul "8523 8891 ";
  - s-a calculat expresia (b/a*c). Întrucît operatorii / și * au același nivel de precedență, calculul s-a făcut de la stânga la dreapta, astfel:
    . s-a efectuat împărțirea întreagă b/a, obținându-se valoarea 21;
    . s-a efectuat înmulțirea 21*c, obținându-se rezultatul 357.
  - s-a concatenat forma externă a numărului 357 cu șirul obținut anterior și cu șirul "  ", obținându-se șirul "8523 8891 357 ";
  - s-a calculat expresia (b/(a*c)), efectuându-se acum mai întâi înmultirea a*c, apoi împărțirea întreagă a valorii lui b la rezultatul înmulțirii și s-a obținut valoarea 1;
  - s-a concatenat forma externă a acestei valori cu șirul obținut anterior, obținându-se șirul "8523 8891 357 1" care a fost afișat pe ecran, după care s-a trecut la linie nouă.

Recomandăm să urmăriți în același mod cum s-au calculat și afisat celelalte expresii. Menționăm că:
  - la evaluarea expresiei (-a+b*c++/3+(d=c--%4))prezinta interes cu ce valori intră în calcul variabila c și ce valoare are operandul din dreapta al ultimului operator +;
  - avand în vedere că valoarea expresiei d<1 este false, la aplicarea operatorului && nu s-a mai evaluat al doilea operand, deci variabila c a rămas la valoarea ei anterioară, in timp ce la aplicarea operatorului & a fost evaluat și al doilea operand, astfel că variabila d a fost incrementată.



© Copyright 2000 - Severin BUMBARU, Universitatea "Dunărea de Jos" din Galați