Punter de funció

De la Viquipèdia, l'enciclopèdia lliure

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]

  1. «Function Pointer in C» (en anglès americà), 08-05-2015. [Consulta: 1r desembre 2023].
  2. Andrew J. Miller. «Fortran Examples» (en anglès). [Consulta: 14 setembre 2013].
  3. «The Function Pointer Tutorials» (en anglès). logo. Arxivat de l'original el 2011-05-16. [Consulta: 13 abril 2011].
  4. «The Function Pointer Tutorials» (en anglès). logo. Arxivat de l'original el 2011-05-16. [Consulta: 13 abril 2011].
  5. «20.1 — Function Pointers – Learn C++» (en anglès). [Consulta: 1r desembre 2023].