Frage

Ich möchte eine Funktion erstellen, die eine per Parameter übergebene Funktion für einen Datensatz ausführt.Wie übergibt man in C eine Funktion als Parameter?

War es hilfreich?

Lösung

Erklärung

Ein Prototyp für eine Funktion, die einen Funktionsparameter entgegennimmt, sieht wie folgt aus:

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

Dies besagt, dass der Parameter f wird ein Zeiger auf eine Funktion sein, die a hat void Rückgabetyp und der einen Single benötigt int Parameter.Die folgende Funktion (print) ist ein Beispiel für eine Funktion, an die übergeben werden könnte func als Parameter, weil es der richtige Typ ist:

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

Funktionsaufruf

Beim Aufruf einer Funktion mit einem Funktionsparameter muss der übergebene Wert ein Zeiger auf eine Funktion sein.Verwenden Sie dazu den Namen der Funktion (ohne Klammern):

func(print);

würde nennen func, und übergibt ihm die Druckfunktion.

Funktionskörper

Wie bei jedem Parameter kann func nun den Namen des Parameters im Funktionskörper verwenden, um auf den Wert des Parameters zuzugreifen.Nehmen wir an, dass func die übergebene Funktion auf die Zahlen 0-4 anwendet.Überlegen Sie zunächst, wie die Schleife aussehen würde, um print direkt aufzurufen:

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

Seit funcDie Parameterdeklaration sagt das f ist der Name für einen Zeiger auf die gewünschte Funktion. Wir erinnern uns zunächst daran, dass if f ist dann ein Zeiger *f ist die Sache, die f zeigt auf (d. h.die Funktion print in diesem Fall).Ersetzen Sie daher einfach jedes Vorkommen von print in der Schleife oben durch *f:

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

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

Andere Tipps

Auf diese Frage gibt es bereits die Antwort zum Definieren von Funktionszeigern. Sie können jedoch sehr chaotisch werden, insbesondere wenn Sie sie in Ihrer Anwendung weitergeben.Um diese Unannehmlichkeiten zu vermeiden, würde ich empfehlen, dass Sie den Funktionszeiger in eine besser lesbare Form eingeben.Zum Beispiel.

typedef void (*functiontype)();

Deklariert eine Funktion, die void zurückgibt und keine Argumente akzeptiert.Um einen Funktionszeiger auf diesen Typ zu erstellen, können Sie jetzt Folgendes tun:

void dosomething() { }

functiontype func = &dosomething;
func();

Für eine Funktion, die ein int zurückgibt und ein char akzeptiert, würden Sie Folgendes tun

typedef int (*functiontype2)(char);

und es zu nutzen

int dosomethingwithchar(char a) { return 1; }

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

Es gibt Bibliotheken, die dabei helfen können, Funktionszeiger in gut lesbare Typen umzuwandeln.Der Boost-Funktion Die Bibliothek ist großartig und die Mühe lohnt sich!

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

ist so viel schöner als das oben.

Seit C++11 können Sie das verwenden funktionale Bibliothek dies auf prägnante und allgemeine Weise zu tun.Die Syntax ist z.B.

std::function<bool (int)>

Wo bool ist hier der Rückgabetyp einer Funktion mit einem Argument, deren erstes Argument vom Typ ist int.

Ich habe unten ein Beispielprogramm eingefügt:

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

Manchmal ist es jedoch bequemer, eine Vorlagenfunktion zu verwenden:

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

Passieren Adresse einer Funktion als Parameter für eine andere Funktion Wie nachfolgend dargestellt

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

Wir können die Funktion auch als Parameter übergeben Funktionszeiger

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

Sie müssen eine bestehen Funktionszeiger.Die Syntax ist etwas umständlich, aber sie ist wirklich leistungsstark, wenn man sich erst einmal damit vertraut macht.

Funktionen können gemäß 6.7.6.3p8 als Funktionszeiger „übergeben“ werden:"Eine Deklaration eines Parameters als „Funktionsrückgabetyp“ muss wie in 6.3.2.1 in „Zeiger auf Funktionsrückgabetyp“ angepasst werden. ".Zum Beispiel dies:

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

ist äquivalent dazu:

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

Es handelt sich nicht wirklich um eine Funktion, sondern um einen lokalisierten Code.Natürlich wird nicht der Code, sondern nur das Ergebnis übergeben.Es funktioniert nicht, wenn es an einen Ereignis-Dispatcher übergeben wird, um es zu einem späteren Zeitpunkt auszuführen (da das Ergebnis jetzt berechnet wird und nicht, wenn das Ereignis auftritt).Aber es lokalisiert Ihren Code an einem Ort, wenn das alles ist, was Sie versuchen.

#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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top