Punteros a funciones en C: Ejemplos prácticos y mejores prácticas
Los punteros a función desbloquean capacidades poderosas en C, permitiendo que las funciones manipulen datos directamente a través de direcciones de memoria en lugar de copiar valores. Al pasar direcciones a parámetros de puntero, una función puede modificar las variables originales, permitiendo patrones como intercambio in-place, callbacks dinámicos y funciones de orden superior.
- Ejemplo de punteros a función
- Funciones con parámetros de array
- Funciones que retornan un array
- Punteros a función
- Array de punteros a función
- Funciones usando punteros void
- Punteros a función como argumentos
Ejemplo de punteros a función
La rutina clásica de intercambio demuestra cómo una función puede intercambiar los valores de dos variables operando sobre sus direcciones.
void swap (int *a, int *b); int main() { int m = 25; int n = 100; printf("m es %d, n es %d\n", m, n); swap(&m, &n); printf("m es %d, n es %d\n", m, n); return 0; } void swap (int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; }
Salida:
m es 25, n es 100 m es 100, n es 25

- Declarar
swapcon dos punteros a entero. - Inicializar
mynenmaine imprimirlos. - Llamar
swap(&m, &n)para pasar las direcciones. - Dentro de
swap, usar una variable temporal para intercambiar los valores. - Desreferenciar punteros para leer/escribir los datos reales.
Funciones con parámetros de array
Los arrays decaen a punteros cuando se pasan a funciones. El siguiente programa suma los elementos de un array iterando sobre el puntero.
int add_array (int *a, int num_elements); int main() { int Tab[5] = {100, 220, 37, 16, 98}; printf("Suma total es %d\n", add_array(Tab, 5)); return 0; } int add_array (int *p, int size) { int total = 0; for (int k = 0; k < size; k++) { total += p[k]; /* equivalente a total += *p; p++; */ } return total; }
Salida:
Suma total es 471

- Definir
add_arraypara aceptar un puntero y tamaño, retornando la suma. - Pasar el nombre del array
Tab(que decae a puntero) y su longitud a la función.
Funciones que retornan un array
Una función puede retornar un puntero a un array estático. Este enfoque es útil cuando el llamador necesita un array temporal sin gestionar asignación de memoria.
#include <stdio.h> int * build_array(); int main() { int *a; a = build_array(); /* obtener primeros 5 números pares */ for (int k = 0; k < 5; k++) printf("%d\n", a[k]); return 0; } int * build_array() { static int Tab[5] = {1,2,3,4,5}; return Tab; }
Salida:
1 2 3 4 5

- Declarar una función que retorna un puntero a un array estático.
- Usar el puntero retornado para iterar e imprimir el contenido del array.
Punteros a función
Un puntero a función contiene la dirección del punto de entrada de una función, permitiendo despacho dinámico y callbacks. La sintaxis de declaración requiere paréntesis alrededor del asterisco para evitar malinterpretación.
tipo_retorno (*nombre_funcion)(argumentos)
Ejemplo: Llamar a una rutina a través de un puntero.
#include <stdio.h> void Hi_function (int times); /* función */ int main() { void (*function_ptr)(int); /* puntero a función */ function_ptr = Hi_function; /* asignación */ function_ptr(3); /* invocación */ return 0; } void Hi_function (int times) { for (int k = 0; k < times; k++) printf("Hola\n"); }
Salida:
Hola Hola Hola

- Definir una función regular.
- Declarar un puntero a función con la firma correcta.
- Asignar el puntero al nombre de la función.
- Invocar la función a través del puntero.
Array de punteros a función
Almacenar múltiples punteros a función en un array permite un enfoque basado en tabla, similar a una sentencia switch. El siguiente programa demuestra una calculadora simple.
#include <stdio.h> int sum(int num1, int num2); int sub(int num1, int num2); int mult(int num1, int num2); int divi(int num1, int num2); int main() { int x, y, choice, result; int (*ope[4])(int, int); ope[0] = sum; ope[1] = sub; ope[2] = mult; ope[3] = divi; printf("Ingrese dos números enteros: "); scanf("%d%d", &x, &y); printf("Ingrese 0 para sumar, 1 para restar, 2 para multiplicar, o 3 para dividir: "); scanf("%d", &choice); result = ope[choice](x, y); printf("%d", result); return 0; } int sum(int x, int y) {return x + y;} int sub(int x, int y) {return x - y;} int mult(int x, int y) {return x * y;} int divi(int x, int y) {return y != 0 ? x / y : 0;}
Resultado: Ingresar 13 48 2 → 624

- Definir cuatro funciones aritméticas.
- Crear un array de cuatro punteros a función con firmas coincidentes.
- Asignar cada puntero a la función correspondiente.
- Obtener la elección del usuario y llamar a la función seleccionada.
Funciones usando punteros void
Los punteros void proporcionan acceso agnóstico al tipo de datos. Cuando se usan en parámetros de función, permiten que la rutina acepte cualquier tipo de dato, siempre que el llamador proporcione el cast correcto.
void * cube (const void *);
Programa de ejemplo:
#include <stdio.h> void* cube (const void* num); int main() { int x = 4; int cube_int = (int)cube(&x); printf("%d al cubo es %d\n", x, cube_int); return 0; } void* cube (const void *num) { int result = (*(int *)num) * (*(int *)num) * (*(int *)num); return (void*)result; }
Resultado: 4 al cubo es 64

- Definir una función que acepte un puntero void const y retorne un puntero void.
- Castear el puntero a
int *para acceder al valor. - Calcular el cubo y castear el resultado de vuelta a
void *para retorno.
Punteros a función como argumentos
Pasar un puntero a función a otra función es un patrón común para callbacks. La biblioteca estándar qsort usa esta técnica para ordenar arrays de tipos arbitrarios.
void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *));
Ejemplo que ordena un array de enteros:
#include <stdio.h> #include <stdlib.h> int compare (const void *, const void *); int main() { int arr[5] = {52, 14, 50, 48, 13}; size_t num = sizeof(arr)/sizeof(arr[0]); size_t width = sizeof(arr[0]); qsort((void *)arr, num, width, compare); for (size_t i = 0; i < num; i++) printf("%d ", arr[i]); return 0; } int compare (const void *elem1, const void *elem2) { int a = *(int *)elem1; int b = *(int *)elem2; return (a - b); }
Resultado: 13 14 48 50 52

- Implementar
comparepara retornar negativo, cero o positivo basado en los dos enteros. - Determinar tamaño del array y ancho de elemento con
sizeof. - Llamar
qsortcon el array, cuenta, ancho y función de comparación. - Imprimir el array ordenado para verificar la operación.
Lenguaje C
- Cuatro patrones probados para funciones definidas por el usuario en C
- Bucle do‑while en C++: Sintaxis, ejemplos prácticos y bucles anidados
- Dominando punteros en C++: Conceptos, ejemplos y aplicaciones prácticas
- Sobrecarga de operadores en C++: Guía práctica con ejemplos de código
- Funciones en C++ Explicadas con Ejemplos de Código Prácticos
- Dominando Colecciones en C#: Tutorial Práctico con Ejemplos del Mundo Real
- Punteros en C: Guía completa sobre tipos, uso y mejores prácticas
- Domine str.count() en Python: Cómo Contar Caracteres y Subcadenas con Ejemplos
- Dominando las funciones lambda en Python: ejemplos prácticos y mejores prácticas
- Función round() en Python explicada con ejemplos prácticos
- Dominando la función map() de Python: sintaxis, ejemplos y mejores prácticas