¿Cómo pasas una función como parámetro en C?

Quiero crear una función que realice una función pasada por parámetro en un conjunto de datos. ¿Cómo pasas una función como parámetro en C?

Declaración

Un prototipo para una función que toma un parámetro de función tiene el siguiente aspecto:

 void func ( void (*f)(int) ); 

Esto indica que el parámetro f será un puntero a una función que tiene un tipo de retorno de void y que toma un solo parámetro int . La siguiente función ( print ) es un ejemplo de una función que podría pasarse a func como parámetro porque es del tipo adecuado:

 void print ( int x ) { printf("%d\n", x); } 

Llamada de función

Cuando se llama a una función con un parámetro de función, el valor pasado debe ser un puntero a una función. Use el nombre de la función (sin paréntesis) para esto:

 func(print); 

llamaría a func y le pasaría la función de impresión.

Cuerpo de la función

Como con cualquier parámetro, func ahora puede usar el nombre del parámetro en el cuerpo de la función para acceder al valor del parámetro. Digamos que func aplicará la función que se pasa a los números 0-4. Considere, primero, cómo se vería el bucle para imprimir directamente:

 for ( int ctr = 0 ; ctr < 5 ; ctr++ ) { print(ctr); } 

Como la statement de parámetros de func dice que f es el nombre de un puntero a la función deseada, primero recordamos que si f es un puntero, entonces *f es lo que apunta f (es decir, la función print en este caso). Como resultado, simplemente reemplace cada aparición de impresión en el ciclo anterior con *f :

 void func ( void (*f)(int) ) { for ( int ctr = 0 ; ctr < 5 ; ctr++ ) { (*f)(ctr); } } 

De http://math.hws.edu/bridgemn/courses/331/f05/handouts/c-c++-notes.html

Esta pregunta ya tiene la respuesta para definir los indicadores de función, sin embargo, pueden ser muy complicados, especialmente si los va a pasar a su aplicación. Para evitar esta desagradable, le recomendaría que escriba el puntero de la función en algo más legible. Por ejemplo.

 typedef void (*functiontype)(); 

Declara una función que devuelve vacío y no toma argumentos. Para crear un puntero de función para este tipo, ahora puede hacer:

 void dosomething() { } functiontype func = &dosomething; func(); 

Para una función que devuelve un int y toma un char, lo harías

 typedef int (*functiontype2)(char); 

y para usarlo

 int dosomethingwithchar(char a) { return 1; } functiontype2 func2 = &dosomethingwithchar int result = func2('a'); 

Hay bibliotecas que pueden ayudar a convertir los punteros de función en buenos tipos legibles. ¡La biblioteca de funciones de refuerzo es excelente y bien vale la pena!

 boost::function functiontype2; 

es mucho más agradable que el anterior.

Desde C ++ 11 puede usar la biblioteca funcional para hacer esto de forma sucinta y genérica. La syntax es, por ejemplo,

 std::function 

donde bool es el tipo de retorno aquí de una función de un argumento cuyo primer argumento es de tipo int .

He incluido un progtwig de ejemplo a continuación:

 // g++ test.cpp --std=c++11 #include  double Combiner(double a, double b, std::function func){ return func(a,b); } double Add(double a, double b){ return a+b; } double Mult(double a, double b){ return a*b; } int main(){ Combiner(12,13,Add); Combiner(12,13,Mult); } 

A veces, sin embargo, es más conveniente usar una función de plantilla:

 // g++ test.cpp --std=c++11 template double Combiner(double a, double b, T func){ return func(a,b); } double Add(double a, double b){ return a+b; } double Mult(double a, double b){ return a*b; } int main(){ Combiner(12,13,Add); Combiner(12,13,Mult); } 

Pasar la dirección de una función como parámetro a otra función como se muestra a continuación

 #include  void print(); void execute(void()); int main() { execute(print); // sends address of print return 0; } void print() { printf("Hello!"); } void execute(void f()) // receive address of print { f(); } 

También podemos pasar la función como parámetro usando el puntero de la función

 #include  void print(); void execute(void (*f)()); int main() { execute(&print); // sends address of print return 0; } void print() { printf("Hello!"); } void execute(void (*f)()) // receive address of print { f(); } 

Necesita pasar un puntero a la función . La syntax es un poco engorrosa, pero es realmente poderosa una vez que te familiarizas con ella.