Extras din curs
3. Pointeri la functii.
Numele unei functii reprezinta adresa de memorie la care începe functia. Numele functiei este, de fapt, un pointer la functie.
Se poate stabili o corespondenta între variabile si functii prin intermediul pointerilor la functii. Ca si variabilele, acesti pointeri:
• pot primi ca valori functii;
• pot fi transmisi ca parametrii altor functii
• pot fi intorsi ca rezultate de catre functii
La declararea unui pointer catre o functie trebuiesc precizate toate informatiile despre functie, adica:
• tipul functiei
• numarul de parametri
• tipul parametrilor
care ne vor permite sa apelam indirect functia prin intermediul pointerului.
Declararea unui pointer la o functie se face prin:
tip (*pf)(lista_parametri_formali);
Daca nu s-ar folosi paranteze, ar fi vorba de o functie care întoarce un pointer.
Apelul unei functii prin intermediul unui pointer are forma:
(*pf)(lista_parametri_actuali);
Este permis si apelul fara indirectare:
pf(lista_parametri_actuali);
Este posibil sa creem un tablou de pointeri la functii; apelarea functiilor, în acest caz, se face prin referirea la componentele tabloului.
De exemplu, initializarea unui tablou cu pointeri cu functiile matematice uzuale se face prin:
double (*tabfun[])(double) = {sin, cos, tan, exp, log};
Pentru a calcula radacina de ordinul 5 din e este suficienta atribuirea:
y = (*tabfun[3])(0.2);
Numele unei functii fiind un pointer catre functie, poate fi folosit ca parametru în apeluri de functii.
În acest mod putem transmite în lista de parametri a unei functii – numele altei functii.
De exemplu, o functie care calculeaza integrala definita:
va avea prototipul:
double integrala(double, double, double(*)(double));
Definiti o functie pentru calculul unei integrale definite prin metoda trapezelor,cu un numar fixat n de puncte de diviziune:
Folositi apoi aceasta functie pentru calculul unei integrale definite cu o precizie data e. Aceasta precizie este atinsa în momentul în care diferenta între doua integrale, calculate cu n, respectiv 2n puncte de diviziune este inferioara lui e
#include <math.h>
double sinxp();
double trapez(double,double,int,double(*)());
double a=0.0, b=1.0, eps=1E-6;
int N=10;
void main(void)
{ int n=N;
double In,I2n,vabs;
In=trapez(a,b,n,sinxp);
do { n*=2;
I2n=trapez(a,b,n,sinxp);
if((vabs=In-I2n)<0) vabs=-vabs;
In=I2n;
} while(vabs > eps);
printf(“%6.2lfn”, I2n);
}
double trapez(double a,double b,int n,double(*f)())
{ double h,s;
int i;
h=(b-a)/n;
for(s=0.0,i=1;i<n;i++)
s+=(*f)(a+i*h);
s+=((*f)(a)+(*f)(b))/2.0;
s*=h;
return s;
}
4. Declaratii complexe.
O declaratie complexa este o combinatie de pointeri, tablouri si functii. In acest scop se folosesc atributele:
() – functie
[] – tablou
* - pointer
care pot genera urmatoarele combinatii:
* () – functie ce returneaza un pointer
(*)() – pointer la o functie
* [] - tablou de pointeri
(*) [] – pointer la tablou
[ ] [] – tablou bidimensional
Exista si combinatii incorecte, provenite din faptul ca în C nu este permisa declararea:
- unui tablou de functii
- unei functii ce returneaza un tablou.
Acestea sunt:
( ) [ ] – functie ce returneaza un tablou
[ ] ( ) – tablou de functii
( ) ( ) – functie ce returneaza o functie
Pentru a interpreta o declaratie complexa vom inlocui atributele prin urmatoarele sabloane text:
Atribut Sablon text
() functia returneaza
[n] tablou de n
* pointer la
Descifrarea unei declaratii complexe se face aplicând regula dreapta – stânga, care presupune urmatorii pasi:
• se incepe cu identificatorul
• se cauta în dreapta identificatorului un atribut
Preview document
Conținut arhivă zip
- Functii, tablouri si pointeri in C si C++.doc