Declaración de punteros a funciones
Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 33 de 61.
Hasta ahora, hemos aprendido a simular la herencia utilizando la incrustación de estructuras (struct embedding). Pero el verdadero polimorfismo — donde diferentes objetos responden de manera distinta a la misma llamada — requiere algo más: punteros a funciones.
Un puntero a función es una variable que almacena la dirección de una función. Al igual que un puntero normal contiene la dirección de los datos, un puntero a función contiene la dirección de código ejecutable.
La sintaxis puede parecer intimidante al principio. Para declarar un puntero a función, se especifica el tipo de retorno, luego el nombre del puntero entre paréntesis con un asterisco, seguido de los tipos de parámetros:
int (*operation)(int, int);Esto declara una variable llamada operation que puede apuntar a cualquier función que tome dos parámetros int y devuelva un int. Los paréntesis alrededor de *operation son cruciales; sin ellos, estarías declarando una función que devuelve un puntero.
Para asignar una función a este puntero, simplemente use el nombre de la función (sin paréntesis):
int add(int a, int b) {
return a + b;
}
int (*operation)(int, int);
operation = add; // Ahora operation apunta a addEl nombre de la función actúa como su dirección. También puedes usar &add explícitamente, pero es opcional; ambas formas son equivalentes en C.
Desafío
FácilPractiquemos la declaración de punteros a funciones y la asignación de funciones a ellos. Crearás un sistema simple de operaciones matemáticas donde un puntero a función puede contener diferentes funciones aritméticas.
Escribe un programa que:
- Defina dos funciones:
multiply— toma dos parámetrosinty devuelve su productosubtract— toma dos parámetrosinty devuelve el primero menos el segundo
- En
main, declare una variable de puntero a función llamadaoperationque pueda apuntar a funciones que tomen dos parámetrosinty devuelvan unint - Lea tres entradas: dos números enteros y un código de operación (1 para multiply, 2 para subtract)
- Basándose en el código de operación, asigne la función apropiada a tu puntero
operation - Imprima el nombre de la operación asignada, luego imprima el resultado de llamar a la función a través del puntero
Recibirás tres entradas: el primer número, el segundo número y el código de operación (1 o 2).
Tu salida debería verse así:
Operation: multiply
Result: 35Donde multiply es el nombre de la operación (o subtract si el código es 2), y 35 es el resultado de llamar a la función a través de tu puntero (en este caso, 5 × 7).
Recuerda: para declarar el puntero a función, necesitas el tipo de retorno, el nombre del puntero entre paréntesis con un asterisco y los tipos de parámetros. Para asignar una función, usa solo el nombre de la función sin paréntesis.
Hoja de referencia
Un puntero a función es una variable que almacena la dirección de una función, permitiendo el polimorfismo al permitir que se llamen diferentes funciones a través del mismo puntero.
Declaración de un puntero a función
La sintaxis especifica el tipo de retorno, el nombre del puntero con un asterisco entre paréntesis y los tipos de parámetros:
int (*operation)(int, int);Esto declara operation como un puntero a cualquier función que tome dos parámetros int y devuelva un int. Los paréntesis alrededor de *operation son esenciales.
Asignación de una función a un puntero
Use el nombre de la función sin paréntesis:
int add(int a, int b) {
return a + b;
}
int (*operation)(int, int);
operation = add; // operation ahora apunta a addEl nombre de la función actúa como su dirección. También puede usar &add explícitamente, pero es opcional.
Pruébalo tú mismo
#include <stdio.h>
// TODO: Define la función multiply aquí
// TODO: Define la función subtract aquí
int main() {
int num1, num2, code;
// Leer entrada
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &code);
// TODO: Declara un puntero de función llamado 'operation' que pueda apuntar a
// funciones que tomen dos parámetros int y devuelvan un int
// TODO: Basado en el código de operación (1 para multiplicar, 2 para restar),
// asigna la función apropiada a tu puntero de operación
// TODO: Imprime el nombre de la operación y el resultado
// Formato:
// Operation: <name>
// Result: <result>
return 0;
}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