Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

TigerClaw25

unregistriert

21

06.07.2017, 13:20

Eine kurze Sache noch. Es wird oft geschrieben, dass Zeiger wie Variablen sind, nur eben für die Aufnahme von Adressen bestimmt.

Folgendes Beispiel verwirrt mich jedoch:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
CSpieler *pSpielerliste = NULL;
int AnzahlSpieler = 0;

cout << "Wie viele Sppieler: " ;
cin >> AnzahlSpieler;

// Speicher auf dem Heap für CSpieler reservieren. 
pSpielerliste = new CSpieler[AnzahlSpieler];


pSpielerliste ist im Prinzip eine Zeigervariable. Mit "pSpielerliste = new CSpieler[AnzahlSpieler];" sage ich dann, dass dieser Zeiger "pSpielerliste" 4 Instanz-Adressen aufnehmen kann? Oder ist das Prinzip eher so, dass durch "pSpielerliste = new CSpieler[AnzahlSpieler]" der Zeiger pSpielerliste auf die Adresse des ersten Elements zeigt und ich dann mit *(pSpielerliste+1) dann einfach zur nächsten Adresse des nächsten Elements springe? Denn wenn ich das richtig verstehe, bin ich mit einem Zeiger in der Lage, durch ein Array zu wandern, ohne das ich mir eine Art Zeiger-Array erstellen muss.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

22

06.07.2017, 13:25

Richtig, Zeiger enthalten Adressen. Eine Zeigervariable ist aber ansonsten eine ganz normale Variable.
new CSpieler[AnzahlSpieler] reserviert einen zusammenhängenden Speicherbereich für AnzahlSpieler Instanzen der Klasse CSpieler, konstruiert diese Objekte (durch Aufruf des Standardkonstruktors) und liefert die Adresse der ersten.
Richtig, mit einem Zeiger kannst du durch ein Array "wandern", wenn du weißt, wo du aufhören musst.
In einem echten Projekt würde man aber eher einen Container wie std::vector verwenden, um die Instanzen zu verwalten anstelle eines Arrays.

TigerClaw25

unregistriert

23

06.07.2017, 13:43

Verstanden :)

Anfangs ist es verwirrend, da es auch verschiedene Wege gibt, um beispielsweise auf die Werte der einzelnen Elemente eines Arrays über Zeiger zuzugreifen wie

C-/C++-Quelltext

1
pSpielerliste[i].foo(); 

oder alternativ

C-/C++-Quelltext

1
*(pSpielerliste+i).foo();
.

Ich dachte vieles auswendig lernen zu müssen. Aber mit Logik erklärt sich vieles von selbst.

Beispiel: int *ptr = &x;
Bei der Deklaration zeigt der Zeiger ohne Initialisierung auf irgend eine Adresse. Daher muss logischerweise auch der &-Operator bei einer Initialisierung verwendet werden.

Erfolgt jedoch nur eine Deklaration mit "int *ptr", wird bei der Zuweisung einer Adresse eben ohne "*" gearbeitet: ptr=&x. Bisher habe ich versucht das Ganze auswendig zu lernen. Wenn man jedoch die grundlegende Arbeitsweise versteht, ist es um einiges einfacher :)

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

24

06.07.2017, 13:53

Aus dem Standard:

Zitat

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))

Das bedeutet, dass *(pSpielerliste + i), pSpielerliste[i] und i[pSpielerliste] das gleiche bedeuten*. Letzteres sieht komisch aus, ist aber völlig in Ordnung.

* Solange es sich bei pSpielerliste um einen Zeiger handelt und bei i um einen integralen Typ.

TigerClaw25

unregistriert

25

06.07.2017, 14:00

Hast du für mich einen sinnvollen Tipp bezüglich Bücher? "C++. Der Einstieg" hat mir viele wertvolle Fragen beantwortet. Jedoch überliest man vieles, wenn man nicht experimentiert und sich selber Fragen stellt. "C++ Primer von Lippman" ist zwar in englisch, aber gut bewertet. Was denkst du? "Der C++ Programmierer von Breymann" hat inhaltlich zwar auch viel zu bieten, ist aber etwas merkwürdig verfasst und lässt sich nur stockig lesen ...

Ah kleine Anmerkung noch zu "new". Im Buch wird ein beispiel genannt, bei dem zur Laufzeit ein Array erzeugt wird:

C-/C++-Quelltext

1
2
CKlasse *pSpielerliste=NULL;
pSpielerliste = new CKlasse[Anzahl]


Den Sinn des Beispiels verstehe ich nicht, denn ohne den Befehl "new" kann ich das ebenfalls tun:

C-/C++-Quelltext

1
2
const int Anzahl = 5;
CKlasse Spielerliste[Anzahl];


Ist der Grund der, dass die Anzahl im zweiten Beispiel "const" sein muss, und im ersten Beispiel ich sozusagen selbst den Wert während der Laufzeit bestimmen kann?

Das die lokalen variablen ihre Gültigkeit verlieren, ist für mich kein Argument. Das tun die Zeigervariablen auch, wenn ich die Adresse nicht anders auffange.

Also worin liegt genau der Sinn der "dynamischen Speicherverwaltung"? Ok, ich habe mit new einen Typ und eine Größe. Bennenen muss ich das Objekt nicht. Das ist für mich aber noch nicht dynamisch.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »TigerClaw25« (06.07.2017, 15:52)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

26

06.07.2017, 17:10

Ist der Grund der, dass die Anzahl im zweiten Beispiel "const" sein muss, und im ersten Beispiel ich sozusagen selbst den Wert während der Laufzeit bestimmen kann?

Genau.

Das die lokalen variablen ihre Gültigkeit verlieren, ist für mich kein Argument. Das tun die Zeigervariablen auch, wenn ich die Adresse nicht anders auffange.

Ja, die Zeigervariable verliert ihre Gültigkeit, aber wenn du den Speicher mit new reserviert hast (oder mit malloc o. Ä.), dann bleibt der auch weiterhin für dich reserviert und gültig. Ein lokal angelegtes Array hingegen "verschwindet".

Also worin liegt genau der Sinn der "dynamischen Speicherverwaltung"? Ok, ich habe mit new einen Typ und eine Größe. Bennenen muss ich das Objekt nicht. Das ist für mich aber noch nicht dynamisch.

Dynamisch in dem Sinne, dass du vorher (= in dem Moment, wo du das Programm schreibst) nicht wissen musst, wie viel Speicher du benötigen wirst, sondern dass das zur Laufzeit entschieden wird. Du kannst Speicher zur Laufzeit reservieren und wieder freigeben, sobald du ihn nicht mehr brauchst. Viele Dinge lassen sich ohne dynamische Speicherverwaltung nicht schön lösen. Stell dir beispielsweise ein Bildbearbeitungsprogramm vor. Wenn der Benutzer ein sehr großes Bild öffnet, brauchst du auch sehr viel Speicher für die ganzen Pixel. Ohne dynamische Speicherverwaltung müsstest du eine feste Menge an Speicher reservieren, die dann gleichzeitig eine obere Grenze darstellen würde, beispielsweise 1 Gigabyte. Dann würde das Programm aber immer diese 1 Gigabyte an Speicher belegen, auch wenn du nur ein popeliges 16x16 Pixel großes Bild lädst.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

27

06.07.2017, 17:35

Das die lokalen variablen ihre Gültigkeit verlieren, ist für mich kein Argument. Das tun die Zeigervariablen auch, wenn ich die Adresse nicht anders auffange.
Na ja, nein. Der Zeiger mag seine Gültigkeit verlieren, aber die im Heap angelegte Variable lebt weiterhin und bewirkt irgendwas, was niemand anders überwachen müsste und daher auch niemand mehr den Pointer dahin bräuchte (wozu auch immer sowas gut sein könnte, man weiß ja nie). Eine Variable im Stack wird zerstört und ruft den Destruktor, wenn der Block verlassen wird. Das ist ein riesiger Unterschied. Sogar noch schlimmer, während sie im Stack weggeräumt wird, bleibt sie im Heap auch dann am Leben, wenn du das vielleicht gar nicht wolltest. So enstehen dann Memory-Leaks.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

28

06.07.2017, 17:41

Hast du für mich einen sinnvollen Tipp bezüglich Bücher?

Der C++ Programmierer ist tatsächlich etwas merkwürdig geschrieben. Schöner liest sich dieses Buch(C++ eine Einführung). Es ist auch wieder von Breymann geschrieben, aber viel viel simpler. Guck einfach mal durch das Inhaltsverzeichnis.
Dieses Buch(Effektives modernes C++) kenne ich selbst nicht, jedoch den Vorgänger(Effective C++). Das Buch war wirklich gut und hat viele gute Tipps gehabt. Die Grundlagen sollten dafür aber unbedingt sitzen, ansonsten kannst du damit relativ wenig anfangen.
Das hier(C++ Programming Language) ist auch wirklich gut, aber auch nichts was man so nebenher runter liest. Es wird auf extrem viele Einzelheiten von C++ eingegangen und hilft dabei das schon vorhandene Verständnis weiter auszubauen.

Die Bücher sollte es alle sowohl auf deutsch als auch auf englisch geben.
Wichtig ist dass du selbst viel programmierst. Zum Beispiel kannst du dir SFML schnappen und mal ein simples Spiel entwickeln. Außerdem solltest du dich mit der Standardbibliothek vertraut machen. In deinem Buch sind da mehrere Kapitel zu vorhanden, das andere von Breymann und das von Stroustrup behandeln das Thema aber auch.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige