Capitolul 2.12. Ponderea si ordinea de evaluare

Vezi subiectul anterior Vezi subiectul urmator In jos

Capitolul 2.12. Ponderea si ordinea de evaluare

Mesaj  zooky la data de Mier Mar 18, 2009 11:53 am

Tabelul de mai jos rezuma regulile de pondere si asociativitate pentru toti operatorii, inclusiv pentru aceia pe care nu i-am discutat inca. Operatorii de pe aceeasi linie au aceeasi pondere; liniile sint in ordine de pondere descrescatoare, astfel ca, de exemplu, "*", "/" si "%" au o aceeasi pondere, care este mai mare decit a lui "+" "-".

+------------------------------+--------------------------------+
| () [] -> . | de la stinga la dreapta |
+------------------------------+--------------------------------+
| ! ~ ++ -- - (tip) * & sizeof | de la dreapta la stinga |
+------------------------------+--------------------------------+
| * / % | de la stinga la dreapta |
+------------------------------+--------------------------------+
| + - | de la stinga la dreapta |
+------------------------------+--------------------------------+
| << >> | de la stinga la dreapta |
+------------------------------+--------------------------------+
| < <= > >= | de la stinga la dreapta |
+------------------------------+--------------------------------+
| == != | de la stinga la dreapta |
+------------------------------+--------------------------------+
| & | de la stinga la dreapta |
+------------------------------+--------------------------------+
| ^ | de la stinga la dreapta |
+------------------------------+--------------------------------+
| | | de la stinga la dreapta |
+------------------------------+--------------------------------+
| && | de la stinga la dreapta |
+------------------------------+--------------------------------+
| || | de la stinga la dreapta |
+------------------------------+--------------------------------+
| ? : | de la dreapta la stinga |
+------------------------------+--------------------------------+
| = += -= etc | de la dreapta la stinga |
+------------------------------+--------------------------------+
| , (Capitolul 3) | de la stinga la dreapta |
+------------------------------+--------------------------------+

Operatorii -> si. sint folositi pentru a accede membrii structurilor; ei vor fi iscutati in Capitolul 6, impreuna cu sizeof (marimea unui obiect). Capitolul 5 discuta * (indirectarea) si & (adresa lui ...).

Sa notam ca ponderea operatorilor logici pe biti &, | si ^ este sub == i |=. Aceasta implica faptul ca expresiile care testeaza biti, ca de exemplu

if (( x & MASK) == 0) ...

trebuie sa fie cuprinse in intregime intre paranteze, pentru a da rezultatele asteptate.
Asa cum am mentionat mai inainte, expresiile ce implica operatori asociativi si comutativi (+, *, &, ^, |) pot fi rearanjate chiar daca sint cuprinse in paranteze. In marea majoritate a cazurilor, aceasta nu da diferente; in situatia in care ar da, se pot folosi variabile temporare explicite pentru a forta o ordine de evaluare particulara.

Limbajul C, ca si majoritatea celorlalte limbaje, nu specifica in ce ordine se evalueaza operanzii unui operator. De exemplu, in instructiuni de tipul

x = f() + g();

f poate fi evaluat inaintea lui g sau viceversa; deci, daca sau f sau g altereaza o variabila externa de care depinde si cealalta, x poate depinde de ordinea de evaluare. Din nou, rezultatele intermediare pot fi stocate in variabile temporare pentru a fi siguri de o anumita secventa.
In mod similar, ordinea in care sint evaluate argumentele unei functii nu este specficata, asa ca instructiunea

printf("%d %d\n", ++n, power(2, n)); /* GRESIT */

poate (si o si face) produce rezultate diferite, pe diferite calculatoare, depinzind de faptul daca n este incrementat sau nu inainte de apelul lui power. Solutia, desigur, este sa scriem:

++n;
printf("%d %d\n", n, power(2, n));

Apelurile de functii, instructiunile de asignare imbricate, operatorii de incrementare si decrementare provoaca "efecte secundare" - o anumita variabila este modificata ca un produs al unei evaluari de expresie. In orice expresie implicind efecte secundare, pot exista subtile dependente de ordinea in care sint stocate variabilele ce iau parte in expresie. O situatie nefericita este ilustrata de instructiunea:

a[i] = i++;

Chestiunea consta in a sti daca indicele este noua valoare a lui i sau daca este vechea. Compilatorul poate face aceste lucruri in moduri diferite, depinzind de interpretarea sa. Cind efectele secundare (asignare la variabile efective) au loc, sint lasate la discretia compilatorului, caci cea mai buna ordine depinde puternic de arhitectura calculatorului.
Morala acestei discutii este aceea, ca scrierea de cod ce depinde de ordinea de evaluare, este o proasta practica de programare in orice limbaj. Natural, e necesar sa stim ce lucruri trebuie evitate, dar daca nu stim cum sint ele facute pe diferite calculatoare, aceasta inocenta ne va ajuta sa ne protejam. (Verificatorul lui C, lint, detecteaza majoritatea dependentelor de ordinea de evaluare).
avatar
zooky
Moderator
Moderator

Numarul mesajelor : 147
Data de inscriere : 15/03/2009
Varsta : 24
Localizare : Cernatesti City

Vezi profilul utilizatorului http://e-learning.forumhit.ro

Sus In jos

Vezi subiectul anterior Vezi subiectul urmator Sus


 
Permisiunile acestui forum:
Nu puteti raspunde la subiectele acestui forum