CATEGORII DOCUMENTE |
DOCUMENTE SIMILARE |
|
TERMENI importanti pentru acest document |
|
Controlul instructiunilor
1. Operatori relationali, de egalitate si logici
2. Operatori si expresii relationale
Operatori si expresii de egalitate
4. Operatori logici si expresii logice
5. Evaluare rapida (short-circuit)
6. Instructiunea compusa
7. Instructiunea vida
8. Instructiunile 'if' si 'if-else'
9. Instructiunea 'while'
10. Instructiunea 'for'
11. Operatorul ','
12. Instructiunea 'do'
1 Instructiunea 'goto'
14. Instructiunile 'break' si 'continue'
15. Instructiunea 'switch'
16. Operatorul conditional
17. Exercitii propuse spre implementare
========
Capitolul 3
========
==================
Controlul instructiunilor
==================
-------- ----- ------ ----- ----- -----------
Operatori relationali, de egalitate si logici
-------- ----- ------ ----- ----- -----------
Operatori relationali : <, >, <=, >=
Operatori de egalitate: ==
Operatori logici , &&, ||
Ca si ceilalti operatori, acesti operatori au reguli de precedenta si asociativitate care determina precis modul de evaluare a acestor
expresii.
-------- ----- ------ -------- ----- ------ ----- ----- ----
| Operatori | Asociativitate |
-------- ----- ------ -------- ----- ------ ----- ----- ----
() ++ (postfix) -- (postfix) | de la stanga la dreapta |
+ (unar - (unar) ++ (prefix) -- (prefix) | de la dreapta la stanga |
* / % | de la stanga la dreapta |
+ - | de la stanga la dreapta |
< <= > >= | de la stanga la dreapta |
== != | de la stanga la dreapta |
&& | de la stanga la dreapta |
|| | de la stanga la dreapta |
| de la dreapta la stanga |
= += -= *= /= etc | de la dreapta la stanga |
, (operatorul virgula) | de la stanga la dreapta |
-------- ----- ------ -------- ----- ------ -------------
Operatorul ! este unar, spre deosebire de toti operatori (relationali, de egalitate si logici) care sunt binari. Toti operatorii vor fi prezenti in expresii ce pot lua valoarea intreaga 1 sau 0. Motivul este ca C reprezinta 'false' orice expresie egala cu zero, si 'true' orice expresie diferita de zero.
------------
Exemple: In continuare, dam o lista de expresii ce se evaluaza la false
------------
1. O expresie de tip int ce are valoarea 0;
2. O expresie de tip float ce are valoarea 0.0;
Caracterul null '0';
4. Pointerul NULL.
-------- ----- ------ --------
Operatori si expresii relationale
-------- ----- ------ --------
Am vazut ca operatorii <, >, <=, >= sunt toti binari. Expresiile ce contin acesti operatori pot lua valoarea 0 sau 1.
-----------
Exemple. Primele patru exemple sunt corecte, restul sunt gresite:
-----------
1. a < 3
2. a > b
-1.1 >= (2.2 * x + 3)
4. a < b < c (corecta, dar confuza)
5. a =< b
6. a < = b
7. a >> b
Fie expresia relationala 'a < b'. Daca valoarea lui a este mai mica decat valoarea lui b, atunci expresia va avea valoarea 1, pe care o gandim ca fiind 'true'. Daca valoarea lui a este mai mare decat valoarea lui b, atunci expresia va avea valoarea 0, pe care o gandim ca fiind 'false'. Observam ca valoarea lui 'a < b' este aceeasi cu valoarea lui 'a - b < 0'. Folosind precedenta operatorilor aritmetici, aceasta este deci echivalenta cu '(a - b) < 0'. De altfel, pe multe masini, expresii cum sunt 'a < b' sunt implementate ca fiind 'a - b < 0'.
-----------
Exemple: Vom considera urmatorul tabel cu declaratii si initializari.
-----------
Presupunem ca avem declaratiile:
int i = 1, j = 2, k = 3;
double x = 5.5, y = 7.7;
-------- ----- ------ -------- ----- ------ ----
| Expresie | Expresie echivalenta | Valoare |
-------- ----- ------ -------- ----- ------ ----
i < j - k i < (j - k) 0
- i + 5 * j >= k + 1 ((- i) + (5 * j)) >= (k + 1) 1
x - y <= j - k -1 (x - y) <= ((j - k) - 1) 1
x + k + 7 < y / k ((x + k) + 7) < (y / k) 0
|----- ----- ------------|-------- ----- ------ |-------------|
-------- ----- ------ ---------
Operatori si expresii de egalitate
-------- ----- ------ --------
Expresiile pot contine si operatorii de egalitate == si !=. Expresiile ce le contin au valoarea 0 sau 1.
-----------
Exemple. Primele trei exemple sunt corecte, restul sunt gresite:
-----------
1. c == 'A'
2. k != -2
x + y == 2 * x - 5
4. a = b
5. a = = b - 1
6. (x + y) =! 44
Intuitiv, o expresie de egalitate cum ar fi a == b este sau 'true' sau 'false'. Mai precis, daca a este egal cu b, atunci a == b intoarce valoarea 1 (true); altfel, aceasta intoarce valoarea 0 (false). O expresie echivalenta este a - b == 0 (aceasta este ceea ce se implementeaza la nivel masina).
Expresia 'a != b' ilustreaza folosirea operatorului 'diferit de' (sau 'nu este egal cu').
-----------
Exemple: Vom considera urmatorul tabel cu declaratii si initializari.
-----------
Presupunem ca avem declaratiile:
int i = 1, j = 2, k = 3;
-------- ----- ------ -------- ----- ------ -------
| Expresie | Expresie echivalenta | Valoare |
-------- ----- ------ -------- ----- ------ -------
i == j j == i 0
i != j j != i 1
i + j + k == - 2 * - k ((i + j) + k) == ((-2) * (- k)) 1
----- ----- ----- ----- -----|-------- ----- ------ ---|----------|
-------- ----- ------ ---------
Operatori logici si expresii logice
-------- ----- ------ ---------
Operatorul logic ! este unar, iar && si || sunt binari. Expresiile ce contin acesti operatori intorc valoarea 0 sau 1. Negarea logica poate fi aplicata unei expresii aritmetice sau unui tip pointer. Daca o expresie are valoarea 0, atunci expresia negata are valoarea 1. Daca expresia are o valoare diferita de 0, atunci expresia negata intoarce valoarea 1.
-----------
Exemple. Primele trei exemple sunt corecte, restul sunt gresite:
-----------
1. !a
(x + 7.7)
a < b || c < d)
4. a!
5. a != b (este corecta, dar se refera la operatorul 'diferit')
Unele identitati logice (din matematica) nu se 'transmit' in C. De exemplu, se stie ca 'not (not s) =s', in timp ce valoarea lui '!!5' nu este 5, ci 1. Motivul este ca operatorul '!' se asociaza de la dreapta la stanga, si deci '!!5' este echivalent cu ' !5)', care echivalent cu '!(0)', ce intoarce valoarea 1.
------------
Exemple: Vom considera urmatorul tabel cu declaratii si initializari.
------------
Presupunem ca avem declaratiile:
int i = 7, j = 7;
double x = 0.0, y = 999.9;
-------- ----- ------ -------- ----- ------ --
| Expresie | Expresie echivalenta | Valoare |
-------- ----- ------ -------- ----- ------ --
! (i - j) + 1 (! (i - j)) + 1 2
! i - j + 1 ((! i) - j) + 1 -6
! ! (x + 3) ! (! (x + 3)) 1
! x * ! ! y (! x) * (! (! y)) 1
----- ----- ------------|----- ----- --------- ----- ------|-------------|
Operatorii logici binari && si || pot fi folositi in expresii care intorc 0 sau 1.
-----------
Exemple. Primele patru exemple sunt corecte, restul sunt gresite:
-----------
1. a && b
2. a || b
a < b) && c
4. 3 && (-2 * a + 7)
5. a &&
6. a | | b
7. a & b (corecta, dar se refera la operatii peste biti)
8. &b (corecta, dar se refera la adresa lui b
Exemple: Vom considera urmatorul tabel cu declaratii si initializari.
-----------
Presupunem ca avem declaratiile:
int i = 3, j = 3, k = 3;
double x = 0.0, y = 2.3;
-------- ----- ------ -------- ----- ------ --
| Expresie | Expresie echivalenta | Valoare |
-------- ----- ------ -------- ----- ------ --
i && j && k (i && j) && k 1
x || i && j - 3 x || (i && (j - 3)) 0
i < j && x < y (i < j) && (x < y) 0
i < j || x < y (i < j) || (x < y) 1
|----- ----- ------------|-------- ----- ------ |------------|
-------- ----- ------ -----
Evaluare rapida (short-circuit)
-------- ----- ------ -----
Pentru expresiile ce contin && sau ||, evaluarea are loc cand s-a stabilit deja valoarea expresiei, eventual fara parcurgerea intregii
expresii. Astfel, presupunem ca 'expr1' se evalueaza la 0 (false). Atunci expresia
expr1 && expr2
se va evalua la 0, fara a se mai face evaluarea expresiei 'expr2'.
Alt exemplu, daca 'expr1' se evalueaza la 1 (true), atunci expresia
expr1 || expr2
se va evalua la true fara a se mai evalua expresia 'expr2'.
Uneori se mai spune ca operatorii && si || sunt lazy (adica le este lene sa mai evalueze toti operanzii din expresie).
----- ----- --------- ----- -----
Instructiunea compusa
----- ----- --------- ----- -----
O instructiune compusa este un sir de declaratii si instructiuni delimitate de acolade. Ceea ce acoladele delimiteaza se numeste 'bloc'. O instructiune compusa este ea insasi o instructiune.
-----------
Exemplu:
-----------
}
----- ----- ----- ----- -----
Instructiunea vida
----- ----- ----- ----- -----
Instructiunea vida se reprezinta cu semnul ; (punct si virgula). Ea se foloseste cand se doreste folosirea ei sintactica, si nu neaparat folosire semantica. Dupa cum vom vedea, aceasta se foloseste in constructii 'if-else' si 'for'. O expresie urmata de ; se numeste 'instructiune expresie'.
-----------
Exemplu:
-----------
a = b;
a + b + c;
;
printf('%dn', a);
-------- ----- ------ -----
Instructiunile 'if' si 'if-else'
-------- ----- ------ -----
Forma generala a instructiunii 'if' este
if (expresie)
instructiune
Semantica intuitiva este simpla. Astfel, daca valoarea expresiei este true (diferita de zero), atunci se executa instructiunea, altfel nu.
-----------
Exemplu:
-----------
Instructiunea 'if' de mai jos va testa daca se poate face impartirea cu y (ce trebuie sa fie diferit de 0):
if (y != 0.0)
x /= y;
Urmatoarele doua instructiuni
if (j < k)
min = j;
if (j < k)
printf('j este mai mic decat kn');
se pot scrie intr-una singura
if (j < k)
Instructiunea 'if-else' de mai jos este foarte apropiata de instructiunea 'if'. Aceasta are forma generala
if (expresie)
instructiune1
else
instructiune2
Semantica intuitiva este de asemenea clara. Daca valoarea expresiei este diferita de zero, atunci se executa instructiune1 si 'se sare' peste instructiune2. Daca valoarea expresiei este zero, atunci 'se sare' instructiune1, si se executa instructiune2.
------------
Exemplu:
------------
Urmatorul subprogram C de mai jos calculeaza si afiseaza minimul dintre x si y.
if (x < y)
min = x;
else
min = y;
printf('Valoarea minima = %dn', min);
----- ----- --------- ----- -----
Instructiunea 'while'
----- ----- --------- ----- -----
'While', 'for' si 'do' sunt cele trei instructiuni repetitive din limbajul C. Consideram urmatorul format general al instructiunii 'while' (iteratia sau bucla 'while').
while (expresie)
instructiune
instructiune_urmatoare
Mai intai se evalueaza expresie. Daca aceasta nu este zero (deci este 'true'), atunci se executa instructiunea, si control trece la inceputul buclei 'while'. Astfel, corpul buclei se executa de cate ori expresie se evalueaza la 'true'. Terminarea buclei are loc cand expresie ia valoarea zero (adica 'false'). In acest punct, controlul se paseaza catre 'instructiune_urmatoare'.
-----------
Exemplu
while (i <= 10)
----- ----- ----- ----- ------
Instructiunea 'for'
----- ----- ----- ----- -----
Ca si instructiunea 'while', instructiunea 'for' se foloseste pentru descrierea structurilor iterative (repetitive). Astfel constructia
for (expresie1; expresie2; expresie3)
instructiune
instructiune_urmatoare
este semantic echivalenta cu
expresie1;
while (expresie2)
instructiune_urmatoare;
Deci, se va evalua expresie1. De obicei, aceasta se foloseste pentru initializarea buclei. Apoi, se evalueaza expresie2. Daca aceasta nu este zero ('true'), atunci se executa instructiune, se evalueaza expresie3, si controlul buclei se 'paseaza' la inceputul buclei (cu deosebirea ca nu se mai evalueaza expresie1). De obicei, expresie2 este o expresie logica care controleaza bucla. Acest proces continua pana cand expresie2 este 0 (false), punct in care se plaseaza controlul catre instructiune_urmatoare.
------------
Exemplu: Exemplul de mai jos calculeaza factorialul numarului n.
------------
factorial=1;
for (i = 1; i <= n; i++)
factorial *= i;
Orice sau toate expresiile dintr-o instructiune 'for' pot lipsi, dar nu poate lipsi ;.
-----------
Exemple:
-----------
Exemplul de mai jos calculeaza suma numerelor intregi de la 1 la 10.
i = 1;
suma = 0;
for ( ; i <= 10; ++i)
suma += i;
Acesta se poate scrie echivalent:
i = 1;
suma = 0;
for ( ; i <= 10; )
suma += i++;
Daca, in schimb, lipseste expresie2, atunci obtinem o bucla infinita.
----- ----- -----------
Operatorul ','
----- ----- -----------
Operatorul ',' are cea mai mica prioritate dintre toti operatorii din C. Este un operator binar ce are ca operanzi drept expresii si se
asociaza de la stanga la dreapta. Intr-o expresie de forma
expresie1 , expresie2
se evalueaza mai intai expresie1, apoi expresie2. Expresia ',' intoarce valoarea si tipul operandului din dreapta.
-----------
Exemplu: Presupunem ca a, b sunt de tip int. Atunci expresia ','
------------
a = 0, b = 1
intoarce valoarea 1 de tipul int.
Operatorul ',' este deseori folosit in instructiunea 'for'.
----------
Exemplu: Exemplul de mai jos calculeaza factorialul numarului n (reluare).
-----------
for (factorial = 1, i = 1; i <= n; i++)
factorial *= i;
------------
Exemplu: Revenim asupra unui exemplu precedent (suma primelor N numere naturale)
------------
for (suma = 0, i = 1; i <= n; ++i)
suma += i;
se poate scrie, echivalent, in
for (suma = 0, i = 1; i <= n; suma += i, ++i);
-------------
Intrebare: Ce se intampla cu valoarea lui suma daca intervertim instructiunile
------------
suma += i cu ++i
-----------
Exemplu:
-----------
for (i=0, p = head; p != NULL; p=p -> next )
..
----- ----- ----- ----- ----
Instructiunea 'do'
----- ----- -------------
Instructiunea 'do' poate fi considerata o varianta a instructiunii 'while'. Deosebirea consta in faptul ca pentru instructiunea 'while' testul se face la inceputul ciclului, iar pentru 'do' la sfarsit. Consideram constructia de forma
do
instructiune
while (expresie);
instructiune_urmatoare
La inceput se executa instructiune, apoi se evalueaza expresie. Daca valoarea lui expresie este diferita de 0 ('true'), atunci controlul se paseaza la inceputul instructiunii 'do', si procesul se repeta. Daca expresie se evalueaza la 0 (false), atunci controlul se paseaza la instructiune_urmatoare.
-----------
Exemplu: Suma unor numere intregi diferite de 0
-----------
suma = i = 0;
do
while (i > 0);
----- ----- ----- ----- ------
Instructiunea 'goto'
----- ----- ----- ----- -----
Instructiunea 'goto' (salt neconditionat) este considerata opusa programarii structurate. Sfatul general valabil este evitarea acestei instructiuni. Totusi, in unele cazuri se poate folosi (cand simplifica controlul, cand face codul mai eficient). O instructiune de etichetare are forma:
eticheta : instructiune
unde eticheta este un identificator.
------------
Exemple:
------------
bye: exit(1);
eticheta1: a = b + c;
333: a = b + c exemplu gresit, de ce ?)
Controlul programului poate fi transferat neconditionat catre o instructiune de etichetare astfel
goto eticheta;
-------- ----- ------ -------------
Instructiunile 'break' si 'continue'
-------- ----- ------ -------------
Cele doua instructiuni
break; si continue;
intrerup controlul normal al programelor. Instructiunea 'break' va cauza iesirea din bucla in care se afla sau din instructiunea 'switch'. Instructiunea 'continue' se poate afla numai in instructiuni 'for', 'while' si 'do'. Ea are rolul de a trasmite controlul catre sfarsitul buclei respective.
-----------Exemple:
-----------
while (1)
while (contor < n)
----- ----- --------- ----- ------
Instructiunea 'switch'
----- ----- --------- ----- -----
'switch' este o instructiune conditionala ce generalizeaza o instructiune 'if-else'.
-----------
Exemplu:
-----------
switch (val)
Corpul unei instructiuni 'switch' este un exemplu de instructiune compusa. Expresia de control dintre paranteze (ce urmeaza cuvantului switch) trebuie sa fie de tip integral (vom reveni intr-un alt capitol). Dupa evaluarea lui val, controlul sare la eticheta corespunzatoare valorii lui val. De obicei, ultima instructiune dintr-un 'case' este de obicei 'break'. Daca nu exista 'break', atunci se vor executa si instructiunile din urmatoarele 'case'-uri.
Atentie ! Omiterea scrierii lui 'break' este foarte frecventa !!
Poate apare cel mult un 'default' (in general pe ultima pozitie). Cuvintele rezervate 'case' si 'default' pot apare numai in interiorul
unui 'switch'.
----- ----- --------- ----- ------
Operatorul conditional
----- ----- --------- ----- ------
Operatorul ' ' este mai putin obisnuit deoarece este ternar (cu trei argumente). Forma generala este
expresie1 ? expresie2 : expresie3
Mai intai, se evalueaza expresie1. Daca aceasta este diferita de 0 (true), atunci se evalueaza expresie2, si aceasta va fi valoarea returnata de intreaga expresie conditionala. Daca expresie1 este 0 (false), atunci se evalueaza expresie3, si aceasta va fi valoarea intregii expresii conditionale.
------------
Exemplu: Instructiunea
-----------
if (y < z)
x = y;
else
x = z;
este echivalenta cu
x = (y < z y : z;
Operatorul ?: are aceeasi prioritate cu operatorul de asignare si se asociaza de la dreapta la stanga.
-------- ----- ------ ----- ----- ----
Exercitii propuse spre implementare
-------- ----- ------ ----- ----- ----
1. Sa se scrie un program care sa calculeze minimul a trei numere (folosind o instructiune 'if-then' si una 'if' sau doua 'if-then' (fara variabila suplimentara)). Generalizare: Sa se gaseasca primele doua numere (cele mai mici) dintr-un vector de n elemente (cu numar minim de comparatii).
2. Cititi n numere de la tastatura si afisati maximul lor. Incercati sa cititi un numar arbitrar de numere (deci fara a citi acest n).
Folosind structura for, scrieti un program care calculeaza urmatoarele formule logice (sub forma unei tabele de adevar):
b1 || b3 || b5 si b1 && b2 || b4 && b5
4. Fie functia lui Collatz:
{ n/2 daca n este par
f(n) =
*n+1 daca n este impar
Sa se scrie un program C care determina k natural minim astfel incat
(f o f o o f)(n)=1.
de k ori
5. Scrieti un program C care calculeaza suma divizorilor naturali ai unui numar natural n. Un numar este perfect daca este egal cu suma divizorilor proprii pozitivi (ex: 28 = 1 + 2 + 4 + 7 + 14). Sa se genereze primele k numere perfecte (k < 5 !).
6. Operatia matematica min(x,y) se poate reprezenta ca o expresie conditionala:
(x < y x : y
Intr-un mod similar, descrieti operatiile aritmetice
min(x, y, z) si max(x, y, z, t)
7. Se stie ca un procedeu de interschimbare a valorii a doua variabile (a si b) se poate face folosind o variabila auxiliara (se foloseste in metodele de sortare, arbori, sisteme de ecuatii, etc):
aux = a ;
a = b ;
b = aux;
Sa se arate ca in limbajul C se poate face acest lucru in mod echivalent fara utilizarea explicita a unei variabile suplimentare. Asadar intervertirea valorilor a si b se poate face si astfel:
a = b + a - (b = a);
Aratati ca aceasta instructiune este echivalenta cu:
aux = b + a ;
b = a ;
a = aux - a sau a = aux - b;)
Echivalent, fara variabile suplimentare, se pot considera instructiunile:
a = a + b;
b = a - b;
a = a - b;
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 824
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved