JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=b951b7ab925830bc742350d4e45d1d3aMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

STL - Verständnisprobleme mit den Iteratoren
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
t10ottoo
Senior JLI'ler


Alter: 40
Anmeldedatum: 15.04.2004
Beiträge: 210
Wohnort: Berlin
Medaillen: Keine

BeitragVerfasst am: 14.04.2006, 21:12    Titel: STL - Verständnisprobleme mit den Iteratoren Antworten mit Zitat

Hi,

ich befasse mich gard mit dem Thema STL. Speziell den Datentyp "vector". Nun bin ich beim Thema Iteratoren. Leider fehlt mir da ein wenig der Sinn. Ich habe hier mal ein kleines Beispielprogramm:
CPP:
vector<int> v1;
   vector<int>::iterator iter1;
   int izahl = 0;

   do
   {
      cout << "Welche Zahl soll hinzugefuegt werden?" << endl;
      cin >> izahl;
      v1.push_back(izahl);
   } while (izahl != 0);

   // Letztes Element löschen, damit die 0 nicht mit ausgegeben wird.
   v1.erase(--v1.end());

   cout << endl << endl;
   for (int j = 0; j < v1.size(); j++)
   {
      cout << v1[j] << " ";
   }

   cout << endl << endl;

   for (iter1 = v1.begin(); iter1 != v1.end(); iter1++)
   {
      cout << *iter1 << " ";
   }

   getch();


Das Programm sollte denk ich klar sein. Liest halt Zahlen ein, bis man eine 0 eingibt. Die Zahlen werden im vector 'v1' gespeichert.

Nun habe ich zwei Möglichkeiten der Ausgabe. Einmal ohne und einmal mit Iterator.
Nun frage ich mich, warum manche die Ausgabe mit Iterator verwenden. Bzw. frage ich mich, ob es wirklich sinnvolle Anwendungen für Iteratoren gibt. Denn die Ausgabe klappt ja auch wunderbar ohne Iteratoren.

Danke schonmal für eure Bemühungen Smile

Gruß
Otti
_________________
Meine kleine Projekte-Seite
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
51m0n
JLI'ler


Alter: 33
Anmeldedatum: 06.01.2006
Beiträge: 167
Wohnort: Erkelenz
Medaillen: Keine

BeitragVerfasst am: 14.04.2006, 21:26    Titel: Antworten mit Zitat

Hi
Bei Vectoren geht die Ausgabe noch ganz gut ohne Iteratoren aber bei einer List sind das schon anders aus Wink .
Du bracuhst Iteratoren zum Beispiel wenn du ein Element löschen willst. Die Methode erase() braucht einen Iterator, der auf das zu löschende Element zeigt.

MfG 51m0n
_________________
Teigwaren
heißen Teigwaren,
weil sie früher einmal Teig waren
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 14.04.2006, 21:50    Titel: Antworten mit Zitat

51m0n hat Folgendes geschrieben:
Hi
Bei Vectoren geht die Ausgabe noch ganz gut ohne Iteratoren aber bei einer List sind das schon anders aus Wink .
Du bracuhst Iteratoren zum Beispiel wenn du ein Element löschen willst. Die Methode erase() braucht einen Iterator, der auf das zu löschende Element zeigt.

MfG 51m0n


Wobei ja v1.erase( v1.begin()+i ); auch wunderbar funktioniert läuft wie du sagtest mit iteratoren ab aber der index i kann so auch wudnerbar verwendet werden, gezwungen iteratoren zu benutzen bist du also in diesem fall nicht unbedingt. Afaik sind iteratoren aber etwas fixer da diese nicht wie beim index erst errechnet werden muss, was einige funktionscalls spart.

Einige hier werden dir das sicher besser erklären können.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
51m0n
JLI'ler


Alter: 33
Anmeldedatum: 06.01.2006
Beiträge: 167
Wohnort: Erkelenz
Medaillen: Keine

BeitragVerfasst am: 14.04.2006, 22:19    Titel: Antworten mit Zitat

Ich weis nicht ob es ganz ohne Iterator geht, denn v1.begin() liefert ja einen Iterator zurück den du dann inkrementierst(oder wie man das auch immer schreibt), also arbeitest du genau genommen auch mit Iteratoren Wink. Auch wenn man das nicht auf den ersten Blick sieht.
_________________
Teigwaren
heißen Teigwaren,
weil sie früher einmal Teig waren
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 14.04.2006, 22:31    Titel: Antworten mit Zitat

Habs ja nicht abgestritten, war wohl nur unleserlich geschrieben von mir Smile

Zitat:
Wobei ja v1.erase( v1.begin()+i ); auch wunderbar funktioniert, läuft wie du sagtest mit iteratoren ab, aber der Index i kann so auch wunderbar verwendet werden.

_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 15.04.2006, 13:45    Titel: Antworten mit Zitat

51m0n hat Folgendes geschrieben:
Ich weis nicht ob es ganz ohne Iterator geht, denn v1.begin() liefert ja einen Iterator zurück den du dann inkrementierst(oder wie man das auch immer schreibt), also arbeitest du genau genommen auch mit Iteratoren Wink. Auch wenn man das nicht auf den ersten Blick sieht.

Nicht ganz...Da es in der Natur des Vectors liegt, dass immer an einem Stück im Speicher liegt, genügt es, einen Zeiger auf das erste Element zu bekommen(Iterator!=Zeiger) und im Speicher um Index fortzuschreiten. So kommst du bei Vectoren immer auf das richtige Element. Also sollte der Zugriff per Index immer noch am schnellsten sein.
Da brauchst du keine Iteratoren im Speicher verwalten und nur eine Zählervariable zu inkrementieren.

Vorsicht: Wer trotzdem Iteratoren für Vectoren verwendet, muss aufpassen, da Iteratoren beim Hinzufügen eines Elements ungültig werden können. Abhilfe schafft dem eine vorzeitige Reservierung des Speichers durch die Elementfunktion reserve():
CPP:
std::vector< int > myvector;

//Reserviert Speicher für 20 Elemente
myvector.reserve(20);

So wird auch der Aufwand umgangen, der beim Hinzufügen eines Elements nötig ist. Sobald im vector noch freier Speicher reserviert ist, kann das Element einfach hinzugefügt werden. Ist dies nicht mehr so, wird 1. der Iterator ungültig, da 2. der gesamte vector zusammenhängend neu in den Speicher geschrieben wird.


Da sind wir genau beim Thema. Ich vermute, dort wo du Iteratoren bei vectoren im Einsatz gesehen hast, mussten sie verwendet werden. Es gibt Elementfunktionen/Algorithmen, die nur Iteratoren (also keine einfache Indexangabe) unterstützen.
Wenn du also deine Liste im Programmablauf sowieso von vorne bis hinten durchlaufen willst und bei einem bestimmten Ereigniss z.B. ein Element löschen willst (oder eben irgendeine andere Aktion, die einen Iterator erfordert), dann bietet es sich an, gleich Iteratoren zu nehmen, anstatt eine normale for-Schleife mit Indexwert, bei der du parallel noch einen Iterator mitlaufen lässt oder ähnliche Verkrampfungen Razz
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Kampfhund
Super JLI'ler


Alter: 42
Anmeldedatum: 20.07.2002
Beiträge: 408

Medaillen: Keine

BeitragVerfasst am: 15.04.2006, 14:17    Titel: Antworten mit Zitat

Ein Vorteil von iteratoren ist Folgendes:

CPP:
#include <vector>
#include <list>

struct test
{
   typedef unsigned int the_type;
   typedef std::list<the_type> TypeStorage;
   typedef TypeStorage::iterator iter;

   void operate_on_s()
   {
      for(iter i=s.begin();i!=s.end();i++)
      {
         if(*i == 3)
            *i = 4;
      }
   }

   TypeStorage s;
};


Willst du in diesem Beispiel nun - warum auch immer - einen anderen container-typ verwenden, so kannst du einfach diese Zeile:
CPP:
typedef std::list<the_type> TypeStorage;

durch diese ersetzen:
CPP:
typedef std::vector<the_type> TypeStorage;


und das Ganze lässt sich ohne weiteren Aufwand kompilieren.
_________________
Kochen ist ein NP-schweres Optimierungsproblem.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
51m0n
JLI'ler


Alter: 33
Anmeldedatum: 06.01.2006
Beiträge: 167
Wohnort: Erkelenz
Medaillen: Keine

BeitragVerfasst am: 15.04.2006, 14:27    Titel: Antworten mit Zitat

Liegt der Vector echt immer an einem Stück? Denn der Compiler kann ja nicht ahnen wie groß er einmal wird und kann dementsprechend nicht den Speicher reservieren. Oder hab ich hier nen Denkfehler?
_________________
Teigwaren
heißen Teigwaren,
weil sie früher einmal Teig waren
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Kampfhund
Super JLI'ler


Alter: 42
Anmeldedatum: 20.07.2002
Beiträge: 408

Medaillen: Keine

BeitragVerfasst am: 15.04.2006, 14:37    Titel: Antworten mit Zitat

51m0n hat Folgendes geschrieben:

Denn der Compiler kann ja nicht ahnen wie groß er einmal wird und kann dementsprechend nicht den Speicher reservieren.

Ist der Speicher des Vectors zu klein, so wird neuer und größerer Speicher reserviert und alle Elemente des alten Vectors werden in den neuen Speicher kopiert. Das ist natürlich zeitaufwändig, weswegen vectoren auch weniger für das einfügen und löschen von Elementen gedacht sind sondern eher für schnellen zugriff (ist ja nur das indizieren in ein array, also konstanter Zeitaufwand).

EDIT: Und ja, meines wissens nach ist der Speicher des vectors immer zusammenhängend.
_________________
Kochen ist ein NP-schweres Optimierungsproblem.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
t10ottoo
Senior JLI'ler


Alter: 40
Anmeldedatum: 15.04.2004
Beiträge: 210
Wohnort: Berlin
Medaillen: Keine

BeitragVerfasst am: 15.04.2006, 19:30    Titel: Antworten mit Zitat

Vielen Dank erstmal für die Antworten und sorry, dass ich jetzt erst antworte. Musste aber noch ein paar Ostervorbereitungen treffen Wink

Soweit hab ich das erstmal verstanden.
Nur noch eine Frage:
Kampfhund hat ja geschrieben, dass Vectoren weniger gut fürs Einfügen und Löschen von Elementen sind, weil das eben sehr langsam ist, da oft (wenn der Speicher nicht mehr zusammenhängend sein kann) neuer Speicher reserviert weden muss und alle Elemente rüberkopiert werden.

Nun stellt sich mir die Frage, wo ich den Vector dann überhaupt sinnvoll anwenden kann? Bzw. sollte?
Zitat:
Für einen schnellen Zugriff

Hmm...ok, d.h. am Anfang Werte reinschreiben und nicht mehr großartig erweitern, sondern nur mit diesen Werten arbeiten? Für Einfügen und Löschen von Elementen wäre dann wohl die Liste besser?

Wäre nett, wenn ihr mir diese Fragen noch beantworten könntet.

Gruß und Danke
Otti
_________________
Meine kleine Projekte-Seite
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Kampfhund
Super JLI'ler


Alter: 42
Anmeldedatum: 20.07.2002
Beiträge: 408

Medaillen: Keine

BeitragVerfasst am: 15.04.2006, 21:43    Titel: Antworten mit Zitat

t10ottoo hat Folgendes geschrieben:

Nun stellt sich mir die Frage, wo ich den Vector dann überhaupt sinnvoll anwenden kann? Bzw. sollte?
Zitat:
Für einen schnellen Zugriff

Hmm...ok, d.h. am Anfang Werte reinschreiben und nicht mehr großartig erweitern, sondern nur mit diesen Werten arbeiten? Für Einfügen und Löschen von Elementen wäre dann wohl die Liste besser?


Ja. Bei einer einfach oder doppelt verketteten List müssen beim Einfügen/Löschen nur Pointer "umgebogen" werden. Das kann in konstanter Zeit erledigt werden (allerdings nur wenn man am Anfang oder am Ende einfügt/löscht, ansonsten ist es von der größe der Liste abhängig).

EDIT:
Unter folgender Adresse findet man (bischen unter der mitte des Dokuments) eine Tabelle mit dem Laufzeitverhalten der verschiedenen Container:
http://www.dd.bib.de/~dozric/C++/kennen/stl.htm
_________________
Kochen ist ein NP-schweres Optimierungsproblem.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 16.04.2006, 02:57    Titel: Antworten mit Zitat

Ja, es gibt ja schließlich auch Situationen, in denen du weniger Elemente hinzufügen musst, aber eher die Struktur oft durchlaufen musst Wink

Aber wie gesagt, man kann auch selbst den Speicher für den Vector reservieren
The Lord of Programming hat Folgendes geschrieben:
CPP:
std::vector< int > myvector;

//Reserviert Speicher für 20 Elemente
myvector.reserve(20);


Also wenn es wahrscheinlich ist, dass während dem Programmverlauf der vector eine bestimmte Maximumgröße nicht überschreitet, wäre sowas ein guter Weg, den Aufwand beim Hinzufügen drastisch zu kürzen.
Genauso wäre es möglich, an "unbelasteten" Stellen des Programms/Spiels zu überprüfen, ob mehr Speicher reserviert werden muss, damit du sowas nicht in den Performance-Engpässen machen musst.
CPP:
// <- liefert die Anzahl der im Speicher reservierten Elemente
unsigned int reserved_elements=myvector.capacity();

_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
GreveN
JLI Master


Alter: 38
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 16.04.2006, 06:56    Titel: Antworten mit Zitat

Was IMHO aber wiederum auch nicht so toll ist, weil du damit im Grunde ein statisches Array hast, bzw. könntest du gleich eins anlegen mit der weitesgehend selben Funktionalität. Der Witz an den STL Vektoren ist ja grade, dass sie dynamische Arrays repräsentieren sollen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
t10ottoo
Senior JLI'ler


Alter: 40
Anmeldedatum: 15.04.2004
Beiträge: 210
Wohnort: Berlin
Medaillen: Keine

BeitragVerfasst am: 16.04.2006, 11:33    Titel: Antworten mit Zitat

@Kampfhund:
Danke für den Link, steht ja auch noch so hilfreiches dabei.

@TLoP:
Wie GreveN schon sagte, wäre das dann denk ich auch ein statisches Array. Ok, man müsste zum Hinzufügen eines Elements immer eine Zählervariable mitlaufen lassen. Aber ich denke, die Funktion "pushback" macht intern auch nichts anderes.

Also Danke nochmals an alle für die sehr gute Hilfe.

Wünsche euch noch zwei restliche schöne Feiertage Smile
Gruß
Otti
_________________
Meine kleine Projekte-Seite
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 16.04.2006, 12:04    Titel: Antworten mit Zitat

Ja...muss man eben genau abwägen.
Natürlich wäre es Blödsinn, am Anfang des Programms festzulegen, dass mein Vector 1.000.000 Elemente hat.
Aber wenn ich z.B. weiß, dass innerhalb der nächsten Frames voraussichtlich mindestens 25 Elemente neu dazukommen und vector::capacity() nicht dafür ausreicht, dann sollte ich mich mal schnell ans Reservieren machen.
Natürlich übernimmt das auch push_back() - aber wesentlich ineffizienter. Das wichtigste bei der Sache ist, dass du den Speicher sinnvoll und zum richtigen Zeitpunkt reservierst, dann hast du auch Chancen, die Geschwindigkeit zu optimieren. Sonst überlässt du dem Computer die (Reservierungs-)Arbeit und der wird hier mehr oder weniger das machen, worauf er Lust hat...
Und das muss ja nicht zwangsweise Geschwindigkeitsoptimierung sein Wink

Wenn ich hier ein statisches (oder gar dynamisches) Array hätte, dann kostet das wesentlich mehr Verwaltungsaufwand und kann wohl deshalb auch fehleranfälliger sein.
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum