Punter de funció
Un punter de funció, també anomenat punter de subrutina o punter de procediment, és un punter que fa referència a codi executable, en lloc de dades. Desreferenciar el punter de funció produeix la funció referenciada, que es pot invocar i passar arguments igual que en una crida de funció normal. Aquesta invocació també es coneix com a trucada "indirecta", perquè la funció s'està invocant indirectament a través d'una variable en lloc de directament a través d'un identificador o adreça fixa.[1]
Els punters de funció permeten executar codi diferent en temps d'execució. També es poden passar a una funció per habilitar les devolució de trucades.
Els punters de funció són compatibles amb llenguatges de programació de tercera generació (com ara PL/I, COBOL, Fortran,[2] dBASE dBL i C) i llenguatges de programació orientats a objectes (com C++, C# i D).[3]
Apuntadors de funció simples
[modifica]La implementació més senzilla d'un punter de funció (o subrutina) és com una variable que conté l'adreça de la funció dins de la memòria executable. Els llenguatges més antics de tercera generació com ara PL/I i COBOL, així com els llenguatges més moderns com Pascal i C, generalment implementen punters de funció d'aquesta manera.[4]
Exemple en C
[modifica]El següent programa C il·lustra l'ús de dos punters de funció:
- func1 pren un paràmetre de doble precisió (doble) i en retorna un altre doble, i s'assigna a una funció que converteix centímetres a polzades.
- func2 pren un punter a una matriu de caràcters constants així com un nombre enter i retorna un punter a un caràcter, i s'assigna a una funció de gestió de cadenes C que retorna un punter a la primera ocurrència d'un caràcter donat en una matriu de caràcters.
#include <stdio.h> /* for printf */
#include <string.h> /* for strchr */
double cm_to_inches(double cm) {
return cm / 2.54;
}
// "strchr" is part of the C string handling (i.e., no need for declaration)
// See https://en.wikipedia.org/wiki/C_string_handling#Functions
int main(void) {
double (*func1)(double) = cm_to_inches;
char * (*func2)(const char *, int) = strchr;
printf("%f %s", func1(15.0), func2("Wikipedia", 'p'));
/* prints "5.905512 pedia" */
return 0;
}
El següent programa utilitza un punter de funció per invocar una de les dues funcions (sin
o cos
) indirectament des d'una altra funció (compute_sum
, calculant una aproximació de la integració de Riemann de la funció). El programa funciona tenint la funció de crida main
a la funció compute_sum
dues vegades, passant-li un punter a la funció de biblioteca sin
la primera vegada i un punter a la funció cos
la segona vegada. La funció compute_sum
al seu torn invoca una de les dues funcions indirectament desreferenciant el seu argument punter de funció funcp
diverses vegades, sumant els valors que retorna la funció invocada i retornant la suma resultant. Les dues sumes s'escriuen a la sortida estàndard mitjançant main
.[5]
#include <math.h>
#include <stdio.h>
// Function taking a function pointer as an argument
double compute_sum(double (*funcp)(double), double lo, double hi) {
double sum = 0.0;
// Add values returned by the pointed-to function '*funcp'
int i;
for (i = 0; i <= 100; i++) {
// Use the function pointer 'funcp' to invoke the function
double x = i / 100.0 * (hi - lo) + lo;
double y = funcp(x);
sum += y;
}
return sum / 101.0 * (hi - lo);
}
double square(double x) {
return x * x;
}
int main(void) {
double sum;
// Use standard library function 'sin()' as the pointed-to function
sum = compute_sum(sin, 0.0, 1.0);
printf("sum(sin): %g\n", sum);
// Use standard library function 'cos()' as the pointed-to function
sum = compute_sum(cos, 0.0, 1.0);
printf("sum(cos): %g\n", sum);
// Use user-defined function 'square()' as the pointed-to function
sum = compute_sum(square, 0.0, 1.0);
printf("sum(square): %g\n", sum);
return 0;
}
Referències
[modifica]- ↑ «Function Pointer in C» (en anglès americà), 08-05-2015. [Consulta: 1r desembre 2023].
- ↑ Andrew J. Miller. «Fortran Examples» (en anglès). [Consulta: 14 setembre 2013].
- ↑ «The Function Pointer Tutorials» (en anglès). logo. Arxivat de l'original el 2011-05-16. [Consulta: 13 abril 2011].
- ↑ «The Function Pointer Tutorials» (en anglès). logo. Arxivat de l'original el 2011-05-16. [Consulta: 13 abril 2011].
- ↑ «20.1 — Function Pointers – Learn C++» (en anglès). [Consulta: 1r desembre 2023].