STL-Container - Vector
-
Hi Leute!
Ich will hier ein kleines Programm schreiben, dass mir den Mittelwert von Werten berechnet, welche der Benutzer eingeben muss. Nun benutze ich "vector". Der sollte sich ja eigentlich dynamisch zur Laufzeit vergrößern, wenn mehr Werte eingegeben werden, als bei der Initialisierung angegeben worden sind. Wenn ich mein noch nicht ganz fertiges Programm laufen lasse, dann funktioniert alles bis zum zehnten Wert Einwandfrei, wenn man aber den 11. Wert eingibt schmeißt mir das Programm einen Fehler. Ich weiß aber leider nicht warum...
#include<iostream> #include<vector> using namespace std; int main() { int anzahl = 0, i = 0, c = 0; vector<double> wert(10); cout << "Mittelwert-Berechnung" << endl << endl; do { cout << i+1 << ". Wert angeben: "; c = cin.peek(); if(c != 'e') { cin >> wert[i]; char cend = cin.get(); i++; } } while(c != 'e'); return 0; }
-
Der vector vergrößert sich nur, wenn du explizit durch ein push_back etwas anhängst. Mit dem Array-Operator können keine Elemente hinzugefügt werden.
-
vip@r schrieb:
Nun benutze ich "vector". Der sollte sich ja eigentlich dynamisch zur Laufzeit vergrößern, wenn mehr Werte eingegeben werden, als bei der Initialisierung angegeben worden sind.
Wie jeder andere Container vergrößert sich ein vector dann, wenn du Elemente audrücklich einfügst. Bei einem Zugriff auf ein ganz bestimmtes Element ist es hingegen deine Aufgabe dafür zu sorgen, dass dieses Element überhaupt existiert.
Anstatt also dem vector eine bestimmte Anfangsgröße zu geben, solltest du ihn zunächst einmal leer lassen und dann mit jeder Eingabe ein Element hinzufügen (push_back).
-
314159265358979 schrieb:
Der vector vergrößert sich nur, wenn du explizit durch ein push_back etwas anhängst.
Genau gesagt erzeugt dein Code undefiniertes Verhalten. Der Feldoperator liest/schreibt ohne eine Bereichsprüfung. Nutze
vector::resizeodervector::push_backum ihn zu vergrössern.
-
Wie soll man das dann machen? Muss ich dann quasi die zehn Iterationen der do-while-Schleife abzählen und dann das push_back ausführen?
-
vip@r schrieb:
Wie soll man das dann machen? Muss ich dann quasi die zehn Iterationen der do-while-Schleife abzählen und dann das push_back ausführen?
Warum fängst du denn überhaupt mit 10 Elementen an?
-
vip@r schrieb:
Wie soll man das dann machen?
Statt
cin >> wert[i];schreibst du einfach:int Temp; cin >> Temp; wert.push_back(Temp);
-
vector<double> werte; ... do ... int einzelwert; cin >> einzelwert; werte.push_back( einzelwert ); ...
-
Nein, du liest den Wert innerhalb der Schleife in eine Variable ein und wirfst diese dann per push_back() in den vector<>
double wert; cin>>wert; werte.push_back(wert);
-
Hm, soweit funktioniert das jetzt. Nun möchte ich noch eine Funktion schreiben, die mir den Mittelwert berechnet. Wie übergebe ich nun am besten den Vector an die Funktion?
-
Am besten als const-Ref.
Aber wieso selber schreiben - die einfachste Lösung wäre std::accumulate()
-
In meinem C++-Buch finde ich leider keine Informationen zu accumulate()...
Kannst du mir noch ein bisschen draufhelfen?
-
-
google und die referenzen sind dein Freund:
-
Den Vector mit Zeigern oder mit einer der Standardmethoden an dei Funktion übergeben ist wohl nicht möglich?
-
vector::begin() und vector::end()

-
vip@r schrieb:
Den Vector mit Zeigern oder mit einer der Standardmethoden an dei Funktion übergeben ist wohl nicht möglich?
Klar ist es möglich, aber ist nicht sinnvoll (Übergabe als Kopie wird recht aufwendig wenn der vector<> größer wird, Übergabe als Pointer ist ein Relikt aus C-Zeiten).
-
Hm, gut. Dann ist hier wohl das an eine Funktion übergeben wohl wirklich nicht so der bringer.
Aber: Ich verstehe irgendwie nicht, dass C++ hier quasi "verweigert", bzw. es anscheinend sehr schwer macht den Vector an eine Funktion zu übergeben und in der dann den Vector mit einer for-Schleife auslesen und dann eben die Werte aufaddieren und durch 2 zu teilen.
So, wie ich das verstanden habe, benötige ich ja für accumulate() auch noch Iteratore von denen ich widerum (noch) nicht weiß wie das gehen soll...
-
vip@r schrieb:
Hm, gut. Dann ist hier wohl das an eine Funktion übergeben wohl wirklich nicht so der bringer.
Aber: Ich verstehe irgendwie nicht, dass C++ hier quasi "verweigert", bzw. es anscheinend sehr schwer macht den Vector an eine Funktion zu übergeben und in der dann den Vector mit einer for-Schleife auslesen und dann eben die Werte aufaddieren und durch 2 zu teilen.
Was heißt hier "verweigert"? Es ist möglich, vector<>en zu kopieren, du mußt nur damit rechnen, daß dort eine ganze Menge Daten zusammenkommt. Deshalb verwendet man da lieber eine (const) Referenz.
So, wie ich das verstanden habe, benötige ich ja für accumulate() auch noch Iteratore von denen ich widerum (noch) nicht weiß wie das gehen soll...
Iteratoren sind eine Abstraktion, damit die Algorithmen nicht für jeden Container neu angepasst werden müssen (außerdem kannst du mit ihnen auch blanke Arrays oder Teilbereiche deines Containers beschreiben). Und die STL-Containerklassen bieten die Methoden begin() und end(), um Iteratoren für alle Elemente zu ermitteln:
double mv = accumulate(werte.begin(),werte.end(),0.0) / werte.size();
-
Ich hab jetzt mal versucht die Mittelwertberechnung ohne Funktion zu realisieren. Dabei ist mir nun folgendes aufgefallen. Wenn der Zähler der for-Schleife auf 0 steht, dann adressiert er mir ja das Element 0 im Vector. Nur steht da eine 0 obwohl ich für das 0-te-Element eine andere Zahl als 0 eingegeben habe...
Hier der Code:
#include<iostream> #include<vector> #include<numeric> using namespace std; //void mittelwert(vector<double>* werte) //{ // int i, anzahl; // // anzahl = werte[i]; // //} int main() { int anzahl = 0, c = 0; int wert = 0, summe = 0, ergebnis = 0; vector<double> werte(1); cout << "Mittelwert-Berechnung" << endl << endl; do { cout << anzahl+1 << ". Wert angeben: "; c = cin.peek(); if(c != 'e') { cin >> wert; werte.push_back(wert); char cend = cin.get(); anzahl++; } } while(c != 'e'); cout << werte[3]; for(int i=0; i<anzahl; i=i+1) { summe = summe + werte[i]; } ergebnis = summe / anzahl; return 0; }