I puntatori a funzione sono variabili che possono essere inizializzate con l'indirizzo di una funzione; questo genere di puntatori sono molto utili, perché consentono di richiamare all'interno dello stesso blocco di codice funzioni diverse (anche se tutte con la stessa signature), modificando a tempo di esecuzione e sulla base di altri dati del programma, il comportamento del codice. Questo processo, in cui gli indirizzi delle funzioni da chiamare non sono risolti al momento della compilazione, ma in fase di esecuzione si chiama late binding.
Per dichiarare un puntatore a funzione basta iniziare scrivendo il prototipo della funzione, poi sostituire il nome_funzione con (*nome_puntatore) ed infine eliminare i nomi dei parametri; a questo punto nome_funzione è il puntatore da utilizzare. Ad esempio supponiamo di voler dichiarare un puntatore alla funzione:
void func(int value);
basta scrivere:
void (*pFunc)(int);
pFunc è il puntatore da utilizzare, adesso non resta che inizializzarlo:
pFunc = func;
E' bene notare che la riga precedente è equivalente a scrivere:
pFunc = &func;
A volte la presenza di più di un asterisco può rendere difficoltoso l'interpretazione del prototipo della funzione, ma la regola è sempre la stessa: isolare il nome della funzione con il suo asterisco ed interpretare il resto come una funzione "normale". Ad esempio:
void* (*pFunc)(int *);
L'invocazione di una funzione tramite un puntatore non è dissimile dall'invocazione della funzione tramite il suo nome:
pFunc(10);
La riga precedente è equivalente a scrivere:
(*pFunc)(10);
Vediamo desso come sia possibile passare una funzione come parametro ad un'altra funzione sfruttando i puntatori.
void func (int v)
{
printf("valore: %d\n", v);
}
void call_func(int v, void (*f1)(int))
{
printf("valore: %d\n", v);
f1(v + 1);
}
int main_funptr(int argc, char *argv[])
{
call_func(3, func);
return 0;
}
Come si nota dal codice precente, la funzione call_func riceve come parametri un intero ed una funzione con la signature void f1(int).
9d7cece6-917f-4ebc-8e68-b1af9897a849|0|.0