3.10. Direcciones de función

Una vez que una función es compilada y cargada en la computadora para ser ejecutada, ocupa un trozo de memoria. Esta memoria, y por tanto esa función, tiene una dirección.

C nunca ha sido un lenguaje [FIXME] donde otros temen pisar. Puede usar direcciones de función con punteros igual que puede usar direcciones variables. La declaración y uso de punteros a función parece un poco opaca al principio, pero sigue el formato del resto del lenguaje.

3.10.1. Definición de un puntero a función

Para definir un puntero a una función que no tiene argumentos y no retorna nada, se dice:

void (*funcPtr)();

Cuando se observa una definición compleja como esta, el mejor método para entenderla es empezar en el medio e ir hacia afuera. «Empezar en el medio» significa empezar con el nombre de la variable, que es funPtr. «Ir hacia afuera» significa mirar al elemento inmediatamente a la derecha (nada en este caso; el paréntesis derecho marca el fin de ese elemento), después mire a la izquierda (un puntero denotado por el asterisco), después mirar de nuevo a la derecha (una lista de argumentos vacía que indica que no función no toma argumentos), después a la izquierda (void, que indica que la función no retorna nada). Este movimiento derecha-izquierda-derecha funciona con la mayoría de las declaraciones. [44]

Para repasar, «empezar en el medio» («funcPtr es un ...», va a la derecha (nada aquí - pare en el paréntesis derecho), va a la izquierda y encuentra el * («... puntero a ...»), va a la derecha y encuentra la lista de argumentos vacía («... función que no tiene argumentos ...») va a la izquierda y encuentra el voidfuncPtr es un puntero a una función que no tiene argumentos y retorna void»).

Quizá se pregunte porqué *funcPtr necesita paréntesis. Si no los usara, el compilador podría ver:

void *funcPtr();

Lo que corresponde a la declaración de una función (que retorna un void*) en lugar de definir una variable. Se podría pensar que el compilador sería capaz distinguir una declaración de una definición por lo que se supone que es. El compilador necesita los paréntesis para «tener contra qué chocar» cuando vaya hacia la izquierda y encuentre el *, en lugar de continuar hacia la derecha y encontrar la lista de argumentos vacía.



[44] (N. del T.) Otra forma similar de entenderlo es dibujar mentalmente una espiral que empieza en el medio (el identificador) y se va abriendo.