Tutorial de programación en C para Linux Parte 25 – Punteros de función

Hasta ahora, en esta serie de tutoriales de programación en C, hemos tratado el concepto básico de punteros, así como bastantes aspectos relacionados con los punteros, como el puntero a una matriz y la matriz de punteros. Ampliando nuestros conocimientos sobre los punteros, en este tutorial trataremos el concepto de punteros a funciones.

Punteros a funciones en el lenguaje de programación C

Al igual que tenemos punteros a variables, también puede haber punteros a funciones. A continuación se muestra un ejemplo de declaración de un puntero a una función:

void (*fn_ptr)(int)

Aquí tenemos un puntero a función llamado ‘fn_ptr’ que puede apuntar a cualquier función que devuelva void y acepte un entero como entrada. No hace falta decir que esto es sólo la parte de la declaración; como cualquier otro puntero, tienes que asignarle una dirección (la de una función en este caso) para poder utilizarlo.

A continuación se muestra un ejemplo de utilización de este puntero:

#include <stdio.h>

void print_int(int a)
{
printf("\n The integer value is: %d\n",a);
}

int main()
{
void (*fn_ptr)(int);
fn_ptr = &print_int;
(*fn_ptr)(10);

return 0;
}

Como puedes ver, primero definimos una función ‘print_int’ que acepta un entero y devuelve void. Luego, en la función ‘main’, declaramos ‘fn_ptr’ como puntero de función que puede apuntar a funciones como ‘print_int’. A continuación, asignamos la dirección de la función «print_int» a «fn_ptr» y, por último, realizamos una llamada a la función utilizando el puntero.

Esta es la salida producida:

The integer value is: 10 

Lo que vale la pena mencionar aquí es que puedes simplificar aún más este programa evitando & y * de las dos últimas líneas. A continuación se muestra el código modificado:

#include <stdio.h>

void print_int(int a)
{
printf("\n The integer value is: %d\n",a);
}

int main()
{
void (*fn_ptr)(int);
fn_ptr = print_int;
fn_ptr(10);

return 0;

Además, al igual que una matriz de punteros, también puedes tener una matriz de punteros a funciones. Por ejemplo, lo siguiente es una matriz de punteros de función capaz de almacenar 3 direcciones de función.

void (*fn_ptr[3])(int)

Y a continuación un ejemplo que utiliza esta matriz de punteros:

void print_int1(int a)
{
printf("\n The integer value is: %d\n",a);
}

void print_int2(int a)
{
printf("\n The integer value is: %d\n",a+1);
}

void print_int3(int a)
{
printf("\n The integer value is: %d\n",a+2);
}

int main()
{
void (*fn_ptr[3])(int);

fn_ptr[0] = print_int1;
fn_ptr[1] = print_int2;
fn_ptr[2] = print_int3;

fn_ptr[0](10);
fn_ptr[1](10);
fn_ptr[2](10);

return 0;
}

Esta es la salida producida por este código:

The integer value is: 10 

The integer value is: 11

The integer value is: 12

Otro aspecto de los punteros de función que debes conocer es que también puedes utilizarlos como argumentos de funciones. Por ejemplo, puede haber una función que acepte un puntero a una función como argumento. Por ejemplo:

void some_random_func(void (*fn_ptr)(int)) 

A continuación se muestra un código de ejemplo que utiliza esta función:

#include <stdio.h>

void another_random_func(int a)
{
printf("\n The integer to entered is: %d\n", a);
}

void some_random_func(void (*fn_ptr)(int))
{
fn_ptr(5);
}


int main()
{
some_random_func(another_random_func);
return 0;
}

Lo que hicimos aquí es que creamos una función llamada ‘some_random_func’ que acepta un puntero a una función en la entrada. Luego, desde ‘main’, llamamos a ‘some_random_func’ con la dirección de otra función ‘another_random_func’ como argumento. Luego, utilizando el puntero, llamamos con éxito a ‘otro_random_func’.

Este es el resultado:

The integer to entered is: 5 

Conclusión

Los punteros a funciones pueden ser útiles cuando quieras crear algo llamado «mecanismo de devolución de llamada» (lee más sobre ello aquí) . Pero antes de entrar en eso, es mejor que entiendas bien este concepto. Te sugerimos que pruebes los ejemplos de este tutorial en tu máquina local (y también que crees otros nuevos). En caso de cualquier duda o consulta, deja un comentario abajo.

También te podría gustar...