¿Cómo se pasa una función como parámetro en C

c function pointers syntax parameters


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




Answer 1 Niyaz


Declaration

Un prototipo para una función que toma un parámetro de función se ve como el siguiente:

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

Esto establece que el parámetro f será un puntero a una función que tiene un tipo de retorno 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.Utilice el nombre de la función (sin paréntesis)para ello:

func(print);

llamaría a func , pasándole la función de impresión.

Función Cuerpo

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 le pasa a los números 0-4. Considere, primero, cómo se vería el bucle para llamar a imprimir directamente:

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

Dado que la declaración de parámetros de func dice que f es el nombre de un puntero a la función deseada, recordamos primero 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);
  }
}

Source




Answer 2 roo


Esta pregunta ya tiene la respuesta para definir los punteros de la función,sin embargo,pueden ser muy desordenados,especialmente si los vas a pasar por tu aplicación.Para evitar esta desagradable situación,le recomendaría que escribiera el puntero de función en algo más legible.Por ejemplo.

typedef void (*functiontype)();

Declara una función que devuelve el vacío y no acepta argumentos.Para crear un puntero de función de este tipo ahora puedes hacer:

void dosomething() { }

functiontype func = &dosomething;
func();

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

typedef int (*functiontype2)(char);

y para usarla

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 tipos agradables y legibles. ¡La biblioteca de funciones de impulso es excelente y vale la pena el esfuerzo!

boost::function<int (char a)> functiontype2;

es mucho más agradable que lo anterior.




Answer 3 Richard


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

std::function<bool (int)>

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 programa de ejemplo a continuación:

// g++ test.cpp --std=c++11
#include <functional>

double Combiner(double a, double b, std::function<double (double,double)> 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);
}

Sin embargo,a veces es más conveniente utilizar una función de plantilla:

// g++ test.cpp --std=c++11

template<class T>
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);
}



Answer 4 Yogeesh H T


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

#include <stdio.h>

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 función

#include <stdio.h>

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();
}



Answer 5 doppelheathen


Las funciones se pueden "pasar" como punteros de función, según ISO C11 6.7.6.3p8: " Una declaración de un parámetro como '' tipo de retorno de función '' se ajustará a '' puntero al tipo de retorno de función '' , como en 6.3 .2.1. ". Por ejemplo, esto:

void foo(int bar(int, int));

es equivalente a esto:

void foo(int (*bar)(int, int));