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 mediante la incrustación de structs. Pero el verdadero polimorfismo —donde diferentes objetos responden de manera diferente 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 regular contiene la dirección de 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, especifica el tipo de retorno, después 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 assign una function a este pointer, simplemente usa el nombre de la function (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 de operaciones matemáticas simple 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 toman dos parámetrosinty devuelven unint - Lea tres entradas: dos enteros y un código de operación (1 para multiplicar, 2 para restar)
- Según el código de operación, asigne la función adecuada a su puntero
operation - Imprima el nombre de la operación asignada, después 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 debe 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.
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 a función llamado 'operation' que pueda apuntar a
// funciones que tomen dos parámetros int y devuelvan un int
// TODO: Según el código de operación (1 para multiply, 2 para subtract),
// asigna la función apropiada a tu puntero operation
// 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írculoImplementación del rectánguloUso polimórficoContenedor de figuras