¿Puntero de función Typedef?
Estoy aprendiendo a cargar DLL dinámicamente pero lo que no entiendo es esta línea
typedef void (*FunctionFunc)();
Tengo algunas preguntas. Si alguien puede responderlas se lo agradecería.
- ¿ Por qué se
typedef
utiliza? - La sintaxis parece extraña; ¿ Después
void
no debería haber un nombre de función o algo así? Parece una función anónima. - ¿Se crea un puntero de función para almacenar la dirección de memoria de una función?
Así que estoy confundido en este momento; ¿Puedes aclararme las cosas?
typedef
es una construcción del lenguaje que asocia un nombre a un tipo.
Lo usas de la misma manera que usarías el tipo original, por ejemplo
typedef int myinteger;
typedef char *mystring;
typedef void (*myfunc)();
usándolos como
myinteger i; // is equivalent to int i;
mystring s; // is the same as char *s;
myfunc f; // compile equally as void (*f)();
Como puede ver, puede simplemente reemplazar el nombre typedefed con la definición dada anteriormente.
La dificultad radica en la sintaxis y legibilidad de las funciones en C y C++, y puede typedef
mejorar la legibilidad de dichas declaraciones. Sin embargo, la sintaxis es apropiada, ya que las funciones, a diferencia de otros tipos más simples, pueden tener un valor de retorno y parámetros, de ahí la declaración a veces larga y compleja de un puntero a la función.
La legibilidad puede comenzar a ser realmente complicada con punteros a matrices de funciones y algunas otras variantes aún más indirectas.
Para responder a tus tres preguntas
¿Por qué se utiliza typedef? Para facilitar la lectura del código, especialmente para punteros a funciones o nombres de estructuras.
La sintaxis parece extraña (en el puntero a la declaración de función). Esa sintaxis no es obvia de leer, al menos al principio. En cambio , utilizar una
typedef
declaración facilita la lectura.¿Se crea un puntero de función para almacenar la dirección de memoria de una función? Sí, un puntero de función almacena la dirección de una función. Esto no tiene nada que ver con la
typedef
construcción que solo facilita la escritura/lectura de un programa; el compilador simplemente expande la definición de typedef antes de compilar el código real.
Ejemplo:
typedef int (*t_somefunc)(int,int);
int product(int u, int v) {
return u*v;
}
t_somefunc afunc = &product;
...
int x2 = (*afunc)(123, 456); // call product() to calculate 123*456
typedef
se utiliza para alias tipos; en este caso le estás asignando un aliasFunctionFunc
avoid(*)()
.De hecho, la sintaxis parece extraña, eche un vistazo a esto:
typedef void (*FunctionFunc) ( ); // ^ ^ ^ // return type type name arguments
No, esto simplemente le dice al compilador que el
FunctionFunc
tipo será un puntero de función, no define uno, así:FunctionFunc x; void doSomething() { printf("Hello there\n"); } x = &doSomething; x(); //prints "Hello there"
Sin la typedef
palabra, en C++ la declaración declararía una variable FunctionFunc
de tipo puntero a función sin argumentos, devolviendo void
.
En typedef
cambio, se define FunctionFunc
como un nombre para ese tipo.
Si puede utilizar C++ 11, es posible que desee utilizar std::function
una using
palabra clave.
using FunctionFunc = std::function<void(int arg1, std::string arg2)>;
#include <stdio.h>
#include <math.h>
/*
To define a new type name with typedef, follow these steps:
1. Write the statement as if a variable of the desired type were being declared.
2. Where the name of the declared variable would normally appear, substitute the new type name.
3. In front of everything, place the keyword typedef.
*/
// typedef a primitive data type
typedef double distance;
// typedef struct
typedef struct{
int x;
int y;
} point;
//typedef an array
typedef point points[100];
points ps = {0}; // ps is an array of 100 point
// typedef a function
typedef distance (*distanceFun_p)(point,point) ; // TYPE_DEF distanceFun_p TO BE int (*distanceFun_p)(point,point)
// prototype a function
distance findDistance(point, point);
int main(int argc, char const *argv[])
{
// delcare a function pointer
distanceFun_p func_p;
// initialize the function pointer with a function address
func_p = findDistance;
// initialize two point variables
point p1 = {0,0} , p2 = {1,1};
// call the function through the pointer
distance d = func_p(p1,p2);
printf("the distance is %f\n", d );
return 0;
}
distance findDistance(point p1, point p2)
{
distance xdiff = p1.x - p2.x;
distance ydiff = p1.y - p2.y;
return sqrt( (xdiff * xdiff) + (ydiff * ydiff) );
}