Skip to content

Apuntadores a funciones

RDLL edited this page Aug 11, 2023 · 1 revision

Apuntadores a funciones

#include <iostream>

using namespace std;

void hola();

// Lo que esta en comentarios es otra forma

int main(){
    void (*ptr)(void) = hola; //void (*ptr)(void)
    //ptr = hola;
    ptr(); 
    return 0;
}

void hola(){
    cout << "Hola mundo" << endl;
}

Otra ventaja importante de los punteros es que pueden apuntar a funciones, por lo que en vez de llamar a una función podemos llamar a un puntero en vez de a la función, tal vez sea mas fácil llamar directamente a la función, sin embargo cuando dependemos de un resultado para llamar a una función, podemos utilizar punteros.

Aunque parezca complicado es más sencillo de lo que parece.

Veamos la sintáxis

tipo de función (*apuntador)(parámetros) = nombre de la función

La sintáxis cambia según los datos que se trabajen

Puntero a función sin parámetros

void (*fptr)(); // Apuntador a funcion que devuelve void
int (*fptr)(); // Apuntador a funcion que devuelve int 
float (*fptr)(); // Apuntador a funcion que devuelve float 
double (*fptr)(); // Apuntador a funcion que devuelve double 
char (*fptr)(); // Apuntador a funcion que devuelve char 
bool (*fptr)(); // Apuntador a funcion que devuelve bool 

Puntero a función con parámetros

void (*fptr)(float,int); // Apuntador a funcion que devuelve void
void (*fptr)(float,int); // Apuntador a funcion que devuelve int 
int (*fptr)(double,int,char); // Apuntador a funcion de tipo int 
float (*fptr)(double); // Apuntador a funcion que devuelve float
double (*fptr)(char); // Apuntador a funcion que devuelve double 
char (*fptr)(bool,int); // Apuntador a funcion que devuelve char 
bool (*fptr)(float); // Apuntador a funcion que devuelve bool 

No importa la cantidad de parámetros, pero al invocar al puntero, deben ir en el orden definido

Puntero a función que devuelve un apuntador

void* (*fptr)(float,int); // Apuntador a funcion que devuelve un apuntador a void
int* (*fptr)(double,int,char); // Apuntador a funcion que devuelve un apuntador a int
float* (*fptr)(); // Apuntador a funcion que devuelve un apuntador a float 
double* (*fptr)(char); // Apuntador a funcion que devuelve un apuntador a double
char* (*fptr)(bool,int); // Apuntador a funcion que devuelve un apuntador a char
bool* (*fptr)(float); // Apuntador a funcion que devuelve un apuntador a bool

Puntero a función que devuelve un apuntador a constante

void const* (*fptr)(float &,int); // Apuntador a funcion que devuelve un apuntador a void constante
int const* (*fptr)(double &,int,char); // Apuntador a funcion que devuelve un apuntador a int constante
float const* (*fptr)(); // Apuntador a funcion que devuelve un apuntador a float constante
double const* (*fptr)(char); // Apuntador a funcion que devuelve un apuntador a double constante
char const* (*fptr)(bool,int); // Apuntador a funcion que devuelve un apuntador a char constante
bool const* (*fptr)(float &); // Apuntador a funcion que devuelve un apuntador a bool constante

Los parámetros también pueden ser referenciados

Puntero a función que devuelve un puntero a función

void (*(*fptr)(char))(int); // Apuntador a funcion que recibe char y devuelve un puntero a funcion que recibe int y devuelve void
int (*(*fptr)(float))(double); // Apuntador a funcion que recibe float y devuelve un puntero a funcion que recibe double y devuelve int
float (*(*fptr)(int))(int); // Apuntador a funcion que recibe int y devuelve un puntero a funcion que recibe int y devuelve float
double (*(*fptr)(char))(bool); // Apuntador a funcion que recibe char y devuelve un puntero a funcion que recibe bool y devuelve double
char (*(*fptr)(float,int))(double,bool); // Apuntador a funcion que recibe float e int y devuelve un puntero a funcion que recibe double y bool y devuelve char
bool (*(*fptr)(char))(int); // Apuntador a funcion que recibe char y devuelve un puntero a funcion que recibe int y devuelve bool

Puntero a función que devuelve un puntero a arreglo de apuntadores

void *(*(*fptr)(int))[5]; //Apuntador a funcion que recibe int y devuelve un puntero a un arreglo de 5 punteros a void
int *(*(*fptr)(char))[7]; // Apuntador a funcion que recibe char y devuelve un puntero a un arreglo de 7 punteros a int
float *(*(*fptr)(float, char))[2]; // Apuntador a funcion que recibe float y char, y devuelve un puntero a un arreglo de 2 punteros a float
double *(*(*fptr)())[4]; // Apuntador a funcion que no recibe parámetros y devuelve un puntero a un arreglo de 4 punteros a double
char *(*(*fptr)(float))[10]; // Apuntador a funcion que recibe float y devuelve un puntero a un arreglo de 10 punteros a char
bool *(*(*fptr)(double))[5]; // Apuntador a funcion que recibe double y devuelve un puntero a un arreglo de 5 punteros a bool

Arreglo de punteros a función

void (*ptr[5])(int); //Arreglo de 5 apuntadores a funcion que recibe int y devuelve void
int (*ptr[7])(int,float); //Arreglo de 7 apuntadores a funcion que recibe int y float, y devuelve int
float (*ptr[4])(); //Arreglo de 4 apuntadores a funcion que no recibe parámetros y devuelve float
double (*ptr[5])(int &); //Arreglo de 5 apuntadores a funcion que recibe int y devuelve double
char (*ptr[8])(char,double &); //Arreglo de 8 apuntadores a funcion que recibe char y double, y devuelve char
bool (*ptr[5])(int); //Arreglo de 5 apuntadores a funcion que recibe int y devuelve bool

Cuando se tiene un arreglo de punteros a función, cada puntero deberá apuntar a una función con los parametros descritos

Sustituyendo switch

Por ejemplo un caso muy sencillo en el que podrías usar punteros a funciones, es cuando usamos switch, en vez de tener los case tendríamos funciones y un arreglo de apuntadores, apuntando a dichas funciones, por lo que solo tendríamos que mandar la posición donde se encuentre la función, como si se tratará del case sin embargo es más directo debido a que no se hace ninguna comparación y se manda directo el resultado.

#include <iostream>

using namespace std;


void suma(float &x, float &y);
void resta(float &x, float &y);
void multiplicacion(float &x, float &y);
void division(float &x, float &y);
void salida(float &x,float &y);
float get(float &y);
int menu();

int main(){
    float x,y;
    x=y=0;
    int op;
    void (*fptr[5])(float &,float &);
    fptr[0] = suma;
    fptr[1] = resta;
    fptr[2] = multiplicacion;
    fptr[3] = division;
    fptr[4] = salida;
    op = menu();
    fptr[op](x,y);
    return 0;
}

void suma(float &x, float &y){
    x = get(y);
    cout << x + y << endl;
}

void multiplicacion(float &x, float &y){
    x = get(y);
    cout << x * y << endl;
}

void division(float &x, float &y){
    x = get(y);
    cout << x / y << endl;
}

void resta(float &x, float &y){
    x = get(y);
    cout << x - y << endl;
}

void salida(float &x, float &y){
    cout << "Hasta luego" << endl;
}

int menu(){
    int op;
    cout << "Selecciona una opcion:\n";
    cout << "1.- Suma\n";
    cout << "2.- Resta\n";
    cout << "3.- Multiplicacion\n";
    cout << "4.- Division\n";
    cout << "5.- Salir\n";
    cin >> op;
    return (op > 4 || op < 1) ? 4 : op-1;
}

float get(float &y){
    float x;
    cout << "Ingresa dos numeros:\n";
    cin >> x >> y;
    return x;
}
Introducción Apuntadores Arreglos y apuntadores Arreglo de apuntadores Estructuras