Wie lernt man C++ in 12 Tagen?
Okay, ich habe vor, C++ in 12 Tagen zu lernen.
Kurzer Rücksicht: Ich kann die Grundlagen wie if statements, while-Schleife / for, etc. und natürlich Ein-/Ausgabe und die verschiedenen Datentypen schon. Aber ich kann sie nicht anwenden.
Zum Beispiel eine Programmieraufgabe kann ich nicht leicht lösen.
Also das nennt man anscheinend Tutorial hell oder so. Wie kann ich raus? Bitte sendet Hilfe!
5 Antworten
Learning by doing.
Überlege dir ein Projekt welches im Grunde einfach ist, aber viel Potenzial zur Erweiterung hat. Beispielweise ein Taschenrechner:
Fang an damit einen Taschenrechner zu basteln, der über die Konsole zahlen und Rechenart eingegeben bekommt und dann die Rechnung ausgibt mit Ergebnis. Erstmal nur Grundrechenarten.
Dann kannst du nach und nach weitere komplexere Rechenoperationen ergänzen und die Eingabe und Ausgaben erweitern. So zB mit einer grafischen Darstellung, rechnen mit Funktionen, zeichnen von Graphen etc. Optimiere dabei stets deinen Code und überlege wie man es noch machen kann.
Dabei lernst du viele Sachen kennen.
Alles wirst du so nicht lernen, aber genug um damit arbeiten zu können und den Rest lernst du nach Bedarf
Nach den Grundlagen halbwegs können einfach selber oder für Andere Projekte realisieren. Programmieren besteht keineswegs allein aus Programmieren können (was Viele denken) sondern auch in der realen Anwendung. Dazu gehört auch Kommunikation mit Auftraggebern und Verstehen der Prozesse samt Erkennen von Verbesserungspotenzial.
Mit einem Ziel vor Augen wird das Lernen viel effektiver, wenn auch kaum in 12 Tagen fertig.
- ordne zuerst dein Wissen ein: kategorisiere alles was du gelernt hast: Variablen, Bedingungen, Schleifen, …; somit hast du einen Überblick und du kannst auch füllen was dir fehlt
- versuche einzelne Sachen miteinander zu kombinieren, bsp einen Zähler mithilfe einer Variable und einer Schleife
- schaue vorgefertigte Lösungen oder auch real-life Code von anderen an und versuche sie in ihre Einzelteile zu zerlegen und nachzuvollziehen
- übe mehr (‚Learn by doing‘). Wenn was falsch ist, versuche den Grund dafür zu finden
du wirst sicherlich die Basics im Nu meistern! Und wenn du dann soweit bist, schaue dir mehr fortschrittliche Themen an. Good luck, ajkcdajefiu!
Sind die 12 Tage und C++ fix? Also brauchst Du das für eine Prüfung oder so? Wenn nicht, dann rate ich dazu C# oder Java statt C++ nu nehmen. Das ist also erste Sprache deutlich einfach, da Dir die Speicherverwaltung abgenommen wird, und Du Dich erstmal auf Dein Kernproblem konzentrieren kannst. Um der Tutorial Hell zu entkommen, schnapp Dir irgendein Programm das Du schon mal gemacht hast und fange an das abzuändern. Eine Zeile zu ändern ist viel einfacher als auf eine leere Textdatei zu starten. Und dann arbeitest Du Dich Stück für Stück vor, und zwar in dem Tempo das Du brauchst. Das wird mehr als 12 Tage dauern.
Mit Smartpointern ist es am Ende so wie mit einem GC.
Mach zB unique_ptr<int> ptr = new int[10]; und du brauchst dich um nichts mehr weiters kümmern.
Sobald der Pointer den Scope verlässt erfolgt automatisch die Freigabe ähnlich wie in C# mit dem GC.
Also Memoryleaks mit modernem C++ sind recht schwierig hinzubekommen so auch wie use after free.
Natürlich muss man dafür aber dann beim smart pointer bleiben und keinen Raw Pointer ableiten oder Referenzen verwenden.
Hm, mein letztes c++ projekt ist zugegebenermaßen schon 15 Jahre her. Damals gab es zwar jede Menge Unterstützung in Form von Smart Pointern, Boost etc. aber wenn man sie nicht genutzt hat, dann konnte man problemlos einen Pointer auf ein Stackelement returnen und solche Scherze. Ist das mittlerweile ein Kompilierfehler?
Nein das geht nach wie vor. Aber geht theoretisch in C# auch.
Also beide Sprachen erlauben aufgrund von legacy unterstützung die allocierung von Speicher an diese Elementen vorbei.
Bei C# gibt es dafür zB Marshal.AllocHGlobal und jede Klasse welche das IDisposable Interface implementiert macht das um so einen Speicher freizugeben. Meistens steckt dahinter Interface Code zu einer anderen Bibliothek deren Speicher nicht durch den GC verwaltet wird.
In C# ist das Freigeben von Unmanaged Speicher natürlich auch nicht vom GC erfasst, daher ist es hier auch unglaublich wichtig using Direktiven für Klassen mit IDisposable zu verwenden sonst hat man hier auch schnell ein Speicherleck.
Weiters gibt es in C# auch den unsafe Kontext. Mit dem kann man Bereichsüberprüfungen umgehen und Pointer wie in C++ verwenden und auch zurückgeben ohne Rücksicht auf den Lifecycle. Der Grund dafür ist weil das idR schneller ist und daher in Performancekritischen Bereichen teilweise verwendet wird.
Es ist also im Endeffekt immer eine Frage des Codestyles und der best Practice ob man sich mit dem Speicher auseinandersetzen muss oder nicht.
Ja klar kann man das in C# und auch in Java umgehen. Man muß dafür aber schon ein bißchen Aufwand betreiben um den GC zu umgehen. Das passiert nicht aus Versehen bei einem Anfänger, der gerade versucht mittels if/else, while und for eine einfache Aufgabe zu lösen und damit Schwierigkeiten hat. Bei dem Wissensstand hat man bei C/C++ glaube ich noch immer einen schwereren Stand, wenn der Compiler da keinen Blödsinn verhindert.
Ich würde mal sagen es ist eher die Frage nach welchen Tutorials man da geht.
Bei uns gibt es zB die Guidelines:
- Keine nackten Pointer auf allocierten Speicher
- Parameterübergabe per Referenz, Copy oder Move, niemals per Pointer
- Wenn es nicht anders geht Pointer nur auf globalen Speicher.
- Kein Return von Pointern oder Referenzen (außer man überlegt sich genau was man tut, in den meisten Fällen kommt man aber drum rum)
Wenn man sich daran hält verhindert der Compiler das meiste bzw kümmert sich darum.
Wenn ich natürlich jetzt in C++ irgendein Tutorial von 99 verwende dann steht das natürlich nicht drinnen, aber dann findest du für C# auch so einen Code:
Filestream stream = File.Create("somefile");
Das ist auch in C# ein Speicherleck es sei denn es kommt ein
stream.Dispose();
hinten drann und selbst da hat man noch das Problem dass eine Exception das Dispose überspringt. Hier muss ein neurer Tutorial verwendet werden mit dem Code
using Filestream stream = File.Create("somefile");
Weiterer common mistake in C# ist dieser Code in einer Schleife
event += (object, sender) { do something; }
Das ist genau so ein Speicherleck. Letzteres ist sogar im Manged Codespace.
Der GC maskiert das Problem maximal teilweise verhindert aber Memoryleaks nicht vollkommen. Schlimmer noch der GC gibt Anfängern ein falsches Gefühl von Sicherheit was dann genau oben genannte Fehler eher begünstigt.
Wirklich effektiv schützen kann man sich in beiden Sprachen nur durch best practice und verschiedene Regeln an welche man sich halten sollte.
Du bist das glaube ich schon viel zu weit. Der Fragesteller ist noch gar nicht bei irgendwelchen Handlern, noch lange nicht. Der ist noch auf dem Niveau »Du bekommst ein Array mit Ints. Gebe die größte und die kleinste Zahl auf dem Bildschirm aus«. Da geht's wirklich erstmal darum zum Ziel zu kommen.
Ja eben und genau da nimm ein modernes C++ Tutorial mit dem Code
template<size_t length>
print_array(const std::array<int, length>& buffer)
for(const auto& data : buffer)
cout << data;
Der Code ist Typsicher und auch Speichersicher. Und zudem schnell weil der Compiler hier implizit loop unrolling machen wird.
Man kann natürlich sagen in C# muss man weniger schreiben, aber wie gesagt es kommt meiner Meinung darauf an wie man es lernt.
Ich habe direkt in C gestartet und bin dann zu C++ gewechselt ohne hier Probleme in C++ gehabt zu haben die ich in C# zB nicht gehabt hätte.
Die meisten Probleme die ich in C++ habe sind eigentlich im Embedded Bereich wo dynamischer Speicher beinahe gar nicht erlaubt ist. Dann wirds spannend denn da muss man teilweise kreativ werden.
Hm, müßte mir mal den aktuellen c++ standard angucken. Ich denke aber nicht aber nicht, daß ich danach c/c++ als erste Sprache empfehlen würde ;-)
Die meisten Probleme die ich in C++ habe sind eigentlich im Embedded Bereich wo dynamischer Speicher beinahe gar nicht erlaubt ist. Dann wirds spannend denn da muss man teilweise kreativ werden.
Oh ja, ich erinnere mich dunkel. new und delete von hand implementieren, aber vorzugsweise nicht mit malloc/free sondern mit einem großen struct auf dem Stack der als Heap-Ersatz gilt, und new/delete belegen dann nur slots auf dem Struct, damit der begrenzte Speicher deterministisch ausreicht. Solche Scherze hatten wir damals auch auf Atmega und STM32.
Im aktuellen hast du einige Hilfen dabei die auch bei C# neu sind zB bei C++ 20 Ranges was ähnlich ist wie Span bzw Memory in C#
Im wesentlichen sind das Wrapper auf Speicherbereiche sodass diese ihre Länge kennen. Damit entfallen Konstrukte wie:
int function (const int * data, size_t length)
Außerdem gibt es damit auch eine Linq ähnliche syntax.
Einige Code Standards müssen komplett ohne dynamischen Speicher auskommen. Das bedeutet jeder Globale Speicher muss zur Compilzeit bekannt sein der Rest muss am Stack sein.
Pooling etc geht zum Teil hängt hier aber von der funktionellen Sicherheit ab. Sobald man Speicher aus einer Liste nimmt muss man nachweisen, dass entweder immer genug da ist und/oder dass out of memory ein valider Zustand ist und letzteres ist extrem schwierig.
Den += anonymer delegate kriegst du nie wieder deregistriert ich weiß nicht warum der reshaper sowas vorschlägt, entweder musst du eine Referenz halte und dieselbe deregistrieren oder eine richtige Methode machen.
Ja richtig daher hab ich ja geschrieben, dass das ein beliebter Fehler ist.
ich kann die Basics schon [...]. Aber ich kann sie nicht anwenden.
Dann wäre es wohl gescheiter, sich primär mit den Grundlagen der Programmierung zu beschäftigen. Dabei brauchst du keine Programmiersprache! Wenn das sitzt, ist die Sprache reichlich egal und lediglich noch das Erlernen der Syntax.
Genau genommen nimmt dir C++ auch die Speicherverwaltung ab. Du kannst speicher in C++ eben auch neben den ganze Smartpointer usw vorbei erstellen aber das geht in C# genau so mit den selben Problemen.
Wichtiger ist es bei C++ ein Tutorial mit modernem C++ zu finden.