Documente Academic
Documente Profesional
Documente Cultură
Cursul nr.8
POINTERI LA FUNC II
Dup compilarea i linkeditarea unui program fiec rei func ii componente i se
asociaz o adresa de memorie care este de fapt adresa de nceput a func iei.
Un pointer c tre func ie este un pointer care poate con ine aceast adres .
S presupunem c o fun ie f are prototipul :
tip f ( lista_param_formali ) ;
Forma general a unui pointer pf la func ia f este de forma :
tip ( *pf ) ( lista param formali ) ;
Se observ c func ia i pointerul asociat func iei trebuie s aibe acela i tip, iar
lista parametrilor formali trebuie s fie identic .
De asemenea, pointerul precedat de stelu trebuie sa fie inclus ntre paranteze
rotunde datorit regulilor de preceden ale limbajului, deoarece in C numele
func iei este echivalent cu adresa ei de nceput.
Un pointer c tre o func ie poate primi adresa de nceput a func iei respective
printr-o atribuire de forma :
pf = f ;
Exemplu :
Un pointer p la func ia f
void f ( float, int ) ;
trebuie declarat in felul urmator :
void ( *pf ) ( float, int ) ;
Dup o atribuire de forma
pf = f ;
apelul func iei prin intermediul pointerului pf se face prin
( *pf ) ( lista_parametri_actuali) ;
1
{
return x/y ;
}
Exemplu :
Transmiterea ca parametri a pointerilor la func ii :
suma(a,b) dac x > 0
Fie func ia f(x)=
dif(a,b)
dac x
Se poate folosi o singur func ie f( )pentru definirea lui f(x), care va avea ca
argumente pe x i un pointer la func ie notat cu p. Acest pointer poate primi att
adresa func iei suma( ) ct i a func iei dif( ).
# include < stadio.h >
# include < conio.h >
int sum ( int a, int b);
int dif (int a ,int b);
void f (float x, int a, int b , int( *p )(int a, int b));
void main( )
{
float x;
int a,b;
clrscr ( );
printf(\n x=); scanf( % f ,&x );
printf(\n a =); scanf(% d ,&a );
printf(\n b =); scanf(% d ,&b);
if(x>0) f(x,a,b,sum) ;
else
f(x,a,b,dif);
getch ( );
}
int sum(int a,int b)
{
return(a+b);
}
int dif(int a,int b)
{
return (a-b);
}
void f(float x,int a,int b,int(*p)(int a,int b))
3
{
printf(\n f ( % f ) = % i ,x, ( *p )(a, b));
}
FUNC II RECURSIVE
Defini ie. O func ie este definit recursiv dac pornind de la anumite valori ale
ei se pot calcula alte valori prin autoapelarea func iei.
Valorile unei func ii recursive se calculeaz din aproape n aproape, pe baza
valorilor cunoscute ale func iei pentru anumite argumente ini iale. Pentru a
calcula noile valori ale unei func ii recursive, trebuie memorate deja valorile
calculate, care sunt strict necesare. Acest fapt face ca implementarea n program
a calculului unor func ii recursive s necesite un consum mare de memorie,
rezultnd timpi mari de execu ie.
Recursivitatea poate fi transformat n itera ie.
In general, forma iterativ a unei func ii este mai eficient dect cea recursiv n
ceea ce prive te timpul de execu ie i memoria consumat .
n alegerea c ii (interativ sau recursiv ) de rezolvare a unei probleme, trebuie
considera i o serie de factori: u urin a program rii, test rii i ntre inerii
programului, eficien a, complexitatea etc.
Dac o problem are o complexitate redus este preferat varianta interactiv .
Forma recursiv este preferat acolo unde transformarea recursivit ii n itera ie
cere un efort de programare deosebit, algoritmul pierzndu- i claritatea, testarea
i ntr tinerea devenind astfel foarte dificile. Calculul valorilor func iilor
respective se poate face direct sau indirect.
Func ia f( ) se nume te direct recursiv dac n corpul ei apar apeluri la ea ns i
(autoapeluri). Func iile f( ) i g( ) se numesc indirect recursive daca f ( ) con ine
apeluri la g( ), iar g( ) con ine apeluri la f( ).
Exemple :
1. Func ia n! pe care o notam cu fact, se define te recursiv astfel :
1 dac n=0 sau n=1
fact:N N
fact(n) =
n . fact(n-1) dac n>1
fib(n)=
fib(n-1)+fib(n-2) dac n>=2
dac
x>12
f( x ) =
f(f(x+2)) dac
0 x<12
ac(m,n) =
n+1
dac m=0
ac(m-1,1)
dac n=0
ac(m-1,ac(m,n-1)) n rest
if x > 12 then x - 1
else f (f ( x+2 ))
endif
4. Func ia lui Ackermann corespunde formei generale a tipului mpachetat :
f(x)=
if b=0 then a
else cmmdc (b, mod ( a, b ))
endif
if a<b then a
else mod (a-b, b)
endif
unde mod : NxN N , (a,b) mod (a, b) este restul mp r irii lui a la b.
Exemple scrise n limbajul C :
1. Func ia factorial : fact : N N
1 dac n=0
fact(n)=
n x fact(n-1) dac n >= 1
# include < stdio.h >
# include < conio.h >
int fact ( int ) ;
void main( )
{
int n ;
clrscr ( ) ;
printf ( \ n n = ) ; scanf ( % d , & n ) ;
printf ( \ n % d ! = % d , n, fact ( n )) ;
getch ( ) ;
}
int fact(int a)
{
if ( a > = 1) return(a * fact ( a - 1) ;
else return 1;
}
sau folosind operatorul conditional
int fact ( int a )
{
return ( a >= 1 ) ? a* fact ( a 1 ) : 1 ;
7
}
Efectul unui apel de forma fact(5) const n declan area unui lan de apeluri ale
func iei factorial pentru 4,3,2,1,0
fact(5)
5 fact(4)
2 fact(1)
1 fact(0)
1
Apelul lui fact ( 5 ) declan eaz un lan de apeluri ale lui f pentru 4, 3, 2, 1, dup
care urmeaz revenirea din apeluri i evaluarea lui fact pentru 1,2,3,4,5.
Starea stivei in timpul execu iei succesive a autoapel rii :
4
Stiva vida
5
apel fact(5)
2
3
1
2
3
5
5
5
5
apel fact(4) apel fact(3) apel fact(2) fact( 1)
Pentru fiecare din aceste apeluri, n stiv se vor depune parametrii actuali:
5,4,3,2,1. St rile stivei dup ie irea din autoapel sunt urmatoarele:
1
2
3
4
5
fact(1)=1
2
3
3
4
4
4
5
5
5
5
Stiva vida
fact(2)=1.2 fact(3)=1.2.3 fact(4)=1.2.3.4 fact(5)=1.2.3.4.5
8
fib(4)
fib(3)
fib(2)
fib(1)
fib(0)
fib(2)
fib(1)
fib(1)
fib(0)
1
1
int fib(int n)
{
if ( n == 0 || n == 1) return 1 ;
else return fib ( n-1 ) + fib( n- 2 ) ;
}
ac : N x N
ac(2,1)
ac(1,ac(2,0))
ac(1,3)
ac(0,ac(1,2))
ac(0,4)
5
ac(1,1)
ac(0,ac(1,1))
ac(0,3)
4
ac(0,ac(1,0))
ac(0,ac(1,0))
ac(0,2)
10
ac(0,2)
ac(0,1)
ac(0,1)
2
11