Blöde Fragen zu itteratoren
-
Hi, Ich habe ein paar Fragen zu itteratoren.
Ich offe einfach dass es hier jemand schnell benatwortenkann. Eigenrecherche dauert immer etwas mahr zeit.=)
Also würd mich über Deine mühe freuen.
1.) Wenn ich eine schleife mache, und die so lange laufen lasse, bis der iterator den *.end() iterator erreicht hat, macht er dann eine Zuweisung, oder wirde jedes mal der *.end() iterator neu berechnet.
Wenn es nicht jedesmal neu berechnet wird, ist es laufzeiteffizienter.
Wenn es jedes mal neu berechnet wird, kann man den Kontainer mnipulieren während dem schleifendurchlauf.
2.) Wenn ich einen iterator auf das Element a setze, und dann b einfüge, ist dann der iterator immer noch auf a, oder ist es möglich, dass dann unter diesem iterator beim Zugriff auf b zugegriffen wird. ???Gruß Alex
-
das kommt immer darauf an, welchen container du verwendest
-
Hmm okay danke. Iteratoren und ich werden wohl nie die besten freund werden
Gruß
-
Also wenn du etwas Code hättest, könnten wir dir sagen, wo das Problem liegt.
-
Na Ja, Also das war eine generelle Frage zum Konzept.
Ich versuche Fehler vor dem programmieren zu vermeiden. (Selten aber das gibts noch)
Es existiert eine Idee für einen Algorithmus. Aber der manupuliert den
Kontainer beim durchlaufen. Bei Zeigern habe ich das Problem nicht. Die sind so lange eindeutig bis ich sie zerstöre.
Um ehrlich zu sein sind mir iteratoren ein bischen zu wässrig. Die sind zu undefiniert und zu lange zum schreiben. Ich weiß garnicht was mein Prozessor damit macht. Das mag ich garnicht, und schon zweimal nicht, wenn kein ordentliches konzept da ist. *auf iteratoren schipmf*
-
AlexXXx schrieb:
Wenn ich einen iterator auf das Element a setze, und dann b einfüge, ist dann der iterator immer noch auf a, oder ist es möglich, dass dann unter diesem iterator beim Zugriff auf b zugegriffen wird. ???
So?
#include <iostream> #include <vector> int main() { std::vector<int> vec; vec.push_back(10); vec.push_back(20); std::vector<int>::iterator it(vec.begin()); // it zeigt auf das erste Element von vec *it = vec[1]; std::cout<< *it; std::cin.get(); }
-
Wieman sieht ist das nicht durch den kompiler. Ich glaube es kommt rüber was ich meine
#include <iostream> #include <map> int main() { std::map<int,int> m; m.insert(std::pair<..>(0,10)); . . . //Weitere Elemente einfügen std::map<int,int>::iterator it; // it zeigt auf das erste Element von vec it=m.begin(); it = m.find(0); m.insert(......); . . . //Weitere Elemente einfügen std::cout<< it->second; //wäre hier die Ausgabe definitiev 10 oder kann sie auch anderst lauten. Vorallem wegen dem Einfügen neuer Elemente. Und was macht er mir, wenn ich vor dem cout ein m.erase mache, welches das element zerstört, auf welches der interator zeigt ?? std::cin.get(); }
-
Mach dir die Iteratoren doch nicht so schwer.
Ein Iterator ist im prinzip nur ein gekapselter Zeiger, bei dem, je nach Iterator-Trait, die Operatoren wie *, ->, --/++prä, pos++/-- überladen sind. Wenn du in einen Iterator das Ergebnis von find speicherst, wird der auch für immer auf dieses Objekt zeigen, es sei denn, du biegst den Iterator, nicht aber den Container, etwas um und zeigst auf was anderes.
Was dein erase angeht, bin ich mir nicht sicher. Ich vermute aber mal, dass du dann einen Iterator auf freigegebenen Speicher hast. Ein Zugriff darauf könnte eine Speicherzugriffsverletzung bringen, musst du mal testen.
-
Zwischen Iteratoren und mir besteht eine Persöhnliche Fehde. Und ich bin der Leittragende *ggg*
-
AlexXXx schrieb:
Wieman sieht ist das nicht durch den kompiler. Ich glaube es kommt rüber was ich meine
Nein. Dein erster Satz ist keiner.
AlexXXx schrieb:
#include <iostream> #include <map> int main() { std::map<int,int> m; m.insert(std::pair<..>(0,10));
Die Standardbibliothek bietet Dir hier eine Helferfunktion an
m.insert(std::make_pair(0,10));
AlexXXx schrieb:
//Weitere Elemente einfügen std::map<int,int>::iterator it; // it zeigt auf das erste Element von vec it=m.begin();
Default-Konstruktor + Zuweisung
Warum nicht gleich initialisieren?
std::map<int,int>::iterator it = m.begin();
Das hier ist eine Kopier-Initialisierung. Wenn Du Dein Objekt gleich initialisieren kannst, solltest Du das auch tun.AlexXXx schrieb:
it = m.find(0); m.insert(......); . . //Weitere Elemente einfügen std::cout<< it->second; //wäre hier die Ausgabe definitiev 10 oder // kann sie auch anderst lauten. Vorallem wegen dem Einfügen neuer Elemente. // Und was macht er mir, wenn ich vor dem cout ein m.erase mache, welches das // element zerstört, auf welches der interator zeigt ??
"10" -- Das gilt allerdings bei anderen Containern eventuell nicht. Musst Du mal gucken, welche Garantien ein Container macht. Bestimmte Operationen bei manchen Containern machen Iteratoren ungültig. Bei std::map sollte das aber in Ordnung sein. Wenn Du das Element mit erase löschst, darfst Du logischerweise nicht mehr darauf zugreifen. So ein Iterator funktioniert wie ein Zeiger. Der Unterschied ist nur, dass er nicht jede Operation unterstützen muss. Dafür gibt es die versch. Iterator-Kategorien.
Gruß,
SP
-
AlexXXx schrieb:
1.) Wenn ich eine schleife mache, und die so lange laufen lasse, bis der iterator den *.end() iterator erreicht hat, macht er dann eine Zuweisung, oder wirde jedes mal der *.end() iterator neu berechnet.
Wenn es nicht jedesmal neu berechnet wird, ist es laufzeiteffizienter.
Wenn es jedes mal neu berechnet wird, kann man den Kontainer mnipulieren während dem schleifendurchlauf.Die Semantik ist klar, er berechnet es natürlich jedesmal neu. (Das heißt, er tut so, dass dasselbe rauskommt, als wenn er es jedesmal neu berechnet. Wenn der Compiler sieht, dass end() immer dasselbe Ergebnis liefert kann er den Aufruf natürlich aus der Schleife rausziehen.)
-
Nein. Dein erster Satz ist keiner.
*ggg* das ist wie dein erstes pferd ist ein hold *lach*
Manche Anhäufungen von worten lassen doch das richtige assoziieren.Danke Sebastian. Das macht die iteratoren doch ein bisschen überschaubarer.
Zumindest die Idee welche dahinter ist. Ev. wäre wünschenswert, dass man die kontainer je nach "Garanie" welche sie geben, Typen zuordnet.
Also map wäre dann zum Beispiel ein Kontainer welcher den iterator bindet.
Und ein Kontainer welcher den iterator nicht bindet, wäre dann einer welcher nicht garantiert, dass bei der kontainer manipulation die iteratoren noch eindeutig auf die Speicherstellen verweisen. Oder irgend so eine Begriffsbildung.
Wenn es sie nicht schon gibt.
-
dein erstes Pferd ist ein Holz eine ich. Tschuldige. Sollte ein Scherz sein.
-
AlexXXx schrieb:
Zwischen Iteratoren und mir besteht eine Persöhnliche Fehde. Und ich bin der Leittragende *ggg*
Lies die Anweisungen und befolge sie, dann klappt es auch mit Iteratoren.
-
AlexXXx, führe dir am besten die STL-Artikel des C++-Magazins zu Gemüte. Dort findest du unter anderem eine Tabelle, in der steht, welche Container Iteratoren invalidieren können. Ausserdem werden Iteratoren selbst recht ausführlich erklärt.
1) Container
2) Iteratoren und Algorithmen
3) Hilfsklassen und Erweiterungen