[STL] Vector iterator an Position springen
-
Also ich habe mit meinen begrenzten C++ Fähigkeiten noch einmal über diese Problematik nachgedacht.
Soweit ich das überblicke stehen die beiden Anfordungen kontraproduktiv gegenüber:
Zum Einen möchte ich einen Indexzugriff, zum anderen auch beliebige dynamisch Elemente löschen könnenVon meinem Verständnis her sind die Elemente in vector komplexer angelegt, als z.B. in einer Liste. Dort kennt jedes Element ja nur seinen Vordermann und Nachfolger.
Um einen Indexzugriff zu ermöglichen benötige ich weitere Informationen, um das Element n schnell finden zu können.Und das ist auch das Problem beim Löschen. Wenn ich nun das Element n löschen will, so muss ich die komplexe Anordnung des vectors aufbrechen, das Element löschen und anschließend müssen die übrigen Elemente neu angeordnet werden, um wieder schnellen Indexzugriff zu erlauben.
Bei einer Liste geht das ganze schneller, da ich lediglich die Adressen des Vordermanns und Nachfolger entsprechend vergeben muss. Also der Nachfolger des Elements wird der Nachfolger des Vordermanns und vice versa. Nicht viel Aufwand.
Jetzt habe ich bei meinem vector zwei Möglichkeiten die ganzen Elemente zu durchlaufen:
Index:
for(unsigned int i = 0; i < vector.size(); ++i) { vector[i] // do something }
Jetzt muss ich beim Löschen eines Elements natürlich auf den Index i aufpassen. Also wenn ich mit der Zeit beim Index i = 17 angekommen bin und entscheide, dass dieses Element gelöscht werden muss, welches Element wird denn dann als nächstes bearbeitet nach dem ++i der for-Schleife?
Spontan würde ich sagen, dass die übrigen Elemente 'nachrutschen', sodass der Nachfolger von i = 17 dann das Element 17 ist. D.h. nach der Aktion ++i wäre ich schon bei i = 18 und hätte somit ein Element übersprungen?Ich hatte auch überlegt, die Indizes der zu löschenden Elemente separat zu speichern, sodass ich anschließend nach dem Durchlauf das Löschen durchführen kann.
Das Problem ist doch dabei wieder nur, sobald ein Element gelöscht ist, sind die ganzen übrigen gespeicherten Indizes falsch, weil die Indexnotation um ein Element verschoben ist.Also auch Müll!
Iterator:
for(vector::iterator iter = vector.begin(); iter != vector.end(); ++iter) { iter // do something }
Hierbei hatte ich mir sogar noch was ganz anderes überlegt, sodass ich sogar komplett auf den Vektor verzichten kann.
Denn während bei der Indexnotation die Problematik das Löschen ist, ist die Problematik bei einer Liste o.ä. eben der fehlende Indexzugriff. Denn ich will eine Eigenschaft eines vorher gelöschten Objekts auf ein zufälliges restliches Objekt verteilen.
Nachdem ich aber bei Listen keinen Indexzugriff habe, kann ich das zufällig bestimmte Element n aber nur finden, indem ich vom Start ausgehend n Element entlangehe - und das dauert!Also habe ich mir überlegt, diese Übertragung auf ein zufällig bestimmtes Element für den nächsten Durchlauf aufzuheben.
Sprich ich lösche ein Element und speichere eine Eigenschaft. Dann bestimme ich ein zufälliges Element, dass diese Eigenschaft erhalten soll und speichere dies in einer separaten Liste (alle Eigenschaften werden sortiert, also nehme ich beser ein Set?)Und beim nächsten Durchlauf läuft ein Zähler mit, der vergleicht ob das aktuelle Element die gleiche Nummer trägt wie das zufällig bestimmte und falls ja - wird die Eigenschaft übertragen.
Damit spare ich mir das mühselige Durchlaufen, um das n. Element zu erreichen, da ich es auf den nächsten Durchlauf verschiebe, wo die ganze Liste sowieso durchgegangen wird.
Vielen Dank an alle, die bis zum Ende gelesen haben.
Viele Grüße,
Klaus.
-
Ich nehme an, dass du nach dem Erase-Remove-Idiom suchst.
-
Hi,
seldon schrieb:
Ich nehme an, dass du nach dem Erase-Remove-Idiom suchst.
das wurde mir auch schon vorgeschlagen und ich hatte es hier kritisch betrachtet.
Mein Problem ist, dass während des Durchlaufs anhand einer Zufallszahl entschieden wird, ob ein Element gelöscht werden muss oder nicht.
Es ist also nicht so, dass ich von vorneherein sagen kann: "Lösche alle Elemente mit 'eigenschaft' = 10".
Gruß,
Klaus.
-
Klaus82 schrieb:
Es ist also nicht so, dass ich von vorneherein sagen kann: "Lösche alle Elemente mit 'eigenschaft' = 10".
Na und? Du kannst doch bei remove_if ein beliebiges Prädikat angeben, z.B. eines, das zufällig true oder false ist.
-
Naja,
std::vector<int> v; v.erase(std::remove_if(v.begin(), v.end(), [](int) { return std::rand() % 10 == 0; }), v.end());
bzw. in C++03
bool is_doomed(int) { return std::rand() % 10 == 0; } ... std::vector<int> v; v.erase(std::remove_if(v.begin(), v.end(), is_doomed), v.end());
-
seldon schrieb:
Naja, [...]
Wenn schon C++11, dann gleich richtig:
std::vector<int> v; v.erase(std::remove_if(begin(v), end(v), [](int) { return std::rand() % 10 == 0; }), end(v));
-
Klaus82 schrieb:
krümelkacker schrieb:
Die Referenz ist da unnötig; denn der Ausdruck
electrons
hat denselben Typ und dieselbe Wertkategorie wie der Ausdruckr_electrons
. Dass lezteres als Referenz deklariert war, merkt die Funktion gar nicht. Es beeinflusst auch nicht die Überladungsauflösung. Ausdrücke haben nie einen Referenztypen.Aber ich dachte das brauche ich genau dafür: [...]
Dann hast du Referenzen noch nicht verstanden.
Klaus82 schrieb:
Wenn ich keinen Pointer oder Referenz übergebe, so mache ich doch Call bei Value, also es wird eine lokale Kopie angelegt.
Dafür musst du aber auf Aufruferseite keine extra Referenz anlegen; denn
void foo(int& ref_in_foo); int main() { int i = 42; int& ref_in_main = i; foo(ref_in_main); }
ist äquivalent zu
void foo(int& ref_in_foo); int main() { int i = 42; foo(i); }
Tatsächlich gibt es da überhaupt keinen Unterschied zwischen der Initialisierung von ref_in_foo und ref_in_main. Du kannst auch 3 Referenzen dazwischen bauen:
void foo(int& ref_in_foo); int main() { int i = 42; int& r1 = i; int& r2 = r1; int& r3 = r2; foo(r3); }
Das spielt alles keine Rolle. Du kannst auch einfach
ref_in_foo
direkt miti
beim Funktionsaufruf initialisieren (wie im zweiten Beispiel).Klaus82 schrieb:
Was genau ist daran komisch? Dafür ist doch der Vektor zum Glück dynamisch.
Es wär halt schön, wenn du um das Löschen einzelner Elemente drum herum kommen würdest. erase-remove hätte ich Dir auch empfohlen, aber ich stimme dir zu, dass das nicht wirklich anwendbar ist, in deinem Fall. Zumindest sehe ich es nicht.
-
1. Iterator auf das letzte Element holen.
2. Wenn ein Element gelöscht werden soll, Element mit *last tauschen.
3. Last erniedrigen
4. Remove & Erase Idiom
-
Hi,
krümelkacker schrieb:
Dann hast du Referenzen noch nicht verstanden.
Dafür musst du aber auf Aufruferseite keine extra Referenz anlegen; denn
void foo(int& ref_in_foo); int main() { int i = 42; foo(i); }
Dieses Beispiel hatte mir wieder zu denken gegeben. Ursprünglich hatte ich es auch so verstanden, dass dies funktioniert, als ich ein paar Beispiel dazu gesehen hatte.
Als ich allerdings wieder über Funktionen nachgelesen hatte, war ich mir nicht mehr so sicher ob das funktioniert.Denn der Prototyp einer Funktion sagt doch auch, was die Funktion zurückgibt und was als Eingabe erwartet wird.
Dies führt dann kurioser Weise schon zu erster Irritation, denn:
#include <iostream> using namespace std; void foo(int i) { cout << "Input is : " << i << endl; } int main() { double j = 10; foo(j); // <-- funktioniert!! return 0; }
Also obwohl ich als Eingabe einen Integer deklariere, übernimmt die Funktion auch ohne Probleme eine double Variable. Okay, soweit ich das verstanden habe findet 'im Hintergrund' dann eine Typumwandlung statt (nennt man das so?).
Das sehe ich sehr schnell, wenn ich das ganze ändere zu:#include <iostream> using namespace std; void foo(int i) { cout << "Input is : " << i << endl; } int main() { double j = 10.25; foo(j); // <-- funktioniert!! return 0; }
Dann ist die Ausgabe einfach:
Input is : 10
Wurde in einen Integer verwandelt.
Also halten wir als Zwischenergebnis fest:
Ich kann auch andere Datentypen als im Funktionsprototype erwartet an eine Funktion übergeben, dann findet eine Typumwandlung statt.Mit der Referenz verhält es sich scheinbar wieder anders, weil eine Referenz selbst kein Datentyp ist? Sondern eben eine Referenz auf diesen? Klingt komisch, scheint aber so zu sein?
Also wenn ich nun deklariere:void bar(int & r_i) { cout << "Input is : " << r_i << endl; }
Dann bedeutet dies: "Initialisiere mir eine Integer-Referenz auf das was du als Eingabe bekommst."
Wieder kurioser Weise ist der Datentyp jetzt zwingend!! Folgendes funktioniert jetzt nicht mehr:
#include <iostream> using namespace std; void bar(int & r_i) { cout << "Input is : " << r_i << endl; } int main() { double j = 10.25; bar(j); // <--- funktioniert nicht!! return 0; }
Warum? Das kann ich nur wieder raten. Ich nehme an dass jetzt der Datentyp zwingend ist auf den die Referenz zeigt.
Also ich kann bei der Variablenübergabe an Funktionen durchaus eine Typumwandlung erwarten, aber keine Referenzumwandlung.Gruß,
Klaus.P.S.:
Ich habe es unbewusst auch schon übernommen, aber: Warum werden Beispielfunktionen oder Variablen immer als foo und bar bezeichnet?
-
foo und bar ... Gegenfrage: wieso stellen Leute immer Fragen deren Antworten sie sich ganz einfach selbst ergoogeln könnten?
Klaus82 schrieb:
Warum? Das kann ich nur wieder raten. Ich nehme an dass jetzt der Datentyp zwingend ist auf den die Referenz zeigt.
Weil non-const Lvalue-Referenzen nicht an Rvalues gebunden werden dürfen, und das Ergebnis einer Konvertierung eine Rvalue ist.
Also ich kann bei der Variablenübergabe an Funktionen durchaus eine Typumwandlung erwarten, aber keine Referenzumwandlung.
Was soll Referenzumwandlung bedeuten?
Wenn dann würde der Wert in den passenden Typ konvertiert, und die Referenz dann an die so entstandene Rvalue gebunden.Das ist in bestimmten Fällen auch erlaubt, nämlich wenn es eine Lvalue-Referenz auf const ist, oder eine Rvalue-Referenz.
Versuch z.B. einfach malvoid bar(int const & r_i) ...
-
314159265358979 schrieb:
1. Iterator auf das letzte Element holen.
2. Wenn ein Element gelöscht werden soll, Element mit *last tauschen.
3. Last erniedrigen
4. Remove & Erase IdiomSuper Idee. Wobei remove hier dann ja überflüssig ist. Statt swap mag auch einfach ein move-assignment reichen.
Also...
unsigned numelecs = electrons.size(); for (unsigned idx=0; idx<numelecs; /* kein ++idx hier*/) { ... if (muss electrons[idx] gelöscht werden?) { --numelecs; if (idx!=numelecs) { // falls idx nicht schon das letzte gültige war ... electrons[idx] = std::move(electrons[numelecs]); } // kein ++idx, weil an idx-ter Stelle ja // jetzt ein neues Electron steht, was wir nicht // ueberspringen wollen, oder wir schon am Ende sind } else { ++idx; // ok, weiter zum nächsten } } electrons.erase(electrons.begin()+numelecs,electrons.end());
(ungetestet)
Klaus82 schrieb:
[...]
Dies führt dann kurioser Weise schon zu erster Irritation, denn:#include <iostream> using namespace std; void foo(int i) { cout << "Input is : " << i << endl; } int main() { double j = 10; foo(j); // <-- funktioniert!! return 0; }
Wie gesagt, die Art der Parameterinitialisierung ist äquivalent zu
double j = 10; int i = j; // OK: implizite Konvertierung des double-Wertes nach int int& r = j; // Compile-Error: Auf was soll sich r denn beziehen? // Dass das hier nicht klappt ist ein Feature, denn // sonst würde das ganz schnell zu Bugs führen, weil // Du ggf beim Schreibzugriff über r Änderungen von j // erwarten würdest, was gar nicht sein kann. const int& c = j; // Das ist erlaubt. Hier bezieht sich die Referenz // auf ein temporär erzeugtes int-Objekt. Da du das // wegen const nicht verändern darfst, kannst du auch // nicht in die Falle von oben reinlaufen.
Die Sache hat mit Funktionen also gar nichts zu tun.
Klaus82 schrieb:
[...]
Warum? Das kann ich nur wieder raten.
[...] aber keine Referenzumwandlung.Zumindest nicht bei nicht-const Referenzen. Sei froh, dass das so ist!
-
Hi,
krümelkacker schrieb:
unsigned numelecs = electrons.size(); for (unsigned idx=0; idx<numelecs; /* kein ++idx hier*/) { ... if (muss electrons[idx] gelöscht werden?) { --numelecs; if (idx!=numelecs) { // falls idx nicht schon das letzte gültige war ... electrons[idx] = std::move(electrons[numelecs]); } // kein ++idx, weil an idx-ter Stelle ja // jetzt ein neues Electron steht, was wir nicht // ueberspringen wollen, oder wir schon am Ende sind } else { ++idx; // ok, weiter zum nächsten } } electrons.erase(electrons.begin()+numelecs,electrons.end());
Ich habe dein Programm versucht nachzubauen und hänge jetzt an der Fehlermeldung
‘move’ is not a member of ‘std’
Eine Suche im Netz ergabe, dass dies scheinbar ein neues Feature von C++ ist? Scheinbar bin ich nicht up to date?
Ein Hinweis ist, dass es in utility zu finden sei - also habe ich dies mit #include <utility> eingefügt. Ich bekomme jetzt keine Fehlermeldung für utility, also scheinbar besitze ich das (?), aber nach wie vor den Kompilerfehler.Ich verwende den g++ Kompiler:
g++ -v gcc version 4.4.5 (Debian 4.4.5-8)
Scheinbar muss ich nachrüsten?
Gruß,
Klaus.
-
<utility> ist ein Standard-Header. Aber
std::move
gibt es erst ab C++2011. Deine Compilerversion unterstützt das glaub'ich auch. Musst du nur aktivieren per-std=c++0x
Zeig doch mal deine Definition von
electron
. Möglicherweise bringt std::move an der Stelle eh nichts. Aber das kommt drauf an, wieelectron
gestrickt ist.Außerdem würdest du mit der Verwendung von
std::move
in Kauf nehmen, dass ein C++1998-Compiler deinen Quellcode nicht mehr übersetzen kann. Das sollte dir klar sein.
-
Hi,
krümelkacker schrieb:
<utility> ist ein Standard-Header. Aber
std::move
gibt es erst ab C++2011. Deine Compilerversion unterstützt das glaub'ich auch. Musst du nur aktivieren per-std=c++0x
also du meinst als Anhang für das Compiler-Kommando? Anstatt normal z.B:
g++ -Wall -pedantic -ansi -c foo.cpp
eben
g++ -Wall -pedantic -ansi -c -std=c++0x foo.cpp
krümelkacker schrieb:
Zeig doch mal deine Definition von
electron
. Möglicherweise bringt std::move an der Stelle eh nichts. Aber das kommt drauf an, wieelectron
gestrickt ist.Eigentlich nichts wildes, ich sammle nur für jedes Elektron seine für mich physikalisch relevanten Eigenschaften:
#ifndef ELECTRON_H #define ELECTRON_H class electron{// public: inline electron(double e, double z, double x, double a); double angle; double energy; double z_coord; double x_coord; }; electron::electron(double e,double z, double x, double a) { energy = e; z_coord = z; x_coord = x; angle = a; } #endif
Gruß,
Klaus.
-
Klaus82 schrieb:
also du meinst als Anhang für das Compiler-Kommando? Anstatt normal z.B:
g++ -Wall -pedantic -ansi -c foo.cpp
eben
g++ -Wall -pedantic -ansi -c -std=c++0x foo.cpp
Ja und Nein. Was macht denn wohl das -ansi? Wenn du es nicht weißt, dann schlag es nach. Mach in der Programmierung niemals irgendetwas blind nach ohne genau zu verstehen, was und warum du es tust. Wenn du rausgefunden hast, was -ansi (und die anderen Optionen) genau machen, dann kommst du sicherlich drauf, wie es richtig heißt.
-
Klaus82 schrieb:
krümelkacker schrieb:
Zeig doch mal deine Definition von
electron
. Möglicherweise bringt std::move an der Stelle eh nichts. Aber das kommt drauf an, wieelectron
gestrickt ist.[c]
Eigentlich nichts wildes, ich sammle nur für jedes Elektron seine für mich physikalisch relevanten Eigenschaften:
#ifndef ELECTRON_H #define ELECTRON_H class electron{// public: inline electron(double e, double z, double x, double a); double angle; double energy; double z_coord; double x_coord; }; electron::electron(double e,double z, double x, double a) { energy = e; z_coord = z; x_coord = x; angle = a; } #endif
Ah ok. Wusstest du, dass wenn du Funktionen innerhalb einer Klasse definierst, dass die dann automatisch inline sind? Wusstest du, dass du im Konstruktor die Elemente direkt initialisieren kannst, statt diese Zuweisungen da zu machen? Wusstest du, dass struct und class sich nur dadurch unterscheiden, dass bei struct die Elemente per default public sind und bei class eben private? Ich verwende struct immer dann, wenn es keine privaten Elemente und keine zu schützende Invariante gibt, es sich also nur um eine Ansammlung von Daten handelt.
#ifndef ELECTRON_H #define ELECTRON_H struct electron { double angle; double energy; double z_coord; double x_coord; electron(double e, double z, double x, double a) : angle(a), energy(e), z_coord(z), x_coord(x) {} }; #endif
Jedenfalls bringt hier in diesem Fall std::move gar nichts. Kannst du also auch ruhigen Gewissens weglassen, ohne dass es irgendeinen Unterschied machen würde.
Ohne dir auf die Füße treten zu wollen: Wie lernst du eigentlich C++? Hast du dir ein schlaues Buch besorgt? (Würde ich nämlich empfehlen, da du dir damit Ärger sparen kannst)
-
...ich würde gar noch auf den C'tor verzichten und mittels braced-init-list initialisieren. Wenn unterstützt...
just
my2ct
-
SeppJ schrieb:
Was macht denn wohl das -ansi? Wenn du es nicht weißt, dann schlag es nach. Wenn du rausgefunden hast, was -ansi (und die anderen Optionen) genau machen, dann kommst du sicherlich drauf, wie es richtig heißt.
Aha,
laut dem gcc Manual (4.7.0) ist-ansi
eine Kurzversion von-std=c90
für C nd-std=c++98
für C++. Und-std
selbst betrifft macht eine Aussage über den language standard.Was mich jetzt nur irritiert, dass ich in dem Manual kein
-std=c++0x
finde. Ich nehme an, dass ich auch nicht explizit nach x suchen soll, sondern das als Platzhalter für insgesamt die Jahre 00 bis 09 gedacht ist? Das aktuellste was sich in der Doku findet istc++11
.krümelkacker schrieb:
Wusstest du, dass wenn du Funktionen innerhalb einer Klasse definierst, dass die dann automatisch inline sind? Wusstest du, dass du im Konstruktor die Elemente direkt initialisieren kannst, statt diese Zuweisungen da zu machen? Wusstest du, dass struct und class sich nur dadurch unterscheiden, dass bei struct die Elemente per default public sind und bei class eben private? Ich verwende struct immer dann, wenn es keine privaten Elemente und keine zu schützende Invariante gibt, es sich also nur um eine Ansammlung von Daten
handelt.Einiges davon kann ich sogar schon mit ja beantworten. Führt das jetzt zu
im Sinne von 'ich kanns' oder
im Sinne von 'wenn du es weißt, wieso programmierst du es dann nicht so'
krümelkacker schrieb:
Jedenfalls bringt hier in diesem Fall std::move gar nichts.
Okay.
krümelkacker schrieb:
Ohne dir auf die Füße treten zu wollen: Wie lernst du eigentlich C++? Hast du dir ein schlaues Buch besorgt? (Würde ich nämlich empfehlen, da du dir damit Ärger sparen kannst)
Na ja, prinzipiell learning by doing. Ich habe hier schnell gemerkt, dass die Aussage "C++ können" einem ziemlich hohen Anspruch genügen muss. Und ich selbst würde eben C++ gerne mehr verstehen, als lediglich ein Programm zusammenzustricken, dass 'irgendwie geht'.
Und so pendle ich von Baustelle zu Baustelle, einmal hier etwas ausprobieren, dann gesagt bekommen wie es 'richtig' geht, das wieder nachvollziehen, dann wieder neu ausprobieren ...Und eigentlich ist das alles nur Nebensache, denn primär mache ich Physik und nicht Programmieren, da ist also von Cheffe kein Anspruch dahinter, dass es sauber programmiert ist, sondern die richtige Physik liefert.
Als Bücher habe ich den C++ Primer, C++ von A bis Z und Die C++-Standardbibliothek. Einführung und Nachschlagewerk
Gruß,
Klaus.
-
Klaus82 schrieb:
Was mich jetzt nur irritiert, dass ich in dem Manual kein
-std=c++0x
finde. Ich nehme an, dass ich auch nicht explizit nach x suchen soll, sondern das als Platzhalter für insgesamt die Jahre 00 bis 09 gedacht ist? Das aktuellste was sich in der Doku findet istc++11
.Das liegt da dran, dass du nicht den GCC 4.7 hast. Ab 4.7 heißt der Sprachstandard c++11. Bei älteren Versionen war noch nicht ganz klar, wie der Standard heißen würde, man nahm allgemein an, dass es vor 2010 werden würde, daher c++0x. (Uralter Witz: Das x ist hexadezimal, daher ist c++11 eigentlich c++0b und die Schreibweise c++0x war daher doch richtig)
Als Bücher habe ich den C++ Primer, C++ von A bis Z und Die C++-Standardbibliothek. Einführung und Nachschlagewerk
"C++ von A bis Z" ist Schrott, der dir eher schadet als hilft. Als Insektenklatsche benutzen, aber bloß nicht lesen!
Verwechsele nicht den (ausgezeichneten) C++ Primer C++ Primer | ISBN: 382732274X mit deinem C++ Primer Plus! Über letzteren kann ich nicht viel sagen. Wenn dein Programmierstil hier aktiv kritisiert wird, dann wird er vielleicht nicht so toll sein.
Das Standardbibliotheksbuch kenne ich nicht. Referenzen gibt es normalerweise online (http://www.cplusplus.com für C++98 und http://en.cppreference.com/w/ wenn es auch C++11 sein soll). Englisch muss man ohnehin können.
-
Klaus82 schrieb:
Einiges davon kann ich sogar schon mit ja beantworten. Führt das jetzt zu
im Sinne von 'ich kanns' oder
im Sinne von 'wenn du es weißt, wieso programmierst du es dann nicht so'
Ich wollte nur sicher gehen, dass du weißt, dass man das auch anders aufschreiben kann. Kannst natürlich sagen "nee, so wie ich das schreibe, finde ich das schöner" und dagegen ist auch nix einzuwenden -- also in diesem Fall.
Klaus82 schrieb:
Na ja, prinzipiell learning by doing. Ich habe hier schnell gemerkt, dass die Aussage "C++ können" einem ziemlich hohen Anspruch genügen muss.
Naja, wenn du sagen würdest "ich kann Turmspringen", dann gehe ich davon aus, dass du auch Salti und nicht nur gerade runterspringen kannst. Und wenn du es einfach so probierst, ohne dich intensiver mit der Technik auseinanderzusetzen, dann machste halt auch mal eher 'nen Bauchklatscher. Tut dann natürlich weh. Ich bereue die Entscheidung nicht, mir ein schlaues C++ Buch besorgt zu haben. Drauflos hacken, ohne zu verstehen, was ich da eigentlich tue, wäre für mich total unbefriedigend. Ich will mir ja auch relativ sicher sein, dass ich keinen Murks baue ...
Klaus82 schrieb:
Und ich selbst würde eben C++ gerne mehr verstehen, als lediglich ein Programm zusammenzustricken, dass 'irgendwie geht'.
Das ist doch schomma 'ne super Einstellung.
Klaus82 schrieb:
Und so pendle ich von Baustelle zu Baustelle, einmal hier etwas ausprobieren, dann gesagt bekommen wie es 'richtig' geht, das wieder nachvollziehen, dann wieder neu ausprobieren ...
Na, wenn es für dich funktioniert.
Klaus82 schrieb:
Und eigentlich ist das alles nur Nebensache, denn primär mache ich Physik und nicht Programmieren, da ist also von Cheffe kein Anspruch dahinter, dass es sauber programmiert ist, sondern die richtige Physik liefert.
Hmmm ... ich denke mal, das eine bedingt ein bisschen das andere.
Klaus82 schrieb:
Die C++-Standardbibliothek. Einführung und Nachschlagewerk
Nicht übel. Das ist doch eine super Quelle, um nachzuschauen, ob es sowas wie <utility> gibt.