O functie este stocata in memorie la o adresa, exact ca o
variabila iar adresa functiei respective se obtine utilizand numele
functiei, fara paranteze si parametri formali, exact cum utilizam numele unui tablou pentru a asigna
adresa sa unui pointer la tipul elementelor tabloului.
Faptul ca o functie este stocata (incarcata) de compilator la o anumita
adresa permite utilizarea unui pointer la functia respectiva.
Sintaxa declararii
unui pointer la functie:
tip_return_functie (* ptrf)(
lista_de_parametri_formali_ai_functiei );
Prima
pereche de paranteze este necesara intrucat, in absenta acestor paranteze,
declaratia respectiva ar fi prototipul unei functii numite ptrf cu lista specificata de parametri si care intoarce un pointer
la tip_return_functie.
Ex:
#include <stdio.h>
……
int i;
int (* ptrf)(const
char * s1, const char * s2);
ptrf = strcmp; // ptrf indica acum spre strcmp
……
i = (* ptrf)(s1, s2); // apelul functiei prin intermediul
pointerului
// i = ptrf(s1, s2);
// Linia comentata anterior este varianta echivalenta de
apel
In continuare un mic reminder al algoritmului GCD si
codul care implementeaza o functie de calcul a GCD, apelata printr-un pointer.
Pentru a, b numere intregi pozitive nenule in relatia de
ordine a >= b executam urmatoarea succesiune de operatii, folosind teorema
impartirii cu rest (oricare a, b in conditiile de mai sus, exista si sunt unici
intregii b1, r cu proprietatea ca a = b x b1 + r) si schimband deimpartitul cu
impartitorul si impartitorul cu restul la fiecare iteratie
a = b x b1 + r
b = r x b2 + r1
r = r1 x b3 + r2
........
r_n = r_(n+1) x b_(n+3) // r_(n+2) = 0 adica oprim iteratiile
cand restul devine nul
Pentru simplitate, presupunem ca obtinem rest nul la a
treia iteratie, adica r2 = 0.
Atunci,
r = r1 x b3; b = r1 x b3 x b2 + r1 = r1 x (b3 x b2 + 1)
a = r1 x (b3 x b2 + 1) x b1 + r1 x b3 = r1 x (b3 x b2
x b1 + b1 + b3)
Deci r1, ultimul rest nenul, este GCD.
Codul si printscreen-ul executiei:
#include <stdio.h>
unsigned GCD(unsigned, unsigned);
int main()
{
unsigned
a, b, c, temp;
unsigned
(* ptrf)(unsigned, unsigned);
ptrf =
GCD;
puts("Dati
doi intregi pozitivi nenuli a si b separati de virgula. Vom determina
GCD.");
scanf("%u,
%u", &a, &b);
_flushall();
if(a
<= b) {temp = a; a = b; b = temp;}
c = (*
ptrf)(a, b);
printf("\nGCD
al %u si %u este %u.\n", a, b, c);
return
0;
}
unsigned GCD(unsigned a, unsigned b)
{
unsigned
temp;
while(b)
{
temp
= b;
b
= a%b;
a
= temp;
}
return
temp;
}
No comments:
Post a Comment