Wie Funktion an Funktion weitergeben?



  • Hallo,
    bin neu in Sachen C++ und habe gerade einen kleinen Integrator geschrieben der auch soweit funktioniert. Allerdings hat mein Programm zur Zeit noch folgende Struktur

    main
    {
        Aufruf von Integrator und Weitergabe von Integralanfang, Integralende an    
        Integrator.
    }
    
    Integrator(Integralanfang, Integralende)
    {
       Integrieren der Funktion func1 und Rückgabe des Ergebnisses.
    }
    
    func1(xwert)
    {
       Rückgabe des Funktionswertes von func1 an der Stelle xwert.
    }
    

    Jetzt würde ich das ganze gerne so gestalten, dass ich die zu integrierende Funktion direkt an Integrator beim Aufruf als Argument übergeben kann, also

    Integrator (Integralanfang, Integralende, zu integrierende Funktion)
    

    Damit hätte ich dann eine universell einsetzbare Integratorfunktion, die ich dann hoffentlich auch in zukünftigen Programmen nutzen kann und ich könnte auch mehrere Funktionen problemlos hintereinander integrieren.
    Da ich gerade erst mit c++ angefangen habe, gestaltet sich das ganze für mich noch etwas schwierig, ich wäre für Hilfe dankbar 🙂



  • Entweder als Funktionszeiger (Google wird dir dazu viel ausspucken), oder über templates.

    Ich hoffe aber dir ist klar, dass man nicht einfach eine C++-Funktion integrieren kann.
    Denn eine C++-Funktion ist was ganz anderes als eine mathematische Funktion. Gilt nicht nur für C++ sondern für so ziemlich jede Programmiersprache.



  • Du kannst Funktionszeiger einsetzen. Ich nehme mal an, die Funktion hat z.B. so eine Signatur:

    float f(float x);
    

    Dann deklarierst du einen Zeiger auf diesen Funktionstyp folgendermassen:

    float (*fptr)(float) = &f;
    

    Nützlich ist auch diese Seite. Wenn du dich nicht auf globale Funktionen mit exakt gleicher Signatur beschränkten willst, kannst du verallgemeinerte Callable-Objekte mit std::tr1::function (oder boost::function ) realisieren. So könntest du zum Beispiel auch Memberfunktionen oder Funktoren (Funktionsobjekte) behandeln.

    std::tr1::function<float(float)> callable = &f;
    

    Edit:

    l'abra d'or schrieb:

    Ich hoffe aber dir ist klar, dass man nicht einfach eine C++-Funktion integrieren kann.

    Wahrscheinlich hat er ein diskretes Integral (Summe), schliesslich muss man für ein bestimmtes Integral nicht zwingend eine Stammfunktion berechnen. Aber ist nur so eine Vermutung...



  • Danke!
    Wie würde ich dann denn die Funktion Integrator aufrufen?
    mit

    Integrator ( Integralanfang, Integralende, *fptr )
    

    ?

    Gibt es auch eine Möglichkeit, das Ganze ohne Zeiger sondern mit Referenzen zu regeln? Ich hab mich mit Zeigern noch nicht so ganz angefreundet, Referenzen funktionieren schon etwas besser 🙂



  • kaesekuchen86 schrieb:

    Wie würde ich dann denn die Funktion Integrator aufrufen?
    mit

    Integrator ( Integralanfang, Integralende, *fptr )
    

    Nein, einfach den Zeiger übergeben. Innerhalb der Funktion kannst du die ganz normale Aufrufsyntax verwenden. typedef kann dir die Syntax ein wenig vereinfachen.

    Das steht übrigens alles im Link.

    kaesekuchen86 schrieb:

    Ich hab mich mit Zeigern noch nicht so ganz angefreundet, Referenzen funktionieren schon etwas besser 🙂

    Du störst dich nicht im Ernst am Sternchen? Zeiger sind hier absolut kein Problem. Und du solltest dich lieber schnell mit ihnen anfreunden, sonst kommst du in C++ nicht weit. In diesem Artikel findest du eine gute Einführung zu Zeigern.



  • Vielen Dank, hat funktioniert! Super Forum, ging ja ruckzuck 🙂
    Werd mich morgen mal in die Zeiger genauer einlesen, aber danke schonmal für die Links.



  • Am besten machst du das über ein Template, dann kann der Aufruf von f(i) geinlined werden. function<...> lohnt sich imho nur, wenn man die Funktion speichern will.

    template<typename Func>
    double integrate(Func f, double begin, double end) {
      // ...
      f(i);
      // ...
    }
    
    int main() {
      // ..
      integrate(func1, x, y);
    }
    

Anmelden zum Antworten