Probleme mit C++



  • Hallo,

    ich bin noch C++ Anfänger und muss mich jetzt damit auseinandersetzen.

    Ich habe 3 x-Werte, welche normiert werden müssen. Anschließend muss mit dem neuen xi-Werten weitergerechnet werden.

    Hier ist der aktuelle Code:

    [code]

    #include <iostream>
    #include <cmath>
    
    double norm(double summe, double xi);
    double  xi[4], summe;
    using namespace std;
    
    double norm(double *xi)
     {
       int i;
       for(i = 1; i <= 3; i++)
         summe += xi[i];
    	 xi[i] = xi[i]/summe;
       return  (xi, summe);
     }
    
    int main(){
    
    	xi[1] = 0.26;
    	xi[2] = 0.26;
    	xi[3] = 0.26;
    
    	norm( xi);
    	cout<<summe ;
    	cout <<"\n	xi1 = "<< xi[1];
    
    	cout << "\n\n Mit ENTER beenden!";
    
    	cin.sync();
    	cin.clear();
    	cin.get();
    return 0;
    }
    

    Die Frage ist, warum der ursprüngliche Wert von x1 ausgegeben wird und nicht der neu berechnete. Ein andere Frage ist, warum die Funktion nicht nach main() geschrieben werden kann.

    Vielen Dank für die Hilfe!

    mfg Rico

    p.s. Derzeit nutze ich VS 2010 express.



  • Zunächst einmal:
    Wenn du Arrays übergibst, dann musst du immer die Größe mit angeben.

    //Deklaration
    typ in_vect(typ vect[], int size); // Eindimensional
    typ in_matrix(typ matrix[][dim2], int size); // Mehrdimensional
    //Aufruf
    in_vect(typ *vect,sizeof(vect)/sizeof(vect[0]); //Eindimensional
    in_matrix(typ *matrix[dim2],dim1); // Mehrdimensioinal
    


  • Oha. Da ist eine ganze Menge falsch/komisch.

    - Komisch: Du deklarierst eine Funktion norm(double,double); welche nie wieder auftaucht
    - Komisch: Du definierst globale Variablen xi und summe
    - Falsch: Du setzt summe vorher nicht auf 0
    - Falsch: Du brauchst zwei Schleifen. Einmal für die Summe und ein zweites Mal für das Dividieren
    - Komisch: Du legst ein Array mit 4 Elementen an, benutzt aber nur drei



  • Man kann in C (C++ ist der Code nur in cout,cin) nur einen Datentyp zurückgeben:

    return  (xi, summe); // geht nich!
    

    Achte wie die Schleifen verlaufen müssen.

    #include <iostream>
    #include <cmath>
    
    void norm(double *xi,int size);
    double  xi[3], summe;
    using namespace std;
    
    void norm(double *xi,int size)
    {
    	for(int i = 0; i < size; i++){ summe += xi[i]; }
    	for(int i = 0; i < size; i++) { xi[i] /= summe; }
    }
    
    int main(){
    
    	xi[0] = 0.26; // Die erste Position im Array ist "0"
    	xi[1] = 0.26;
    	xi[2] = 0.26;
    
    	norm(xi,sizeof(xi)/sizeof(xi[0]));
    	// summe kannst du hier ausgeben weil sie oben global definiert ist.
    	cout << summe << '\n' << "xi[1] = " << xi[1] << '\n' << "Mit ENTER beenden!";
    
    	cin.sync();
    	cin.clear();
    	cin.get();
    	return 0;
    }
    


  • Am besten du gewöhnst dich gleich an std::vector, er ersetzt in den meisten Fällen das den *array.

    Sieht dann so aus:

    #include <iostream>
    #include <vector>
    
    void norm(std::vector<double> &xi);
    
    using namespace std;
    
    vector<double> xi;
    double summe;
    
    void norm(vector<double> &xi)
    {
    	vector<double>::iterator i;
    	for(i=xi.begin();i!=xi.end();i++){ summe += *i; } // ist es am besten
    
    	for(int j=0;j<xi.size();j++) {
    		xi[j] /= summe; // so geht das auch, wenn bereits werte vorhanden sind
    	}
    }
    
    int main(){
    
    	xi.push_back(1.23); // schiebe einen Wert in die letzte Position
    	xi.push_back(2.34);
    	xi.push_back(3.45);
    
    	norm(xi); //  keine größenangabe nötig
    
    	cout << "summe = " << summe << '\n';
    	cout << "xi[0] = " << xi.at(0) << '\n';
    	cout << "xi[2] = " << xi.at(2) << '\n';
    	cout << "Mit ENTER beenden!";
    
    	return 0;
    }
    


  • darkfate schrieb:

    Am besten du gewöhnst dich gleich an std::vector, er ersetzt in den meisten Fällen das den *array.

    Und übergibst diesen bitte nicht als Kopie, sondern je nach Anforderung als Referenz oder konstante Referenz. Und verwendest auch keine globalen Variablen.

    Nach noch ein paar Änderungen könnte dies wie folgt aussehen:

    #include <iostream>
    #include <vector>
    
    void norm(
        std::vector<double> & xi, // Soll geändert werden, daher Referenz
        double & summe);          // Soll geändert werden, daher Referenz
    
    int main()
    {
        std::vector<double> xi;
        xi.push_back(1.23);
        xi.push_back(2.34);
        xi.push_back(3.45);
    
        double summe = 0.0;
        norm(xi, summe);
    
        std::cout << summe << std::endl;
        std::cout << "xi[0] = " << xi[0];
        // ...
    } 
    
    void norm(
        std::vector<double> & xi,
        double & summe)
    {
        // Was auch immer der Sinn von dieser Funktion sein sollte, ich
        // behaupte, die Berechnung ist nicht so, wie der OP sich das
        // vorstellt (ZUDEM: Arrays etc. beginnen beim Index 0).
        for(int pos=0, size=xi.size(); pos<size; ++i) {
            summe += xi[pos];
            xi[pos] /= summe;
        }
    }
    


  • asc schrieb:

    Und übergibst diesen bitte nicht als Kopie, sondern je nach Anforderung als Referenz oder konstante Referenz. Und verwendest auch keine globalen Variablen.

    So grausam wollte ich erstmal nicht sein 🙂



  • darkfate schrieb:

    asc schrieb:

    Und übergibst diesen bitte nicht als Kopie, sondern je nach Anforderung als Referenz oder konstante Referenz. Und verwendest auch keine globalen Variablen.

    So grausam wollte ich erstmal nicht sein 🙂

    Nur ist dein Programm schlicht und ergreifend falsch. Da nur die summe (da global) dauerhaft geändert wird. Der Vektor wurde als Kopie übergeben, und nur diese Kopie (die am Ende der Funktion zerstört wird) wurde angepasst.



  • asc schrieb:

    Nur ist dein Programm schlicht und ergreifend falsch. Da nur die summe (da global) dauerhaft geändert wird. Der Vektor wurde als Kopie übergeben, und nur diese Kopie (die am Ende der Funktion zerstört wird) wurde angepasst.

    Stimmt, da fehlt ein & in der Funktion

    void norm(std::vector<double> &xi);
    

    und beim Aufruf

    void norm(vector<double> &xi){
    ...
    }
    

    Normieren tut aber dennoch richtig.



  • darkfate schrieb:

    Zunächst einmal:
    Wenn du Arrays übergibst, dann musst du immer die Größe mit angeben.

    Nicht wenn wie hier die Größe vorher schon festgelegt ist. Er weiß ja dass genau 3 Elemente drin sein sollen.

    Was hier ein problem ist:
    - du deklarierst eine Funktion norm(double, double) und definierst danach eine Funktion norm(double*), die eine andere Signatur hat! Wozu?
    - du definierst ein Array mit 4 Elementen obwohl du sagst du hast nur 3 - wozu? (das ist kein char-Array wo man ein Element mehr braucht für das abschließende '\0')
    - deine for-Schleife ist zwar eingerückt als solle sie über zwei Zeilen laufen, de facto läuft sie aber nur über die erste. -> Klammern setzen!
    - die Rückgabe der Funktion tut nicht was du erwartest. Wobei nicht klar ist, was du überhaupt erwartest. (xi, summe) hat den Wert von summe, weril beim Komma-Operator der wert des letzten Ausdrucks den Wert des gesamtausdrucks ergibt.
    - summe als globale variable ist ungünstig bzw. schlechtes Design. Noch dazu initialisierst du die Variable nirgends, es kann also alles mögliche bei rauskommen.

    Das alles zusammen sieht nicht so aus als ob du genau wüsstest was du tust. Hast du dir die zugehörigen Kapitel im Buch schon genau durchgelesen und verstanden?



  • pumuckl schrieb:

    - summe als globale variable ist ungünstig bzw. schlechtes Design. Noch dazu initialisierst du die Variable nirgends, es kann also alles mögliche bei rauskommen.

    Nicht deswegen "kann alles mögliche rauskommen". summe wird, nachdem das Programm in den Arbeitsspeicher geladen wurde, 0 sein. Es gibt aber woanders undefiniertes Verhalten...

    for(i = 1; i <= 3; i++)
      summe += xi[i];
      xi[i] = xi[i]/summe; // <-- gehört nicht zur Schleife, i ist 4.
    

    Denn xi[4] gibt es nicht.

    Alles in allem sind da ziemlich viele Würmer drin -- soviele, dass man nicht genau weiß, was das Programm eigentlich machen sollte.



  • Erst einmal vielen dank für die Antworten und Anregungen. Das Programm läuft jetzt wie gewünscht.
    Bei dem Programm handelt es sich um eine Konsolenanwendung, mit deren Hilfe Messdaten ausgewertet werden sollen. Die Anwendung enthält verschiedenen Ein- und Ausgaben sowie weitere Berechnungsschritte. Zur besseren Übersichtlichkeit habe ich diese aus dem Beispielcode entfernt. Wahrscheinlich daher die Unklarheiten bzw. auch einige Fehler. Ich werde bei der nächsten Fragestellung mehr zum Ziel der Anwendung schreiben. Das Hauptproblem war die for-Anweisung und damit die falschen Ergebnisse der weiteren Berechnungen.

    Danke.


Anmelden zum Antworten