Pasar funciones como argumentos
Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 36 de 61.
Uno de los usos más potentes de los punteros a funciones es pasarlos como argumentos a otras funciones. Esto permite inyectar un comportamiento personalizado en una función sin modificar su código — una técnica que a veces se denomina callback.
Considera una función que realiza un cálculo sobre dos números. En lugar de codificar la operación de forma fija, puedes aceptar un puntero a función que defina qué operación realizar:
typedef int (*Operation)(int, int);
int compute(int a, int b, Operation op) {
return op(a, b);
}La función compute no sabe si está sumando, restando o haciendo algo completamente distinto. Simplemente llama a cualquier función que se le pase:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Salida: 8
printf("%d\n", compute(5, 3, multiply)); // Salida: 15
return 0;
}Observa cómo la misma función compute produce resultados diferentes según la función que pasemos. Este patrón es fundamental para escribir código flexible y reutilizable: escribes la estructura una vez y los usuarios de tu función proporcionan la lógica específica que necesitan.
Desafío
FácilEscribe una función apply_twice que tome dos enteros y un código de operación, aplique la operación a los números dos veces en secuencia y devuelva el resultado final.
Tu función recibirá un código de operación que determina qué operación usar. Debes definir las funciones de operación dentro de tu solución y pasarlas a una función auxiliar compute que acepte un puntero de función.
Estructura requerida:
- Define un
typedefllamadoOperationpara un puntero de función que tome dos parámetrosinty devuelva unint - Define dos funciones de operación:
add(devuelve a + b) ymultiply(devuelve a * b) - Define una función
computeque tome dos enteros y un puntero de funciónOperation, y luego devuelva el resultado de llamar a la operación - En
apply_twice, selecciona la operación apropiada basada en el código, luego usacomputedos veces: primero con los números originales, luego con el resultado y el segundo número nuevamente
Lógica:
- Selecciona la función de operación basada en
op_code(1 = add, 2 = multiply) - Llama a
compute(a, b, operation)para obtener un resultado intermedio - Llama a
compute(intermediate, b, operation)para obtener el resultado final - Devuelve el resultado final
Parámetros:
a(int): Primer númerob(int): Segundo númeroop_code(int): Código de operación (1 para add, 2 para multiply)
Devuelve: El resultado después de aplicar la operación dos veces en secuencia (int)
Ejemplo: Con a = 5, b = 3, op_code = 1 (add):
- Primer compute: 5 + 3 = 8
- Segundo compute: 8 + 3 = 11
- Devuelve: 11
Con a = 2, b = 4, op_code = 2 (multiply):
- Primer compute: 2 × 4 = 8
- Segundo compute: 8 × 4 = 32
- Devuelve: 32
Hoja de referencia
Los punteros a funciones pueden pasarse como argumentos a otras funciones, permitiendo los callbacks — una forma de inyectar un comportamiento personalizado sin modificar el código de la función.
Define un tipo de puntero a función usando typedef:
typedef int (*Operation)(int, int);Crea una función que acepte un puntero a función como parámetro:
int compute(int a, int b, Operation op) {
return op(a, b);
}Pasa diferentes funciones para lograr diferentes comportamientos:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Salida: 8
printf("%d\n", compute(5, 3, multiply)); // Salida: 15
return 0;
}Este patrón te permite escribir código flexible y reutilizable donde la estructura se define una vez y los usuarios proporcionan la lógica específica que necesitan.
Pruébalo tú mismo
int apply_twice(int a, int b, int op_code) {
// Escribe el código aquí
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1Fundamentos de programación modular
Archivos de cabeceraGuardas de inclusiónArchivos fuenteFunciones estáticasRepaso: Calculadora modular4Encapsulamiento
Concepto de punteros opacosDefinición de structs opacosGetters y SettersValidación en settersResumen: Caja secreta7Punteros a funciones
Declaración de punteros a funcionesLlamada a punteros a funcionesTypedef para punteros a funcionesPasar funciones como argumentosRepaso: Dispatch de calculadora10Contenedores genéricos
Repaso de punteros voidWrapper genéricoSwap genéricoComparación genéricaRepaso: Array genérico2Objetos y métodos
Structs como objetosEl puntero 'Self'Const CorrectnessPuntero vs. ValorMétodos auxiliaresResumen: Point Manager5Proyecto: Cuenta bancaria simple
Configuración del proyectoImplementación de la cuenta3Ciclo de vida de los objetos
Patrón ConstructorPatrón DestructorInicialización en StackCopia profundaResumen: String Wrapper6Herencia mediante composición
Incrustación de StructsLa regla del primer miembroAcceso a miembros padreUpcastingResumen: Jerarquía de formas9Proyecto: Dibujador de figuras
Descripción general del proyectoImplementación del círculo