Domanda

Voglio creare una funzione che esegua una funzione passata per parametro su un insieme di dati.Come si passa una funzione come parametro in C?

È stato utile?

Soluzione

Dichiarazione

Un prototipo per una funzione che accetta un parametro di funzione è simile al seguente:

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

Questo afferma che il parametro f sarà un puntatore a una funzione che ha a void tipo restituito e che accetta un singolo int parametro.La seguente funzione (print) è un esempio di una funzione a cui potrebbe essere passato func come parametro perché è del tipo corretto:

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

Chiamata di funzione

Quando si chiama una funzione con un parametro di funzione, il valore passato deve essere un puntatore a una funzione.Utilizza il nome della funzione (senza parentesi) per questo:

func(print);

chiamerebbe func, passandogli la funzione di stampa.

Corpo funzionale

Come con qualsiasi parametro, func ora può utilizzare il nome del parametro nel corpo della funzione per accedere al valore del parametro.Diciamo che func applicherà la funzione passata ai numeri 0-4.Consideriamo innanzitutto come apparirebbe il ciclo se chiamasse direttamente print:

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

Da funcla dichiarazione dei parametri di dice questo f è il nome di un puntatore alla funzione desiderata, ricordiamo innanzitutto che if f è un puntatore allora *f è la cosa che f indica (cioèla funzione print in questo caso).Di conseguenza, sostituisci semplicemente ogni occorrenza di print nel ciclo precedente con *f:

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

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

Altri suggerimenti

Questa domanda ha già la risposta per definire i puntatori a funzione, tuttavia possono diventare molto confusi, soprattutto se li passerai all'interno della tua applicazione.Per evitare questa spiacevolezza, ti consiglio di digitare il puntatore a funzione in qualcosa di più leggibile.Per esempio.

typedef void (*functiontype)();

Dichiara una funzione che restituisce void e non accetta argomenti.Per creare un puntatore a funzione di questo tipo ora puoi fare:

void dosomething() { }

functiontype func = &dosomething;
func();

Per una funzione che restituisce un int e accetta un carattere lo faresti

typedef int (*functiontype2)(char);

e per usarlo

int dosomethingwithchar(char a) { return 1; }

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

Esistono librerie che possono aiutare a trasformare i puntatori a funzione in tipi leggibili.IL funzione di potenziamento la biblioteca è fantastica e vale la pena!

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

è molto più bello di quanto sopra.

A partire da C++11 è possibile utilizzare il file libreria funzionale farlo in modo conciso e generico.La sintassi è, ad esempio,

std::function<bool (int)>

Dove bool è il tipo restituito in questo caso di una funzione con un argomento il cui primo argomento è di tipo int.

Ho incluso un programma di esempio qui sotto:

// 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 volte, però, è più conveniente utilizzare una funzione modello:

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

Passaggio indirizzo di una funzione come parametro di un'altra funzione come mostrato di seguito

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

Inoltre possiamo passare la funzione come parametro utilizzando puntatore di funzione

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

Devi superare a puntatore di funzione.La sintassi è un po' macchinosa, ma diventa davvero potente una volta presa familiarità con essa.

Le funzioni possono essere "passate" come puntatori a funzioni, come da 6.7.6.3p8:"Una dichiarazione di un parametro come "tipo di restituzione della funzione" deve essere modificata in "puntatore al tipo di restituzione della funzione", come in 6.3.2.1. ".Ad esempio, questo:

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

è equivalente a questo:

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

Non è realmente una funzione, ma è un pezzo di codice localizzato.Ovviamente non passa il codice ma solo il risultato.Non funzionerà se passato a un dispatcher di eventi per essere eseguito in un secondo momento (poiché il risultato viene calcolato ora e non quando si verifica l'evento).Ma localizza il tuo codice in un unico posto se questo è tutto ciò che stai cercando di fare.

#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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top