Puntatori a funzione

In generale, un puntatore è una variabile che contiene un indirizzo. Allora, ha senso che possano esistere puntatori a tutti gli oggetti dotati di indirizzo. Finora, si è visto che le variabili hanno un indirizzo, mentre ad esempio le espressioni non lo hanno. Un altro oggetto caratterizzato da un indirizzo sono le funzioni: una funzione è rappresentata da una sequenza di istruzioni in memoria, dunque il suo indirizzo è l’indirizzo della prima istruzione (quella a cui si salta quando la funzione viene chiamata). Perciò, il linguaggio C consente la definizione di puntatori a funzione.

Definizione

Esistono tanti tipi di puntatori a funzione — uno per ogni possibile prototipo di funzione (cioè per ogni combinazione di tipo restituito e tipi dei parametri). La sintassi per definire un puntatore a funzione è

tipo_restituito (*nome)(tipi_parametri)

dove:

Questa sintassi è ispirata alla sintassi dei prototipi di funzione e al modo in cui il puntatore viene suato una volta definito: (*nome) è l’oggetto puntato da *nome,* ed è appunto una funzione con un prototipo corrispondente a indicato nella definizione di nome.

Ad esempio, data una funzione f con prototipo

int f(short, double);

un puntatore chiamato ptr_to_f che è del tipo giusto per puntare a f viene definito nel modo seguente:

int (*ptr_to_f)(short, double);

Uso

In C, così come il nome di un array può essere interpretato come un puntatore al suo primo elemento, anche il nome di una funzione corrisponde a un puntatore alla funzione stessa (ovvero alla sua prima istruzione). Di conseguenza, dati il puntatore ptr_to_f e la funzione f mostrati prima, per assegnare a ptr_to_f l’indirizzo di f è sufficiente scrivere:

ptr_to_f = f;

Una volta assegnato un indirizzo, quando si vuole invocare la funzione puntata, si usa prima l’operatore di indirizzamento indiretto per passare dal puntatore alla funzione puntata, e poi si usa la normale sintassi di chiamata con le parentesi. Ad esempio, se ptr_to_f contiene l’indirizzo di f, l’invocazione

int x = (*ptr_to_f)(5, 8.64);

equivale a