C++ Anfänger hat große Probleme beim lernen



  • Guten Tag,

    zuerst einmal hoffe ich, dass ich hier richtig bin und ich auch im richtigen Unterforum poste. Wenn dies nicht zutrifft, entschuldige ich mich schon mal.
    Seit 3 Jahren (mit kleinen/großen Pausen) versuche ich die Programmiersprache C++ zu lernen. Ich habe mir bereits 3 Bücher gekauft:

    C++ Für Spieleprogrammierer 4. Auflage | Heiko Kalista

    Der C++ Programmierer

    Schrödinger programmiert C++ | Das etwas andere Fachbuch

    Das erste Buch (Spieleprogrammierer) habe ich bereits vor ca. 2-3 Monaten durchgelesen. Ich habe auch damit gearbeitet !!!ABER!!! die Quellcode Dateien funktionieren nicht immer... sprich es kommen viele Fehler. Die letzte Aufgabe, wo man ein Spiel coden soll, ging auch nicht. Es kamen auch nur Fehler obwohl ich das genau so gemacht habe wie beschrieben und sogar die Aufgabe heruntergeladen habe...
    Der C++ Programmierer ist für mich noch etwas schwer, deshalb habe ich mir Schrödinger programmiert C++ geholt. Auch da das gleiche.

    Bin ich nun einfach zu blöd um zu programmieren? Ehrgeiz habe ich, jedoch fällt mir einiges noch schwierig aber verstanden habe ich es. Nur in der Praxis muss ich das noch lernen. Ich habe mir vorgenommen so ein kleines Spiel zu programmieren (genauso wie bei C++ für Spieleprogrammierer). Es soll kein 3D Spiel oder sonst was werden... doch das schaffe ich auch nicht... das einbinden habe ich nach einer Weile geschafft, doch wenn ich damit arbeiten will(nach dem Buch von Heiko Kalista) geht es nicht...

    Auch bei Schrödinger programmiert gehen einige Aufgaben nicht. Der Compiler kennt den Befehl nicht usw... Es frustriert langsam...
    Wie soll man so eine Programmiersprache lernen? Ist es meine Schuld? Ich mache genau das was ich machen soll aber trotzdem geht es nicht.

    Ich benutze zurzeit Visual Studio 2017 (vorher habe ich mit CodeBlocks gearbeitet). Normalerweise sollte es ja alles gehen. Auch in den Büchern wird mit Visual Studio gearbeitet und dort funktioniert es.

    UND NEIN alles wichtige wie int main()... sind in den Aufgaben dabei. Ich hab also nicht vergessen bzw auch der Autor hat nichts vergessen. Bei anderen funktioniert das ja. Nur bei mir will es anscheinend nicht. Auch der Befehl ist richtig geschrieben und es macht auch Sinn. Nur er weigert sich das Programm zu compilieren.



  • Ob du zu blöd bis kann man per Ferndiagnose nicht so einfach beurteilen 😉

    Zeige den Code und die komplette Fehlermeldung. Vielleicht kann man etwas dazu sagen.



  • Zeig bitte das kürzeste Programm, das nicht geht - mit Fehlermeldungen. (Copy&Paste)

    Gerne aus "Der C++ Programmierer".



  • Zum Beispiel sowas:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    vector<int>* Gruselstunde(const int& n, const int& val)
    {
      vector<int> lokalerMist(n); 
      for(int i=0; i<n; ++i)
      {
        lokalerMist.at(i) = val; 
      }
      return(&lokalerMist);
    }
    
    int main()
    {
      vector<int> *adresse_lokalerMist = Gruselstunde(5, 666);
      for(size_t i = 0; i<5; ++i) 
      {
        cout << adresse_lokalerMist->at(i) << endl;
      }
      return 0;
    }
    

    Es öffnet sich dann noch ein Tab mit dem Namen "vector":

    In Zeile 1965:

    [[noreturn]] static void _Xrange()
    		{	// report an out_of_range error
    		_Xout_of_range("invalid vector<T> subscript");
    		}
    

    Meldung: Unbehandelte Ausnahme bei 0x773C4878 in Projekt7.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x00F9FA00.

    Das sollte eig eins der kürzesten sein.

    Sowas passiert dann. Das ist einer der Fehler.



  • Das Beispiel soll auch crashen.

    Du gibst einen Zeiger auf die (funktions-)lokale variable lokalerMist zurück.
    lokalerMist wird aber in Z. 13 (zum Funktionsende) zerstört und der Zeiger zeigt nicht mehr auf einen "echten" vector .

    Bisher ist also alles in Ordnung. 🙂



  • 6th schrieb:

    Zum Beispiel sowas:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    vector<int>* Gruselstunde(const int& n, const int& val)
    {
      vector<int> lokalerMist(n); 
      for(int i=0; i<n; ++i)
      {
        lokalerMist.at(i) = val; 
      }
      return(&lokalerMist);
    }
    
    int main()
    {
      vector<int> *adresse_lokalerMist = Gruselstunde(5, 666);
      for(size_t i = 0; i<5; ++i) 
      {
        cout << adresse_lokalerMist->at(i) << endl;
      }
      return 0;
    }
    

    Es öffnet sich dann noch ein Tab mit dem Namen "vector":

    In Zeile 1965:

    [[noreturn]] static void _Xrange()
    		{	// report an out_of_range error
    		_Xout_of_range("invalid vector<T> subscript");
    		}
    

    Meldung: Unbehandelte Ausnahme bei 0x773C4878 in Projekt7.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x00F9FA00.

    Das sollte eig eins der kürzesten sein.

    Sowas passiert dann. Das ist einer der Fehler.

    Ich nehme mal an, dies ist ein Beispiel, wie man's nicht macht.

    In Zeile 12 wird die Adresse einer lokalen Variablen zurückgegeben. Die Adresse ist aber sofort nach dem Rücksprung ungültig und darf daher nicht benutzt werden.

    MERKE: Niemals Adressen oder Referenzen von lokalen Variablen zurückgeben.

    VG Martin



  • Das liegt daran, dass du einen Zeiger auf ein Objekt zurückgibst, das es nicht mehr gibt, da es nur ein lokales Objekt ist.
    Aus welchem der Bücher hast du das denn?

    Du kannst aber auch zum Beispiel den vector kopieren:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    vector<int> Gruselstunde(const int& n, const int& val)
    {
    	vector<int> lokalerMist(n);
    	for (int i = 0; i<n; ++i)
    	{
    		lokalerMist.at(i) = val;
    	}
    	return lokalerMist;
    }
    
    int main()
    {
    	vector<int> adresse_lokalerMist = Gruselstunde(5, 666);
    	for (size_t i = 0; i<5; ++i)
    	{
    		cout << adresse_lokalerMist.at(i) << endl;
    	}
    
    	return 0;
    }
    

    oder auch die Referenz verändern

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void Gruselstunde(vector<int> &lokalerMist, const int& n, const int& val)
    {
    	for (int i = 0; i<n; ++i)
    	{
    		lokalerMist.at(i) = val;
    	}
    }
    
    int main()
    {
    	const int size = 5;
    	vector<int> _lokalerMist(size);
    	Gruselstunde(_lokalerMist, size, 666);
    	for (size_t i = 0; i<5; ++i)
    	{
    		cout << _lokalerMist.at(i) << endl;
    	}
    
    	return 0;
    }
    

    Das ist eigentlich das Einfachste.



  • Vielen Dank. Ein EXTRA dank an Skylac06 für eine weitere Möglichkeit.

    Ich hab das aus dem Buch "Schrödinger programmiert C++". Da stand aber nicht, dass man das so NICHT macht. Da steht man kann es so machen. Deshalb bin ich etwas verwirrt gewesen. Hat jemand eine gute Quelle hat wie man seine Grundkenntnisse vertiefen kann bzw bei einem Projekt mit arbeiten kann oder woher ich Quellcode bekomme welches für Anfänger auch vertragbar ist? Ich habe nun Visual Studio neuinstalliert und viele Fehler sind nicht mehr da. Hat jemand das Buch von Heiko Kalista durchgearbeitet? Ich schaffe es einfach nicht das Programm zu kompilieren... immer ist was nicht definiert oder gefunden. Obwohl ich SDL eingebunden habe...

    PS: Weiß jemand gute Seiten/Tutorials für die Spielentwicklung speziell in C++ (ENGLISCH geht auch) die gut sind und auch relativ aktuell?



  • Schau mal, die Funktion heißt "Gruselstunde" und die Variable heißt "lokalerMist". Ich habe das Buch nicht gelesen, aber willst du uns hier wirklich erzählen, dass das ein Beispiel sein soll, wie es richtig gemacht wird? Bei diesen Bezeichnungen? Ernsthaft?

    Das ist ganz offensichtlich ein Beispiel wie es NICHT geht, und das Problem liegt ziemlich sicher bei deinem Leseverständnis. Auch beim besten Buch muss man ALLE WÖRTER lesen, wenn man es verstehen will. Lästig, aber leider notwendig.



  • 6th schrieb:

    Ich hab das aus dem Buch "Schrödinger programmiert C++".

    Das Buch würde ich erstmal zur Seite legen...scheint nicht so gut zu sein. (Das Beispiel ist viel zu komplex, schlecht programmiert und die Funktion Gruselstunde, selbst um den Fehler behoben, überflüssig.)

    6th schrieb:

    Ich habe nun Visual Studio neuinstalliert und viele Fehler sind nicht mehr da.

    Na ist doch prima. Dann nimm doch jetzt erstmal den Breymann - der hat wohl ausser einem Compiler keine Voraussetzungen und Du kannst sofort loslegen!
    Schau gleich mal nach, was da zum Thema std::vector steht - und wie Du das gesamte Gruselstundeprogramm in 3-4 Zeilen abfrühstücken kannst.



  • Ich habe mir mal die Mühe gemacht, und mir das Buch besorgt... meine Fresse, ist das ein unlesbarer Haufen Scheiße. Mehr lustige Bildchen als Text, und das Layout macht schlimmeren Krebs als ein Surfausflug vor Fukushima.

    Augenkrebs erklärt dann vielleicht auch, wieso der TE die extrem subtilen Hinweise und Erklärungen nicht sehen konnte.



  • alpha telefon schrieb:

    Ich habe mir mal die Mühe gemacht, und mir das Buch besorgt... meine Fresse, ist das ein unlesbarer Haufen Scheiße. Mehr lustige Bildchen als Text, und das Layout macht schlimmeren Krebs als ein Surfausflug vor Fukushima.

    Augenkrebs erklärt dann vielleicht auch, wieso der TE die extrem subtilen Hinweise und Erklärungen nicht sehen konnte.

    Finde ich ja toll, dass der Autor zur Lösung des Problems globale Variablen, unique_ptr, auto_ptr und sogar static ins Feld führt, aber die hier einzige sinnvolle Lösung unterschlägt (vector<int> zurückgeben).



  • alpha telefon schrieb:

    Ich habe mir mal die Mühe gemacht, und mir das Buch besorgt... meine Fresse, ist das ein unlesbarer Haufen Scheiße. Mehr lustige Bildchen als Text, und das Layout macht schlimmeren Krebs als ein Surfausflug vor Fukushima.

    Frag mich was du hast, das ist ein Buch für Anfänger. - Als solches finde ich es eigentlich ziemlich gut.

    Auch steht im oberen Bereich der Seite, das man eben keine Referenz zurück geben soll. Also alles gut.


  • Mod

    ;brq schrieb:

    Finde ich ja toll, dass der Autor zur Lösung des Problems globale Variablen, unique_ptr, auto_ptr und sogar static ins Feld führt, aber die hier einzige sinnvolle Lösung unterschlägt (vector<int> zurückgeben).

    Wobei hier die kanonische Lösung wäre, dass der Nutzer einen Outputiterator angibt. Solange man das konsequent von Anfang an täte, wäre das auch anfängerfreundlicher als es zunächst klingt. Gewiss mindestens so verständlich wie unique_ptr und auto_ptr (deprecated). static und globale Variablen zur Rückgabe zu Missbrauchen würde ich sogar einen groben Fehler nennen. Man löst damit ein kleines Problem und bekommt dadurch viel größere Probleme¹ an anderer Stelle.

    ¹: Die Funktion ist dann nicht mehr threadsicher; höchstwahrscheinlich nicht reentrant; darf nicht mehr aufgerufen werden, bevor das Ergebnis verwertet wurde; und ist allgemein die Hölle zu debuggen.



  • Mich interessiert mal die folge Seite. Eventuell wird dort ja noch erklärt, wie man es richtig macht.



  • inflames2k schrieb:

    Frag mich was du hast, das ist ein Buch für Anfänger. - Als solches finde ich es eigentlich ziemlich gut.

    Design und Layout sind furchtbar. Sieht aus wie ein Kinderbuch, übersäht mit unnötigen Cliparts und deplazierten Zeichnungen auf jeder Seite. Überall bunte Schrift, deren Farbe alle drei Seiten wechselt, und kindische Metaphern. Wirkt auf mich wenig seriös und nicht lesbar. Ich würde mir das nicht antun. Für Kinder wäre es vermutlich okay.

    Inhaltlich habe ich keine Meinung, weil ich es nicht gelesen habe.

    Mich interessiert mal die folge Seite. Eventuell wird dort ja noch erklärt, wie man es richtig macht.

    Nope. Die nächste Seite zeigt das gleiche Problem mit Referenzen.


Anmelden zum Antworten