Funktion auf mehrere dateien verpacken- wo fehler?



  • Eigentlich Frage ich andauernd ungern, weil es den Eindruck erweckt als verstehe ich nichts, aber nun habe ich ein weiteres Problem^^
    Und zwar funktinierte meine Ableitungsfunktion bis eben. Nun will ich Sie aber auf mehrere dateien verpacken da ich sie für weitere Zwecke noch brauche.
    Daher habe ich nun folgendes:

    naeherung.cpp:
    #include <iostream>
    #include <conio.h>
    #include "ableitung.h"
    using namespace std;
    int main(void)
    {
        int grad = 2;
        double koeff[3] = {2, 3};
        ableitung(grad, koeff);
        return 0;
    }
    
    ableitung.h:
    int ableitung(int grad, double *koeff);
    
    ableitung.cpp:
    #include <iostream>
    #include "ableitung.h"
    /* 
    Diese Funktion führt die eigentliche Ableitung durch.
    Es müssen hier zwei Parameter übergeben werden:
    Der Grad der Funktion und die Koeffizienten.
    */
    int ableitung(int grad, double *koeff)
    {
        double koeffA[grad];
        int i;
        for(i=0;i<grad;i++)
        {
         koeffA[i]=(grad - i)*koeff[i];
         cout << "+" << koeffA[i] << "x^" << grad-i-1;
        }
    }
    

    Mein Fehler liegt nun laut Compiler in der cout-Zeile der ableitung.cpp. Als fehlermeldung wird gesagt 15 D:Desktop-Savec++Aufträge + Übungen



  • Schreib einfach using namespace std; auch bei ableitung.cpp mit rein.



  • Super 🙂 danke 🙂

    Nun gibt die Funktion ja eine ausgabe zurück mittels:
    cout << "+" << koeffA[i] << "x^" << grad-i-1;

    ich möchte aber lediglich die Variable und die Array weiterverarbeiten in einer anderen Funktion. Wie mache ich das am besten?
    Ich habe an return koeffA[i], grad;
    gedacht aber dann gibt er nichts aus. Ich vermute weil ja i keinen wert hat. Also müsste man es mit einer for-schleife wieder machen, aber darf ich in return eine for-schleifen verwenden?
    In den anderen Funktionen muss ich jede Zahl des Array einzeln wieder verarbeiten.



  • Du kannst mit return nur einen Wert zurückgeben. Du brauchst doch eigentlich sowieso nur koeffA. Hier würde sich anbieten koeffA der Funktion ableitung gleich mit zu übergeben.

    int ableitung(int grad, double *koeff, double *koeffA)
    {
        for(int i=0; i<grad; i++)
        {
           koeffA[i]=(grad - i)*koeff[i];
        }
    }
    

    Vielleicht solltest du dir auch mal std::vector ansehen.



  • mhm.. also ich hab die ableitung.cpp nun so gestalltet:

    double ableitung(int grad, double *koeff, double *koeffA)
    {
        double koeffA[grad];
        int i;
        for(i=0;i<grad;i++)
        {
         koeffA[i]=(grad - i)*koeff[i];
        }
        return 0;
    }
    

    Und meine naeherung so:

    ...
        //Funktion zum Ableiten
        ableitung(grad, koeff);
    
        for(int i=0;i<grad;i++)
        {
         koeffA[i]=(grad - i)*koeff[i];
         cout << koeffA[i];
        }
        getch();
        return 0;
    

    Bekomme nun aber eine Fehlermeldung: koeffA undeclared! Muss ich koeffA in beiden cpp's neu deklarieren oder wie jetzt, dachte ich kann den so mit übergeben?



  • Schau dir bitte meine Variante von Ableitung nochmal an.
    Ableitung dann so

    double koeffA[grad];
    ableitung(grad, koeff, koeffA);
    


  • Wie kann ich in C++ eigentlich Brüche auswerten? Ist für mathematische Funktionen ja wichtig weil wenn ich 3*0,3333 schreibe ist es nicht das gleiche wie 3*1/3. Naja gut, mathematisch bewiesen schon, aber der PC gibt halt 0,9999 aus und nicht 1. Also, wie kann ich Brüche darstellen und verwerten?



  • Schreib dir am Besten deine eigene Klasse CBruch. Oder such ob du so eine irgendwo findest.



  • ich weiß zwar noch nicht wie, aber ich behalte es mal im hinterstübchen.

    Ich hab nun ein neues Problem und zwar folgende Fehlermeldungen mit denen ich nichts anfangen kann:

    [Linker error] undefined reference to `naeherung(int, double*, double*)'
    ld returned 1 exit status
    D:\Desktop-Save\c++\Aufträge + Übungen\08. Newton Näherungsverfahren\näherung\Makefile.win [Build Error] [Naeherungsverfahren.exe] Error 1

    Die kamen zu stande als ich meine überarbeitete Version compilieren wollte. Neu ist lediglich eine neue funktion die werte normal übergeben bekommt..
    Ich hab auch gleich return 0; probiert aber trotzdem gibt ein eRROR.
    Meine Funktion sieht so aus: naeherungsverfahren.cpp:

    #include <iostream>
    #include "ableitung.h"
    using namespace std;
    /* 
    Diese Funktion führt das Newton'sche Näherungsverfahren durch
    */
    double naeherung(int grad, double *koeff, double *koeffA, double xnull)
    {
           double fx[grad];
           double fxA[grad];
           double fxz;
           double fxAz;
           double fxzz;
           double xeins;
           int b;
           for (int i=0;i<grad;i++)
           {
    
           fxA[i]=xnull*koeffA[i];
           potenz(koeffA[i], grad);
           }
           return 0;
    }
    

    ableitung.h:

    double ableitung(int grad, double *koeff, double *koeffA);
    void potenz(double b, double e);
    double naeherung(int grad, double *koeff, double *koeffA, double xnull);
    

    naherung (dient zur eingabe):

    #include <iostream>
    #include <conio.h>
    #include "ableitung.h"
    using namespace std;
    /*Diese Funktion fragt lediglich alle Einzugebenen Daten ab.
    grad steht für den Grad der Funktion.
    koeff reserviert den Platz für die Koeffizienten, die Anzahl ist ja vom Grad abhängig.
    xnull steht für den Startwert.
    */
    int main(void)
    {
        char r;
        int grad;
        double koeff[grad];
    
        //Die Eingabe des Grades und der Koeffizienten kann ggf. wiederholt werden
        do
        {
         int i;
         cout << "Bitte geben Sie den Grad der Funktion ein: ";
         cin >> grad;
         cout << "Bitte geben Sie jetzt die Koeffizienten ein (absteigende Reihenfolge der Exponenten und 0 beachten): " << endl;
    
         //Eingabe der Koeffizienten, bedingt durch den Grad der Funktion
         for(i=0;i<grad;i++)
         {
          cin >> koeff[i];
         }
         cout << "Ist das Ihre Funktionsgleichung: ";
    
         //Ausgabe der Koeffizienten, bedingt durch den Grad der Funktion
         for (i=0;i<grad;i++)
         { 
           cout << "+" << koeff[i] << "x^" << grad - i; 
         }
         cout << "? Wenn ja geben sie j ein und bestaetigen Sie mit Enter. Anderfalls geben Sie bitte n ein und bestaetigen dies: ";
         cin >> r;
        }while(r=='n');
        //Wenn die ausgegebene Funktionsgleichung mit der des Benutzers übereinstimmt geht es hier weiter, anderfalls wird die Eingabe wiederholt.
    
        //Eingabe des Startwertes
        double xnull;
        cout << "Bitte geben Sie den Startwert x0 fuer die Naeherung an: ";
        cin >> xnull;
    
        //Funktion zum Ableiten
        double koeffA[grad];
        ableitung(grad, koeff, koeffA);
    
        //Ausgabe der abgeleiteten Koeffizienten
        cout << endl << "Die abgeleiteten Koeffizienten sind: ";
        for(int i=0;i<grad;i++)
        {
         koeffA[i]=(grad - i)*koeff[i];
         cout << koeffA[i] << ", ";
        }
    
        //Funktion zum Nähern
        naeherung(grad, koeff, koeffA);
        int e;
        char re;
        do
        {
         cout << endl << "Moechten Sie die Naeherung erneut durchfuehren um ein exakteres Ergebnis zu erhalten? Wenn ja geben sie j ein und bestaetigen Sie mit Enter. Anderfalls geben Sie bitte n ein und bestaetigen dies: ";
         cin >> re;
        }while(re=='j');
        // cout << fxAz << ", " << fxz;
        getch();
        return 0;
    }
    

    ableitung.cpp (leitet ab):

    #include <iostream>
    #include "ableitung.h"
    using namespace std;
    /* 
    Diese Funktion führt die eigentliche Ableitung durch.
    Es müssen hier zwei Parameter übergeben werden:
    Der Grad der Funktion und die Koeffizienten.
    */
    double ableitung(int grad, double *koeff, double *koeffA)
    {
        int i;
        for(i=0;i<grad;i++)
        {
         koeffA[i]=(grad - i)*koeff[i];
        }
        return 0;
    }
    

    potenz.cpp (zum potenzieren):

    #include <iostream>
    using namespace std;
    double potenz(double b, double e)
    {
    
            int i;
            double be = b;
            for(i=0; i<e-1; i++)
            {
            be=b*be;
            }
            return be;
    }
    


  • Kontrollier mal die Anzahl der Parameter von naeherung bei Deklaration und bei Anwendung.
    Bei Potenz muß der zweite Parameter (Exponent) übrigens int sein sonst macht deine Schleife keinen Sinn.
    Ansonsten schau dir mal pow aus der cmath an.



  • Du hast anscheinend einen Parameter vergessen (und irgendwo in deinen Headern findet der Compiler noch die 3-Parameter-Version), als du die Funktion naeherung() aufgerufen hast - richtig lautet das "naeherung(grad, koeff, koeffA, xnull);"

    (PS: Und die Funktion sollte eigentlich auch die berechnete Nullstelle zurückgeben)



  • bei der potenzierfunktion sag ich ja return be;
    wie kann ich diesen wert nun in den anderen funktionen verwenden?
    einfach be als variable nutze?

    Was ist denn pow? Wo kann man die Inhalte der cmath und allen anderen bibliotheken einsehen?
    ---
    Ich habe die Parameter nun angepasst und folgende änderung vorgenommen:
    naeherung.cpp:

    //Funktion zum Nähern
        naeherung(grad, koeff, koeffA, xnull);
    
        cout << fxAz <<;
    

    näherungsverfahren.cpp:

    #include <iostream>
    #include "ableitung.h"
    using namespace std;
    /* 
    Diese Funktion führt das Newton'sche Näherungsverfahren durch
    */
    double naeherung(int grad, double *koeff, double *koeffA, double xnull)
    {
           double fx[grad];
           double fxA[grad];
           double fxz;
           double fxAz;
           double fxzz;
           double xeins;
           for (int i=0;i<grad;i++)
           {
           potenz(xnull, grad);
           fxA[i]=koeffA[i]*be;
           fxAz+=fxA[i];
           }
           return fxAz;
    }
    

    Aber ich kann trotzdem die Variable fxAz nicht ausgeben, was ich ja oben mit cout << fxAz <<; versuche...



  • t1m0n schrieb:

    bei der potenzierfunktion sag ich ja return be;
    wie kann ich diesen wert nun in den anderen funktionen verwenden?
    einfach be als variable nutze?

    Indem du das Ergebnis einer Variablen zuweist:

    double xn=potenz(x,n);
    

    (btw stimmt was nicht mit der Definition - der Header sagt "void potenz(...)", die Implementation verwendet "double potenz(...)")

    PS: Die Informationen zur Standard-Bibliothek findest du z.B. in den Manuals deines Compilers oder unter http://www.cppreference.com



  • Ausgabe bitte so

    cout << naeherung(grad, koeff, koeffA, xnull);
    

    Schau dir bitte ein Tutorial zu Funktionen an.
    z.Bsp. hier
    http://www.volkard.de/vcppkold/funktionen.html
    oder hier
    http://tutorial.schornboeck.net/funktionen2.htm
    oder...



  • Ich habs nun etwas merkwürdiger gemacht:

    double naeherung(int grad, double *koeff, double *koeffA, double xnull)
    {
           double fx[grad];
           double fxA[grad];
           double fxz;
           double fxAz;
           double fxzz;
           double xeins;
           for (int i=0;i<grad;i++)
           {
           fxA[i]=koeffA[i]*potenz(xnull, grad);
           fxAz+=fxA[i];
           }
           return fxAz;
    }
    

    Dann hab ich in der naeherung.cpp

    cout << naeherung(grad, koeff, koeffA, xnull);
    

    gemacht.
    Nun klappt alles soweit aber ich habe einen logischen fehler drinne (so heißt das doch oder?)
    Laut meinen Berechnungen müsste ich 14 herausbekommen, bekomme aber 28...
    Kennt sich jemand mit dem newton'schen näherungsverfahren aus udn kann mir da sagen was ich falsch habe?
    ---Aktuell sieht alles so aus:---

    naeherung.cpp:

    #include <iostream>
    #include <conio.h>
    #include "ableitung.h"
    using namespace std;
    /*Diese Funktion fragt lediglich alle Einzugebenen Daten ab.
    grad steht für den Grad der Funktion.
    koeff reserviert den Platz für die Koeffizienten, die Anzahl ist ja vom Grad abhängig.
    xnull steht für den Startwert.
    */
    int main(void)
    {
        char r;
        int grad;
        double koeff[grad];
    
        //Die Eingabe des Grades und der Koeffizienten kann ggf. wiederholt werden
        do
        {
         int i;
         cout << "Bitte geben Sie den Grad der Funktion ein: ";
         cin >> grad;
         cout << "Bitte geben Sie jetzt die Koeffizienten ein (absteigende Reihenfolge der Exponenten und 0 beachten): " << endl;
    
         //Eingabe der Koeffizienten, bedingt durch den Grad der Funktion
         for(i=0;i<grad;i++)
         {
          cin >> koeff[i];
         }
         cout << "Ist das Ihre Funktionsgleichung: ";
    
         //Ausgabe der Koeffizienten, bedingt durch den Grad der Funktion
         for (i=0;i<grad;i++)
         { 
           cout << "+" << koeff[i] << "x^" << grad - i; 
         }
         cout << "? Wenn ja geben sie j ein und bestaetigen Sie mit Enter. Anderfalls geben Sie bitte n ein und bestaetigen dies: ";
         cin >> r;
        }while(r=='n');
        //Wenn die ausgegebene Funktionsgleichung mit der des Benutzers übereinstimmt geht es hier weiter, anderfalls wird die Eingabe wiederholt.
    
        //Eingabe des Startwertes
        double xnull;
        cout << "Bitte geben Sie den Startwert x0 fuer die Naeherung an: ";
        cin >> xnull;
    
        //Funktion zum Ableiten
        double koeffA[grad];
        ableitung(grad, koeff, koeffA);
    
        //Ausgabe der abgeleiteten Koeffizienten
        cout << endl << "Die abgeleiteten Koeffizienten sind: ";
        for(int i=0;i<grad;i++)
        {
         koeffA[i]=(grad - i)*koeff[i];
         cout << koeffA[i] << ", ";
        }
    
        //Funktion zum Nähern
        cout << naeherung(grad, koeff, koeffA, xnull);
        /*
        char re;
        do
        {
         cout << endl << "Moechten Sie die Naeherung erneut durchfuehren um ein exakteres Ergebnis zu erhalten? Wenn ja geben sie j ein und bestaetigen Sie mit Enter. Anderfalls geben Sie bitte n ein und bestaetigen dies: ";
         cin >> re;
        }while(re=='j');
        */
        getch();
        return 0;
    }
    

    ableitung.h:

    double ableitung(int grad, double *koeff, double *koeffA);
    double potenz(double b, int e);
    double naeherung(int grad, double *koeff, double *koeffA, double xnull);
    

    ableitung.cpp:
    #include <iostream>
    #include "ableitung.h"
    using namespace std;
    /*
    Diese Funktion führt die eigentliche Ableitung durch.
    Es müssen hier zwei Parameter übergeben werden:
    Der Grad der Funktion und die Koeffizienten.
    */
    double ableitung(int grad, double *koeff, double *koeffA)
    {
    int i;
    for(i=0;i<grad;i++)
    {
    koeffA[i]=(grad - i)*koeff[i];
    }
    return 0;
    }
    potenz.cpp:

    #include <iostream>
    using namespace std;
    double potenz(double b, int e)
    {
    
            int i;
            double be = b;
            for(i=0; i<e-1; i++)
            {
            be=b*be;
            }
            return be;
    }
    

    Naherung.cpp:

    #include <iostream>
    #include "ableitung.h"
    using namespace std;
    /* 
    Diese Funktion führt das Newton'sche Näherungsverfahren durch
    */
    double naeherung(int grad, double *koeff, double *koeffA, double xnull)
    {
           double fx[grad];
           double fxA[grad];
           double fxz;
           double fxAz;
           double fxzz;
           double xeins;
           for (int i=0;i<grad;i++)
           {
           fxA[i]=koeffA[i]*potenz(xnull, grad);
           fxAz+=fxA[i];
           }
           return fxAz;
    }
    


  • Erstmal hast du da ein ganzes Paket überflüssiger Variablen drin.

    Zweitens solltest du lieber potenz(xnull,i) oder potenz(xnull,grad-i) verwenden (je nachdem, in welcher Reihenfolge die Koeffizienten in dem Vektor stehen).

    Und drittens bin ich mir nicht sicher, was du damit eigentlich berechnen willst - die Funktion hat nichts mit dem Newton-Verfahren zu tun, sondern berechnet lediglich f'(xnull) für deine "mögliche Nullstelle" xnull.



  • Desweiteren ist fxAz in der Funktion nicht initialisiert. Da kann also irgendwas drinstehen.
    Newton wäre doch
    x1 = x0 - f(x0)/f'(x0) (kenn mich mit LATEX leider nicht so aus)
    und das iterativ.



  • Braunstein schrieb:

    Desweiteren ist fxAz in der Funktion nicht initialisiert. Da kann also irgendwas drinstehen.
    Newton wäre doch
    x1 = x0 - f(x0)/f'(x0) (kenn mich mit LATEX leider nicht so aus)
    und das iterativ.

    ja genau, aber ich brauche ja erst die f'x und die fx für die berechnung. Und die müssen ja erstmal berechnet werden und das verscuhe ich gerade..



  • while(/*hier ein passendes Abbruchkriterium einsetzen*/)
    {
      double fx=0,fxA=0;
      for(int i=0;i<=grad;++i)
      {
        double p=potenz(xnull,i);
        fx +=koeff[i]*p;  //summiert f(x)
        fxA+=koeffA[i]*p; //summiert f'(x)
      }
      xnull=xnull-fx/fxA; //neuer Näherungswert
    }
    return xnull;
    

    Das wäre ein Ansatz - eventuell noch optimierungswürdig



  • Naja, das hier stimmt nicht so ganz

    fxA+=koeffA[i]*p;
    

    eher so

    fx +=koeff[i] * potenz(xnull,i);  //summiert f(x)
    if( i>0) fxA+=koeffA[i] * potenz(xnull,i-1); //summiert f'(x)
    

Log in to reply