Documente Academic
Documente Profesional
Documente Cultură
Operatori i expresii
Expresiile sunt categorii sintactice fundamentale pentru limbajul C. Practic cele mai multe i
mai des folosite instruciuni sunt construite pe baza expresiilor. Expresiile reprezint un
mijloc extrem de puternic de manipulare a valorilor, pentru c instruciunile tuturor limbajelor
procedurale acioneaz asupra datelor prin intermediul acestora.
x = 3
/*
/*
/*
/*
operand simplu */
operand simplu */
3 este operand simplu */
v este operand asupra caruia se efectueaza
operatia de indexare */
/* n este operand simplu */
/* f este operand asupra caruia se efectueaza
operatia de apel de functie */
/* doi operanzi:
- a este operand simplu,
- (b+2) este subexpresie
*/
/* doi operanzi simpli (x si 3);
Atentie: atribuirea este considerata
operator in limbajul C */
operatori logici
operatori de atribuire
operatori de adrsare
operatori la nivel de bit
operatori specifici limbajului
n funcie de numrul de operanzi asupra crora se aplic, operatorii pot fi unari, binari,
ternari, sau n cazul general n-ari (se aplic asupra a n operanzi).
Exemple.
x-y
i--a-b
n?a:b
/* operator binar */
/* operator unar */
/* primul operator este unar */
al doilea este binar */
/* ?: este operator ternar */
Din punct de vedere al poziiei operatorilor fa de operanzi, acetia pot fi n poziie prefix
(preced operanzii), postfix (urmeaz dup operanzi) sau infix (operatorul se afl ntre
operanzi). Primele dou poziii sunt specifice operatorilor unari, pe cnd ultima este specific
celor binari.
Exemple.
n++
--i
a+b
Pentru evaluarea unei expresii se iau n considerare alte dou proprieti ale operatorilor:
precedena i asociativitatea acestora. Precedena determin prioritatea operatorilor, iar
asociativitatea determin ordinea de aplicare a operatorilor consecutivi.
Pentru a determina ordinea de aplicare a operatorilor asupra operanzilor ntr-o expresie
fr paranteze, se au n vedere urmtoarele elemente:
nti se grupeaz operatorii n clase de preceden; ntr-o clas de preceden toi
operatorii au aceeai prioritate;
la evaluare, operatorii se aplic n ordinea descresctoare a precedenei;
n cadrul fiecrei clase, ordinea depinde de asociativitatea acestora (de la stnga la
dreapta sau invers).
Exemplu. Pentru expresia:
a + 2 * 3 + b + 4 + d * e * 5
Operator
()
[]
.
->
-++
+
-++
!
~
*
&
sizeof
()
*
/
%
+
<<
>>
<
<=
>
>=
==
!=
&
^
|
&&
||
?:
=
*=
/=
-=
+=
&=
^=
|=
<<=
>>=
,
Utilizare
f(e)
v[i]
r.c
p->c
a-a++
-n
+n
--a
++a
!i
~i
*p
&x
sizeof(x)
(d) e
v1 * v2
v1 / v2
i1 % i2
v1 + v2
v1 v2
i1 << i2
i1 >> i2
v1 < v2
v1 <= v2
v1 > v2
v1 >= v2
v1 == v2
v1 != v2
i1 & i2
i1 ^ i2
i1 | i2
i1 && i2
i1 || i2
i1 ? v1 :
v2
a = v
a *= v
a /= v
a -= v
a += v
a &= v
a ^= v
a |= v
a <<= v
a >>= v
e1, e2
Semnificaie
apel funcie
indexare
selecie
selecie indirect
postdecrementare
postincrementare
schimbare de semn
plus unar
predecrementare
preincrementare
negaie logic
negare la nivel de bit
adresare indirect
preluare adres
determinare dimensiune memorie
conversie de tip (cast)
nmulire
mprire
determinare rest (modulo)
Adunare
Scdere
deplasare stnga
deplasare dreapta
mai mic
mai mic sau egal
mai mare
mai mare sau egal
Egal
Diferit
i la nivel de bit
sau exclusiv la nivel de bit
sau la nivel de bit
i logic
sau logic
operator condiional
Asociere
---->
operatori de atribuire
<----
Secveniere
---->
<----
---->
---->
---->
---->
---->
---->
---->
---->
---->
---->
---->
e1
Spre deosebire de alte limbaje de programare, n limbajul C evaluarea unei expresii poate
avea i efecte laterale datorate modificrii valorilor unor variabile n timpul evalurii. Acest
lucru se poate ntmpla datorit operatorului de atribuire.
Exemplu.
if ( x + ( y = v[k]) < a)
z = 1;
else
z = 2;
n expresia condiional anterioar, se evalueaz nti subexpresia y=v[k], care are drept
efect modificarea valorii variabilei y.
Aceast facilitate permite descrierea mai compact a unor secvene de prelucrri care
n mod normal necesit mai multe instruciuni de atribuire. n cazul utilizrii excesive a
acestui stil de programare, exist ns riscul srierii unor programe criptice, greu de neles i
nu ntotdeauna corecte.
Un alt aspect ce intervine n operaia de evaluare a unei expresii se refer la
conversiile automate ale tipurilor de date ale diferitelor valori ce intervin ntr-o expresie.
Exist mai multe motive ce impun conversii de tip, principala cuz fiind determinat de
tipurile de date diferite ale operanzilor asupra crora se aplic un operator.
Marea majoritate a operatorilor, n special cei aritmetici, necesit operanzi de acelai
tip, iar din acest motiv, n cazul n care operanzii sunt de tipuri diferite, este necesar (dac
este posibil) o operaie de conversie a valorii unui operand sau a ambilor operanzi. Acest
operaie se numete n mod uzual reechilibrare, regula de baz fiind urmtoarea:
dac operanzii sunt de tip unsigned int i long atunci
dac valorile unsigned int pot fi reprezentate ca long atunci
tipul echilibrat este long
altfel
tipul echilibrat este unsigned int
altfel
tipul echilibrat este tipul unuia dintre cei doi operanzi,
care apare ultimul n lista:
int
unsigned int
long
unsigned long
float
double
long double
Tipul de date al valorii rezultate n urma evalurii unei expresii simple este stabilit n urma
operaiei de echilibrare.
Aa cum se observ, regula presupune existana a doi operanzi. n cazul operatorilor
unari, este evident faptul c nu este necesar operaia deechilibrare. n cazul operatorului
condiional, care este singurul operator ternar al limbajului C, ultimii doi operanzi sunt cei
care conteaz la determinarea tipului valorii rezultate.
Eval(2.0/4.0) = 0.5
Eval(2/4.0) = 0.5
Eval(2/4) = 0
pe cnd instruciunea:
n = ++k;
Se observ faptul c n cele dou cazuri, valoarea variabilei n este diferit dup evaluarea
expresiei respective.
n general, la evaluarea unei expresii ce conine un operand care este o subexpresie care
conine la rndul ei un operator de incrementare/decrementare se utilizeaz urmtoarea regul:
n cazul unui operator prefix de incrementare/decrementare, nti se modific valoarea
operandului aferent operatorului i apoi se evalueaz expresia;
n cazul unui operator postfix, se evaluaeaz nti expresia cu valoarea veche a
operandului aferent operatorului de incrementare/decrementare i apoi se modific
valoarea operandului.
Un caz uzual de utilizare al operatorilor de incrementare/decrementare se refer la operaiile
cu tablouri, cnd se dorete modificarea indicilor. De exemplu, instruciunea urmtoare
iniializeaz un tablou cu valorile: xk = k, k = 0, 1, , n-1:
for (k=0; k<n; x[k++]=k);
mai mic
mai mic sau egal
mai mare
>=
==
!=
Aceti operatori sunt binari i presupun operaia de echilibrare a valorilor operanzilor. Din
punct de vedere al prioritii, ei se mpart n dou clase de preceden:
<, <=, >, >=
==, !=
Din punct de vedere matematic, rezultatul unei operaii de comparare este o valoare logic.
Conform regulilor de interpretare a valorilor logice n limbajul C, rezult c rezultatul
evalurii unei expresii de relaie poatr fi:
- constanta zero, n cazul n care valorile operanzilor nu respect relaia aferent
operatorului;
- o constant ntreg diferit de zero (n mod uzual canstanta 1 pentru multe
compilatoare) n caz contrar.
Observaie. Nu trebuie confundat operatorul de comparare (==) cu cel de atribuire (=). n
cazul utilizrii din greeal a operatorului de atribuire n locul celui de comparare, efectul
lateral al operaiei de atribuire este greu de detectat n anumite situaii.
Exemplul 6.1. Secvena urmtoare testeaz dac o valoare dintr-un ir de numere este egal
cu o anumit valoare dat.
int k, n, y = 7, v[4];
/* ... */
for (k=0; k<n; k++)
if (v[k] == y)
printf(Valoare gasita in sir pe pozitia %d\n, k);
expresia condiional ar fi fost tot timpul adevrat, deoarece prin atribuirea v[k]=y,
valoarea lui v[k] ar fi fost alterat la valoarea 7.
O alt problem n utilizarea expresiilor condiionale o poate constitui apariia operatorilor de
incrementare/decrementare, datorit posibiltii poziiei prefixe sau postfixe a acestora. n
acest caz rezultatul evalurii unei expresii condiionale depinde de poziia operatorilor.
Exemplul 6.2. Urmtoarea secven calculeaz suma: S = 1 + 1/2 + 1/(n-1)
int n
float
while
s =
= 4;
s = 0;
(--n > 0)
s +1.0/n;
execuia programului n acest caz va genera o eroare (mprire la zero). n acest caz, la
nceputul fiecrei iteraii se evalueaz nti expresia condiional i apoi se decremanteaz
valoarea lui n. Astfel, la iteraia a 4-a n va avea valoarea 1 i deci expresia condiional este
adevrat, dar nainte de execuia instruciunii de atribuire interne instruciunii while,
valoarea lui n se va decrementa, instruciunea fiind de fapt: s = s +1.0/0;
negaie logic
conjuncie logic (i logic)
disjuncie logic (sau logic)
Observaie. Prezena parantezelor rotunde nu este necesar, deoarece dup cum se poate
observa din tabelul tuturor operatorilor, operatorii de relaie au o preceden mai mare dect
operatorii logici i subexpresiile x >= a , x >= a se evalueaz primele.
Rezultatul evalurii unei expresii logice se determin n conformitate cu tabelel de adevr ale
celor trei operaii. n figura 6.1, a i b reprezint doi operanzi ntregi, iar x o valoare ntreag
diferit de zero:
a
b
0
x
a && b
b
0
x
!a
0
x
x
0
a || b
!a
Ordinea de evaluare a expresiilor logice este de la stnga la dreapta. Datorit acestui fapt i n
concordan cu semantica operatorilor logici, n anumite situaii o expresie logic nu este
evaluat pn la sfrit.
Dac n programul precedent s-ar inversa poziia operanzilor din expresia condiional:
if (x[k] > 0 || (d=x[k]*x[k])<y)
programul ar conine o eroare: n cazul n care x[k]>0, a doua subexpresie nu mai este
evaluat i valoarea variabilei d nu este calculat corect.
Din acest motiv, este indicat ca expresiile cu efecte laterale s fie plasate n fa, sau
atribuirile ce constituie efecte laterale s fie scoase n afara (dar naintea) expresiilor
condiionale.
Din punct de vedere pragmatic, atribuirea presupune dou aciuni distincte, o operaie de
evaluare i una de scriere n memorie i const n scrierea valorii rezultate n urma evalurii
expresiei din dreapta operatorului de atribuire n zona de mamorie asociat variabilei din
partea stng. Din acest motiv, n sintaxa anterioar, variabil nu nseamn neaprat
numele unei variabile simple, ci o construcie sintactic ce are asociat o zon de memorie.
Exist dou noiuni importante legate de lucrul cu variabile i valori: noiunea de Lvaloare i cea de R-valoare. Valoarea curent a unei variabile (coninutul zonei de memorie
ataat) reprezint R-valoarea variabilei (right value, valoarea din partea dreapt a
operatorului de atribuire), iar adresa zonei de memorie ataat variabilei este o L-valoare (left
value, valoarea din partea stng a operatorului de atribuire).
Deoarece n dreapta operatorului de atribuire poate fi o expresie, care evaluat produce
o valoare, prin extensie se numete R-valoare orice valoare specific unui tip de date
fundamental sau derivat, cu excepia funciilor i tablourilor. n mod asemntor, deoarece n
partea stng a operatorului de atribuire poate fi o construcie sintactic ce genereaz o adres
de memorie, se numete L-valoare adresa de memorie a unei valori de orice tip. n plus, exist
noiunea de F-valoare, care este o referin ctre o funcie.
Exemple.
int n = 10, v[7];
float x, *px;
struct { int k; float r; } a;
int f(int);
int (*pf)(float) = f1;
/* pf este un pointer la o functie cu un parametru
de tip float care returneaza un intreg
*/
void f2(float);
v[3] = n;
/* n este R-valoare, v[3] este L-valoare */
x = 1;
/* 1 este R-valoare, x este L-valoare */
px = &x;
/* &x este R-valoare, px este L-valoare */
a.k = v[3];
/* v[3] este R-valoare, valoarea componantei a 4-a
a tabloului v, a.k este L-valoare, adresa
de memorie a componentei k din variabila a
*/
n = (*pf)(v[3]);
/* v[3] este R-valoare, n este L-valoare,
*pf este F-valoare, o referinta spre functia f1,
iar (*pf)(v[3]) este R-valoare
*/
f2(*px);
/* *px este o R-valoare, continutul zonei de
memorie indicata de px, iar f2 este F-valoare
*/
O problem poate apare n cadrul operaiei de atribuire dac operandul din stnga i din
dreapta atibuirii nu au acelai tip de date. n cazul n care tipurile sunt incompatibile se
genereaz un mesaj de eroare, iar n cazul n care ele sunt compatibile, dar diferite, are loc o
conversie de tip. Mai exact, valoarea expresiei din dreapta este convertit la tipul variabilei
din stnga. n general, rezultatul unei asemenea conversii este dependent de implementare i
poate conduce la depiri.
Exemple.
float s;
s = 2;
/* se converteste intregul 2 la valoarea
reala 2.0; corect
*/
int n;
n = 12.73;
/* se converteste valoarea reala 12.73 la valoarea
intreaga 12 prin trunchiere; corect
*/
n = 124E200;
/* depasire, deoarece partea intreaga a numarului
124*10200 nu se poate reprezenta ca o valoare
intreaga; gresit
*/
Dup cum s-a precizat anterior, o particularitate a limbajului C este aceea c trateaz
atribuirea ca un operator uzual ce poate interveni n cadrul expresiilor. Aceasta permite
modificarea valorii unei variabile n timpul evalurii unei expresii, ceea ce reprezint un efect
lateral al operaiei de evaluare (al crui scop principal este s produc o valoare dup
evaluare).
Exemplul 6.4. Se va relua problema referitoare la determinarea celui mai mare divizor
comun. n programul anterior, din exemplul 3.5, expresia folosit pentru determinarea restului
era evaluat de dou ori: o dat n expresia condiional a instruciunii while, iar a doua oar
n corpul acesteia.
while(m%n != 0) {
r = m%n;
m = n;
n = r;
}
se atribuie nti variabilei a valoarea 5, apoi lui b i apoi lui c. Instruciunea anterioar este
tratat de ctre compilator ca avnd forma urmtoare:
c = (b = (a = 5));
fr scrierea de dou ori a L-valorii (n acest caz operator este un operator binar).
Pentru expresiile de forma anterioar, scrierea compact este urmtoarea:
variabil = operator_compus expresie
Avantajul utilizrii operatorilor compui de atribiure apare n situaiile n care L-valoarea din
cadrul atribuirii nu este o variabil simpl, ci o expresia mai complex, coninnd la rndul ei
mai muli operatori i operanzi. De exemplu, instruciunea:
grupa[i].situatie.nr_restante =
grupa[i].situatie.nr_restante + 1;
Observaie. n cazul n care expresia din dreapta operatorului compus de atribuire conine la
rndul ei operatori, aceasta este tratat de ctre compilator ca o subexpresie inclus ntre
paranteze. De exemplu, instruciunea:
x *= y + 1;
x = x * (y + 1);
i nu cu instruciunea:
x = x * y + 1;
unde este o entitate ce memoreaz adresa unui element din program. Rezultatul evalurii
unei asemenea expresii este valoarea elementului a crui adres este memorat de ctre
pointer.
Exemple:
int a = 3, b, *p;
p = &a;
/* pointerul p memoreaza adresa variabilei a */
b = *p;
/* b primeste valoarea elementului a carui
adresa este memorata de p, adica 3
*/
b
0
1
a&b
~a
0
1
1
0
a^b
a|b
~a
0
0
1
0
0
0
0
1
1
0
1
1
0
1
1
0
1
1
1
1
0
1
1
0
0
1
1
0
1
1
1
0
0
0
1
1
1
1
0
1
1
0
0
1
1
0
1
1
n cazul operatorilor de deplasare, cei doi operanzi au semnificaii diferite: primul reprezint
numrul ai crui bii se deplaseaz, iar al doilea specific numrul de poziii cu care se face
deplasarea n direcia respectiv. De exemplu, expresia n << 2 specific faptul c cifrele
binare ale numrului n se vor deplasa cu dou poziii spre stnga.
La deplasarea spre stnga cu k cifre, primii k bii ai numrului se pierd, iar ultimii k se
completeaz cu zero. La deplasarea spre dreapta cu k cifre, ultimii k bii ai numrului se
pierd, iar primii k se completeaz cu cifra binar 0 sau 1, cifr ce depinde de implementare
(valoarea nu se specific in standardul limbajului).
Dac valoarea expresiei de deplasare este negativ, sau depete lungimea de
memorie a operandului din stnga, semnificaia operaiei este nedefinit.
Exemplu pentru un operand de tip char:
a
a << 2
a >> 2
0 0 1 1 1 1 0 1
1 1 1 1 0 1 0 0
0 0 0 0 1 1 1 1
else
Return 0;
return 1;
}
O masc reprezint un grup de cifre binare 1 consecutive i se utilizeaz pentru a putea reine
din mai multe cifre binare un grup de cifre dorit. Selecia grupului de cifre se realizeaz cu
ajutorul operaiei i la nivel de bit ntre numrul dorit i ablon.
n exemplu, s-au utilizat dou mti: prima reine primii 3 bii (masca_tip_operatie),
iar a doua ultimii 5 bii (masca_distanta). Dup efectuarea operaiei i la nivel de bit, se
obin utmtoarele structuri de cifre binare:
Comanda
Masca_tip_operatie
Masca_distanta
Tip_operatie
Distanta
Tip_operatie >> 5
b7
1
0
b7
0
0
b6
1
0
b6
0
0
b5
1
0
b5
0
0
b4
0
1
0
b4
0
b3
0
1
0
b3
0
b2
0
1
0
b2
b7
b1
0
1
0
b1
b6
b0
0
1
0
b0
b5
Valoarea corect pentru masca_tip_operatie se obine dup o deplasare spre stnga cu 5 cifre
binare. Dup selectarea biilor b7, b6 i b5 din cadrul octetului aferent unei comenzi, acetia
trebuie deplasai spre dreapta cu 5 cifre binare. n acest mod, octetul corespunztor variabilei
tip_operatie poate fi utilizat simplu prin valoarea sa n cadrul expresiilor condiionale din
instruciunile if (de exemplu: 00000101 reprezint valoarea 5, 00000100 reprezint
valoarea 4, etc.).
sau
sizeof
expresie_unar
n primul caz operatorul se aplic direct asupra tipului de date specificat, iar n al doilea se
aplic asupra tipului de date al expresiei respective.
Operatorul returneaz o valoare ntreag, reprezentnd numrul de octei necesari
pentru memorarea valorilor tipului asociat.
Observaie. Expresia unar este o expresie care nu conine operatori binari sau ternari. n
cazul unei expresii complexe, operatorul sizeof se va aplica numai asupra primului
operand. De exemplu, considerndu-se secvena:
int n1, n2, n3, a = 5;
double b = 2.2;
n1 = sizeof a + b;
n2 = sizeof (a + b);
n3 = sizeof(double);
se observ faptul c valorile lui n2 i n3 sunt egale. Presupunnd faptul c valorile de tip int
se memoreaz pe 4 octei i cele de tip double pe 8 octei, valorile lui n2 i n3 sunt ambele
egale cu 8 (n cazul lui n2, nu se evaluaeaz expresia a + b, ci se determin tipul de date al
acesteia), iar valoarea lui n1 este 7 (conversia valorii 7.2 la valoare ntreg). Se remarc
urmtoarele echivalene:
n1 = Eval(sizeof a + b) =
= Eval(sizeof a) + Eval(b)
n cazul n care operandul lui sizeof este numele unui tablou, acesta nu este convertit la un
pointer. Valoarea returnat n acest caz reprezint numrul total de octei alocat tabloului
respectiv. De exemplu, n secvena:
int n1, n2, a[10], *p;
n1 = sizeof (a);
n2 = sizeof (p);
presupunnd faptul c valorile de tip int se reprezint pe 2 octei, valoarea lui n1 este 20, pe
cnd valoarea lui n2 (p are tipul int*) este n general 4 (adic numrul de octei necesari
pentru memorarea adresei unui obiect de tip int).
B) Operatorul de conversie de tip
Acest operator, numit i operator cast, determin schimbarea forat a tipului de date a
valorii unei expresii sau subexpresii la un alt tip de date specificat explicit de programator.
Operatorul cast are o poziie prefix, forma de utilizare fiind urmtoarea:
( tip )
expresie_unar
Se evalueaz expresia unar, iar rezultatul este convertit la tipul specificat ntre paranteze.
Observaie. Ca i n cazul operatorului sizeof, trebuie avut grij n cazul n care expresia
n care apare operatorul cast este mai complex (operatorul se aplic doar asupra
operandului urmtor). De exemplu, n cazul n care variabilele a i b sunt de tip ntreg:
int a = 5, b = 7;
n cadrul expresiei:
(double) a / b;
operatorul cast se aplic doar asupra variabilei a schimbndu-i valoarea ntrag 5 n constanta
de tip double 5.0, astfel nct operatorul / joac rol de mpire real.
O folosire uzual a operatorului cast este n cazul apelului funciilor, fie cnd se dorete
conversia tipului de date a valorii returnate de o funcie, fie cnd se dorete conversia tipului
de date al parametrilor de apel.
Exemple.
1) O funcie des utilizat pentru alocarea memoriei n zona heap a programului este
malloc, care are prototipul:
void* malloc(size_t);
Dac se dorete s se aloce memorie pentru o valoare de tip float, se poate utiliza un
pointer, ca n secvena urmtoare:
float *p;
p = (float*)malloc(sizeof(float));
Se convertete astfel tipul void* la tipul float* pentru a exista compatibilitate cu tipul
variabilei p.
2) O funcie matematic corespunztoare operaiei de ridicare la putere este funcia pow, care
are prototipul:
double pow(double, double);
n cazul n care a i b sunt dou variabile ntregi, apelul acestei funcii se poate scrie:
x = pow((double)a, (double)b);
Observaie. Operatorul nu afecateaz valoarea variabilelor din cadrul expresiei, astfel nct a
i b i pstreaz valorile iniiale.
C) Operatorul condiional (?:)
Acesta este singurul operator ternar al limbajului C i are urmtoarea form de utilizare:
expr.1 ? expr.2 : expr.3
Denumirea sa provine de la faptul c valoarea de evaluare a unei asemenea expresii depinde
de tipul primei expresii:
Eval( exp r.2 ), daca Eval( exp r.1 ) 0
Eval( exp r.1 ? exp r.2 : exp r.3 )
Eval( exp r.3 ), daca Eval( exp r.1 ) 0
Avantajul utilizrii unui asemenea operator const n faptul c permite scrierea unui cod
compact i evitarea utilizrii intruciunilor if.
Exemplul 6.7. Presupunnd faptul c variabila c este de tip caracter i memoreaz n timpul
execuiei programului o cifr a bazei de numeraie 16:
c {0, 1, ..., 9} {a, b, ..., f}
Observaie. S-a utilizat poziia relativ a caracterelor alfabetice i numerice din tabela de
caractere.
Operatorii condiionali pot fi imbricai. De exemplu, pentru a determina valoarea maxim a
trei numere, x, z i z, se poate scrie funcia urmtoare:
double max3(double x, double y, double z) {
return (x > y) ? (x > z ? x : z) : (y > z ? y : z) ;
}
unde cel puin o expresie este o expresie de atribuire. Ea se utilizeaz atunci cnd sintaxa
limbajului presupune prezena unei singure expresii, dar algoritmul problemei de rezolvat
necesit prelucrarea secvenial a mai multor expresii.
Operatorul de secveniere nu poate fi utilizat pentru a separa elementele dintr-o list.
n mod uzual, el se folosete n cadrul unei expresii condiionale, sau ntr-o expresie ce
conine paranteze.
Evaluarea unei asemenea expresii se face de la stnga la dreapta, valoarea de evaluare fiind de
fapt valoarea ultimei expresii:
Eval(expr.1, expr.2 , ... , expr.k) = Eval(expr.k)
Celelalte expresii sunt folosite de obicei pentru efectele laterale pe care le produc.
De exemplu, presupunnd c variabilele x, y, z i t sunt de tip numeric, atunci instruciunea:
z = (x > y) ? x : y;
are acelai efect, dar n plus realizeaz i ordonarea cresctoare a valorilor x i y. O utilizare
eronat este urmtoarea:
z = (x > y) ? (t = y, y = x, x = t) : y;
6.9 Probleme
6.1. S se scrie un program pentru rezolvarea ecuaiaei biptrate: a*x4 + b*x2 + c = 0.
6.2. S se scrie un program pentru rezolvarea problemei 2.3.