Sunteți pe pagina 1din 20

?? ?

?
Subprograme (continuare sem. 1)

 Pointeri la funcții (subprograme)

 Recursivitate

 Studiu individual
 Funcții cu număr variabil de parametri

 Lucrul cu parametri din linia de comandă


Pointeri la funcții (subprograme)

 Numele unei funcții este un pointer constant

 Semnificație
 Adresa din memorie unde se află codul executabil al funcției

 Tip de dată
 pointer către o funcție care primește o anumită listă de parametri și
întoarce a un anumit rezultat

 Utilizare
 Apelul dinamic al subprogramelor, transmiterea funcțiilor ca parametri
către alte funcții
Pointeri la funcții (subprograme)

 Exemple

void sortare(float v[], int n);

sortare  pointer către o funcție care primește un vector cu elemente


float și un int și întoarce rezultat de tip void

float minim(float v[], int n, int poz[], int* nr);

minim  pointer către o funcție care primește un vector cu elemente


float, un int, un vector cu elemente int și un pointer către int și
întoarce rezultat de tip float
Pointeri la funcții (subprograme)

 Variabile / parametri de tip pointer la funcție

void sortare(float v[], int n);


float minim(float v[], int n, int poz[], int* nr);

void main()
{ int dim; float a[100]; int unde[100], cite;
void (*p)(float [], int );
float (*q)(float [], int , int [], int* );
//…
p = sortare;
q = minim;
sortare(a,dim); //  (*p)(a, dim); p(a, dim);
minim(a,dim,unde,&cite); //  (*q)(a,dim,unde,&cite);
//…
}
Pointeri la funcții (subprograme)

 Exemplu
 Metoda bisecției pentru rezolvarea unei ecuații

f(x)

n, eps
x1 x x2
Pointeri la funcții (subprograme)

#include <stdio.h> void main()


{ float a, b, sol, prec;
float ecuatie(float x) int nr, cod;
{ return x*x - 7*x + 12; printf("\na="); scanf("%f",&a);
} printf("\nb="); scanf("%f",&b);
printf("\nprecizia=");
int bisectie( float x1, float x2, scanf("%f",&prec);
float eps, int n,
float (*f)(float), printf("\nnr="); scanf("%d",&nr);
float *x)
{ int cod = 0; cod =
while ((n > 0) && (cod == 0)) bisectie(a,b,prec,nr,ecuatie,&sol);
{ *x = (x1 + x2) / 2;
if((*f)(*x) == 0) switch(cod)
cod = 1; { case 0: printf("\nFara solutie");
else break;
if((x2-x1) < eps) case 1: printf("\nSolutia exacta este
cod = 2; %7.3f", sol);
else break;
if((*f)(x1)*(*f)(*x)<0) case 2: printf("\nSolutia
x2 = *x; aproximativa
else este %7.3f", sol);
x1 = *x; }
n--; }
}
return cod;
}
Recursivitate

 Algoritmi iterativi
 Algoritmi recursivi
 Recursivitate simplă (algoritmi uni-recursivi)
 Recursivitate multiplă (algoritmi multi-recursivi)

 Formulă de start (o formulă / mai multe)


 Formulă recursivă

 Exemple
 Numărarea valorilor care îndeplinesc o condiție
 Suma elementelor unui masiv
 Algoritmul lui Euclid
 Calcularea elementelor șirului Fibonacci (și multe altele)
Recursivitate, funcții recursive

 Algoritm iterativ / recursiv  funcție iterativă / recursivă

 Funcție recursivă: autoapel (cel puțin unul)


 Recursivitate directă
▪ Simplă
▪ Multiplă
 Recursivitate mutual
▪ Declarare anticipată a funcțiilor

 Implicații
 Construire funcții
 Cerințe de memorie
Recursivitate, funcții recursive

 Construirea funcțiilor recursive


 Asigurarea caracterului finit al algoritmului: încheiere după un număr finit de
repetări
▪ Fiecare apel recursiv trebuie aplicat unei probleme mai simple decît în iterația
curentă
▪ Oprire cînd problema curentă este trivială
 Condiție de oprire a generării de noi apeluri recursive
▪ Aplică formula de start dacă e îndeplinită condiția
▪ Aplică formula recursivă altfel

long fact ( unsigned n )


{ long f;
if ( !n )
f = 1; 0!=1
else
f = n*fact ( n-1); n!=n*(n-1)!
return f;
}
Recursivitate, funcții recursive

apelator
fact(3) t1
 Memorie ocupată
fact(3)
3*fact(2) t2

fact(2)
Stack 2 * fact(1) t3
Return address
t1 3 t8 fact(1)
f 1 * fact(0) t4
Return address
t2 2 t7
f fact(0)
Return address 1
t3 1 t6
f 1*1=1 t5
Return address
t4 0 t5
f 2*1=2 t6

3*2=6 t7

6 t8
Recursivitate, funcții recursive

fib(n) = fib(n-1) + fib(n-2), fib(1) = fib(0) = 1

fib( 4 )
fib( 1 )
fib( 3 )
fib( 2 ) 1
fib( 0 )
fib( 1 )
1
1 2
fib( 0 )
6
1
2
fib( 1 )
1
3
fib( 2 )
Recursivitate, funcții recursive

 Alegere subprograme iterative / recursive


 Avantaje și dezavantaje

▪ Consum de memorie

▪ Timp de procesare

▪ Ușurința în proiectare / implementare


▪ Lungime / simplitate cod sursă
Recursivitate, funcții recursive

 Calculul combinărilor (combinări de n luate cîte k)


𝑛! 𝑘 𝑘−1
𝐶𝑛𝑘 = => 𝐶𝑛𝑘 = 𝐶𝑛−1 + 𝐶𝑛−1 , 𝐶𝑛0 = 1 𝐶𝑛𝑛 = 1
𝑘! 𝑛−𝑘 !

long comb(unsigned n, unsigned k)


{ long c;
if (k>n)
c = 0;
else
if ((k==0)||(k==n))
c = 1;
else
c = comb(n-1,k) + comb(n-1,k-1);
return c;
}
Recursivitate, funcții recursive

 Suma elementelor unui vector


 S(n) = x[n-1] + S(n-1), S(0) = 0

double suma(double v[], int n)


{ double s;
if( n == 0)
s = 0;
else
s = v[n-1] + suma(v, n-1);
return s;
}

 Produsul elementelor unui vector


Recursivitate, funcții recursive

 Căutare binară

int cauta(float v[], int p, int u, float k)


{ int m;
if (p > u)
m = -1;
else { m = (p + u) / 2;
if(k < v[m])
m = cauta(v, p, m-1, k);
else
if(k > v[m])
m = cauta(v, m+1, u, k);
}
return m;
}
Recursivitate, funcții recursive

 Transformarea unei funcții iterative în funcție recursivă


1. Elimină instrucțiunea iterativă (for, while, do)
2. Condiția iterative devine (eventual modificată) condiție de oprire
a generării de noi apeluri recursive
3. Repetarea e asigurată de apelul recursiv

 Exemplu: metoda bisecției


Recursivitate, funcții recursive

int bisectie( float x1, float x2, float eps, int n, float
 Metoda bisecției
(*f)(float), float *x)
{ int
int cod;
bisectie( float x1, float x2, float eps, int n,
if ( n == 0 ) float (*f)(float), float *x)
{ cod
int =cod0; = 0;
else
while
{ *x = (x1((n > 0)
+ x2) && (cod == 0))
/ 2;
{ *x = (x1 ==
if((*f)(*x) + x2)
0) / 2;
if((*f)(*x)
cod = 1; == 0)
else cod = 1;
else
if((x2-x1) < eps)
if((x2-x1) < eps)
cod cod
= 2;= 2;
elseelse
{ if( if((*f)(x1)*(*f)(*x)<0)
(*f)(x1) * (*f)(*x) < 0 )
x2 =x2*x;
= *x;
elseelse
x1 =x1*x;
= *x;
n--;
n--;
} cod = bisectie( x1, x2, eps, n, f, x );
return
}
cod; if((*f)(x1)*(*f)(*x)<0)
} cod = bisectie( x1, *x, eps, n-1, f, x );
return cod;
} else cod = bisectie( *x, x2, eps, n-1, f, x );
Recursivitate, funcții recursive

 Temă. Scrieți funcții recursive care realizează:


Numărarea elementelor negative dintr-un vector
Produsul scalar dintre doi vectori
Implementarea algoritmului lui Euclid
Metoda tangentei pentru rezolvarea unei ecuații
Sortarea unui vector (metoda bulelor)

Capitolul 1 din culegere, 1.6-1.8 (recapitulare 1.1-1.5)

S-ar putea să vă placă și