Pregunta

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?

¿Fue útil?

Solución

Declaración

Un prototipo de una función que toma un parámetro de función se parece al siguiente:

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

Esto indica que el parámetro f será un puntero a una función que tiene un void tipo de retorno y que toma un solo int parámetro.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

Al llamar 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 esto:

func(print);

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

Cuerpo de función

Como ocurre 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 del 0 al 4.Consideremos, primero, cómo se vería el bucle al llamar a imprimir directamente:

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

Desde funcLa declaración del parámetro dice que f es el nombre de un puntero a la función deseada, recordemos primero que si f es un puntero entonces *f es lo que f apunta a (es decirla función print en este caso).Como resultado, simplemente reemplace cada aparición de print en el bucle anterior con *f:

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

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

Otros consejos

Esta pregunta ya tiene la respuesta para definir punteros de función, sin embargo, pueden resultar muy complicados, especialmente si los va a pasar por su aplicación.Para evitar este malestar, recomendaría que escribadef el puntero de función en algo más legible.Por ejemplo.

typedef void (*functiontype)();

Declara una función que devuelve nula y no acepta 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 carácter, lo harías

typedef int (*functiontype2)(char);

y para usarlo

int dosomethingwithchar(char a) { return 1; }

functiontype2 func2 = &dosomethingwithchar
int result = func2('a');

Existen bibliotecas que pueden ayudar a convertir los punteros de función en tipos agradables y legibles.El función de impulso ¡La biblioteca es genial y vale la pena el esfuerzo!

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

es mucho mejor que el anterior.

Desde C++ 11 puedes usar el biblioteca funcional hacerlo de forma sucinta y genérica.La sintaxis es, por ejemplo,

std::function<bool (int)>

dónde 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);
}

A veces, sin embargo, 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);
}

Aprobar dirección de una función como parámetro de otra función Como se muestra abajo

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

Necesitas pasar un puntero de función.La sintaxis es un poco engorrosa, pero es realmente poderosa una vez que te familiarizas con ella.

Las funciones se pueden "pasar" como punteros de función, según 6.7.6.3p8:"Una declaración de un parámetro como "tipo de retorno de función" se ajustará a "puntero a 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));

En realidad no es una función, pero es un fragmento de código localizado.Por supuesto, no pasa el código solo el resultado.No funcionará si se pasa a un despachador de eventos para ejecutarlo más adelante (ya que el resultado se calcula ahora y no cuando ocurre el evento).Pero localiza su código en un solo lugar si eso es todo lo que intenta hacer.

#include <stdio.h>

int IncMultInt(int a, int b)
{
    a++;
    return a * b;
}

int main(int argc, char *argv[])

{
    int a = 5;
    int b = 7;

    printf("%d * %d = %d\n", a, b, IncMultInt(a, b));

    b = 9;

    // Create some local code with it's own local variable
    printf("%d * %d = %d\n", a, b,  ( { int _a = a+1; _a * b; } ) );

    return 0;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top