Documente Academic
Documente Profesional
Documente Cultură
Instruciuni
expresie
Execuia unei instruciuni expresii se reduce la evaluarea expresiei asociate. n mod uzual
expresia asociat este reprezentat de o instruciune de atribuire sau de un apel de funcie, sau
de o operaie de incrementare/decrementare i deci evaluarea ei are i un efect lateral prin
modificarea valorii unei variabile (sau mai multe) din cadrul expresiei.
Exemple de instruciuni expresii:
x = sin(y) + z;
i++;
n = (u > v) ? u : v;
printf(Exemplu de instructiune expresie\n);
}
declaraii/
definiii
instruciune
Se observ faptul c sintaxa limbajului permite scrierea unui bloc ce nu conine nici declaraii
i nici instruciuni. Blocul repectiv reprezint n acest caz un bloc vid. Blocurile vide sunt
utilizate mai ales n etapa de dezvoltare i testare a programelor, ele putnd fi completate pe
msur ce s-a testat funcionalitatea unui program pn n momentul respectiv.
O alt situaie n care s-ar putea utiliza un bloc vid corespunde cazului cnd sintaxa
limbajului impune prezena unei instruciuni, dar n algoritmul de rezolvare al problemei nu
trebuie efectuat nici o aciune. n aceste cazuri este preferabil utilizarea instruciunii vide,
care se scrie mai simplu, deoarece nu conine dect caracterul ;.
instruciunea
;
vid
if
if
else
expresie
instruciune
instruciune
n primul caz (o instruciune if intern aflat pe alternativa if) pot exista confuzii
semantice doar din punctul de vedere al programatorului. De exemplu, n cazul unei
instruciuni de forma:
if (<expr1>)
if (<expr2>)
<instr1>;
else
<instr2>;
Cazul II.
k1 k2 0
pentru i 1 la n execut
citete x
dac x > a atunci
dac x > b atunci
k2 k2 + 1
altfel
k1 k1 + 1
scanf(%f, &x);
if (x < a)
if (x < b)
k2++;
else
k1++;
}
/* Cazul II. */
for (i=0; i<n; i++) {
scanf(%f, &x);
if (x < a) {
if (x < b)
k2++;
}
else
k1++;
}
Dup cum se observ, problema apare la asocierea alternativei else. Semantica limbajului
este clar: instruciunea care apare dup cuvntul else se asociaz ntotdeauna ultimei
instruciuni if incomplete (care nu are alternativ else).
n concluzie, dac pe ramura else a unei instruciuni if se apeleaz tot o
instruciune if incomplet (fr ramur else), atunci aceasta fie trebuie ncadrat ntre
acolade (ca n exemplul precedent), fie trebuie s i se adauge o alternativ else inefectiv (o
instruciune vid pe aceast alternativ). De exemplu, cazul II anterior se mai poate scrie
astfel:
/* Cazul II. */
for (i=0; i<n; i++) {
scanf(%f, &x);
if (x < a)
if (x < b)
k2++;
else
;
else
k1++;
}
B) Instruciunea switch
n mod uzual, instruciunile din cadrul unui bloc sunt executate n mod secvenial, ncepnd
cu prima instruciune a blocului. Instruciunea switch permite ca din cadrul instruciunilor
unui bloc, s se execute doar un grup, ncepnd cu o anumit instruciune specificat.
Sintaxa de utilizare a instruciunii switch este urmtoarea:
instruciunea
switch
switch
expresie
instruciune
etichetat
}
default
instruciune
case
expresie
constant
instruciune
case 2:
y *= x;
case 1:
y *= x;
}
printf(y = %lf\n, y);
return 0;
}
Observaii:
1) n cazul n care exist mai multe expresii constante care au aceeai valoare, se va selecta
instruciunea asociat primei etichete.
2) Este posibil ca o instruciune s aib asociate mai multe etichete, ceea ce face ca aceasta
s poat fi selectat prin mai multe valori.
Folosirea uzual a instruciunii switch este mpreun cu instruciunea break. n acest mod
se poate selecta pentru execuie o singur secven se instruciuni din mai multe posibile.
Instruciunea break este format doar din cuvtul cheie break i are ca efect
terminarea forat a instruciunii structurate n care ea apare. Din acest motiv, dac ultima
instruciune dintr-o secven este break, toate celelalte instruciuni din blocul instruciunii
switch nu se mai execut.
n concluzie, dac se dorete ca secvenele de instruciuni din cadrul instruciunii
switch s fie disjuncte (n mod asemntor instruciunii case din limbajul Pascal), se
adaug la sfritul fiecrei secvene (mai puin eventual la sfritul ultimei secvene) cte un
break. Astfel rezult alternative disjuncte la execuie.
Exemplul 7.3. Determinarea valorii unei funcii de dou variabile de forma urmtoare:
1 x 2 , n 1
1 sin( x), n 2
f ( x, n )
x
1 e , n 3
1 x , n 4
#include <stdio.h>
#include <math.h>
int main () {
int n, ok = 1;
double x, y;
printf(n = );
scanf(%d, &n);
printf(x = );
scanf(%lf, &x);
switch (n) {
case 1:
y = 1 + x * x;
break;
case 2:
y = 1 + sin(x);
break;
case 3:
y = 1 + exp(x);
break;
case 4:
y = 1 + sqrt(x);
break;
default:
ok = 0;
}
if (ok)
printf(y = %lf\n, y);
else
printf(Valoare incorecta pentru n\n);
return 0;
}
4) n cazul instruciunii for, expresia condiional poate lipsi, ceea ce nu se poate ntmpla
pentru celelalte dou instruciuni repetitive. Lipsa unei expresii condiionale n cadrul
instruciunii for este interpretat drept constanta 1. De exemplu, instruciunea:
for (;;)
instructiune
este interpretat ca o bucl infinit:
for (; 1 ;)
instructiune
Exemplul 7.4. Se consider un ir de n numere, x1, x2, , xn. S se ordoneze cresctor irul
de numere.
Descrierea algoritmului.
Se va prezenta o metod simpl de sortare (acesta este termenul consacrat pentru operaia de
ordonare a elementelor unui grup de elemente), numit sortarea prin numrare. Ideea acestei
metode se bazeaz pe urmtoarea observaie: elementul aflat pe poziia k n ir dup
terminarea operaiei de sortare este mai mare dect k-1 elemente din ir (aflate naintea lui).
Cu alte cuvinte, dac un element dintr-un ir este mai mare dect k elemente, atunci el se va
afla la sfrit pe poziia k+1.
n concluzie, pentru fiecare element din ir, se va determina numrul de elemente din
ir, fa de care el este mai mare ca valoare. Vom nota cu contor un tablou de numere ntregi
ce memoreaz aceste valori. n acest mod, poziia n ir a elementului xk dup sortare este
contork.
Determinarea valorilor contork se determin prin compararea perechilor de elemente
xI cu xj. Pentru a se elimina comparrile redondante, se vor compara doar perechile (xi, xj)
distincte. Descrierea algoritmului este urmtoarea (pentru simplitate, s-a utilizat notaia cu
indici n dou forme):
start
citeste n
pentru i 1 la n executa
citeste xi
contori 0
pentru i 1 la n executa
scrie x[contor[i]]
sfarsit
Analiza algoritmului.
Timpul de execuie al algoritmului este:
T = t1 + t2 + t3
Unde cei trei timpi corespund celor trei instruciuni for. Primul i ultimul se determin
simplu:
t1 = 1 + 3*n,
t2 = 1 + 2*n,
Pentru determinarea timpului t3, se observ faptul c timpul de execuie al instruciunii
interne if este tot timpul 2, deoarece se execut o singur incrementare a contorului,
indiferent de valorile lui x[i] i x[j]. Rezult:
n 1
n 1
i 1
i 1
Instruciunea goto este una dintre cele mai vechi instruciuni aprute n cadrul limbajelor
de programare de nivel nalt. Dezavantajul ei este acela c distruge caracterul structurat al
programelor, dar a fost pstrat n cadrul limbajului C din considerente istorice.
Orice program ce utilizeaz instruciunea goto se poate transforma ntr-un program
echivalent ce nu conine aceast instruciune. Modul de definire al limbajului C nu
ncurajeaz utilizarea acestei instruciuni, considerndu-se faptul c programatorul care
utilizeaz instruciunea goto este un slab programator.
instruciunea
goto
goto
etichet
unde etichet este o constant ntrege sau un identificator, reprezentnd eticheta unei
instruciuni.
Instruciunile unui program pot fi etichetate i nu trebuie confundate cu cele din
interiorul unei instruciuni switch. O etichet poat fi un numr ntreg sau un identificator i
preced instruciunea pe care o eticheteaz, fiind separat de aceasta prin caracterul :.
Efectul execuiei unei asemenea instruciuni const n continuarea execuiei
programului cu instruciunea care are eticheta specificat dup cuvntul cheie goto.
Un exemplu uzual de folosire al instruciunii goto este n cadrul instruciunilor
repetitive. Dac, de exemplu, exist dou instruciuni for imbricate, utilizarea instruciunii
break n cadrul instruciunii for interioare nu permite ntreruperea execuiei instruciunii
for exterioare. n acest caz se poate justifica utilizarea unei instruciuni goto.
Exemplul 7.6. Funcia urmtoare determin abaterea ptrat a valorilor elementelor dintr-o
matrice, presupunnd faptul c acestea sunt pozitive. n caz contrar, se determin poziia
primului element negativ. Variabile auxiliar k are rolul de a determina dac matricea conine
sau nu elemente negative
#define max 4
void AbatereMedie(int n, int m, int a[max][max]) {
int i, j, k, s = 0, s1 = 0;
for (i=0; i<n; i++)
for (j=0; j<m; j++) {
if (a[i][j] < 0) {
k = 1;
goto 100;
}
s += a[i][j];
}
med = s/(n*m);
for (i=0; i<n; i++)
for (j=0; j<m; j++)
s1 += (a[i][j]-med) * (a[i][j]-med);
100: if(k)
printf(Element negativ pe pozitia %d %d, i, j);
else
printf(s = %f, s1);
}
Observaii.
1) Nu este permis saltul n afara corpului funciei curente, ci doar n interiorul acesteia.
2) Saltul din interiorul unei instruciuni repetitive nspre exterior este n mod uzual
utilizat, variabilele de control ale instruciunii respective pstrndu-i valorile din
momentul saltului.
3) Saltul dinspre exteriorul unei instruciuni repetitive nspre interiorul acesteia nu este
indicat, deoarece variabilele de control ale acesteia pot avea valor alterate, ceea ce
poate conduce la erori n execuia programului.
7.5 Probleme
7.1.
7.2.
S se scrie programul pentru determinarea valorii y = xn, pentru un numr real pozitiv x
i un numr ntreg pozitiv n efectund un numr minim de operaii de nmulire i
ridicare la ptrat.
7.3.
Se consider un circuit electric format numai din rezistoare, avnd structura prezentat
n figura urmtoare: r11
r1m
r21
r2m
rn1
rnm
Cunoscndu-se valorile rezistenelor R1, R2, ..., Rn, dintr-un circuit electric, s se
determine rezistena echivalent a circuitului urmtor:
R1
R2
Rn-k
R3
Rn-k+1
Rn
Prima latur a circuitului are o rezisten, a doua are dou rezistene, la fiecare latur
numrul de rezistene crete cu una fa de latura precedent. Pentru ultima latur aceast
regul nu mai este valabil, ea coninnd restul rezistenelor neluate n considerare.
7.5.
Fiind dat un numr real x0 i un numr real pozitiv subunitar eps, s se scrie un
program care s calculeze valoarea funciei f(x)=sin(x) n punctul x0, cu o precizie eps,
folosind dezvoltarea n serie de puteri a funcie:
sin(x) = x - x3/(3!) + x5/(5!) - x7/(7!) + ...
7.6.
7.7.
7.8.