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

1

04.07.2017, 16:17

Zeiger und Referenzen - Aussage im Buch

Hallo Zusammen,
ich habe eine kurze Anmerkung zu Kapitel 6: Zeiger und Referenzen. Dort gibt es am Ende des Kapitels eine Übersicht über Parameterübergabe als Wert, per Zeiger und als Referenz. Jedoch denke ich, dass die Aussage zu "Call by Value" nicht ganz richtig ist. Im Buch steht, dass das sinnvoll ist, wenn Standard-Datentypen an eine Funktion übergeben werden, die nicht geändert werden müssen wie beispielsweise das Anzeigen eines Levels. Jedoch fehlt etwas. Es wird nicht erwähnt, in wie fern die Verwendung von "return" sinnvoll ist. Möchte ich eine kleine Zwischenrechnung machen, wäre die Übergabe als Wert mit einem "return" sinnvoll. Klar kann man das auch per Zeiger tun, aber für eine einzige int-Variable wäre der Aufwand doch auch zu hoch oder was denkt ihr?

An der Aufgabe 6.10 ist mir außerdem aufgefallen, dass für die Berechnung der Punkte die komplette Struktur als Zeiger übergeben wird:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct S_Spieler {
    int Energie;
    int Punkte;
    int Team;
};

//Prototypen
void BerechnePunkte(S_Spieler *Spieler, const int Bonus){
    cout << "Es gibt " << Bonus << " Bonuspunkte dazu!" << endl;
    Spieler->Punkte += Bonus;
}

int main(){
    S_Spieler Spieler1;
    Spieler1.Energie = 1000;
    Spieler1.Punkte = 0;
    Spieler1.Team = 1;

    int Bonus = 550;
    int Level = 7;

    BerechnePunkte(&Spieler1, Bonus);
    
    return 0;
}
    

Hätte man nicht auch einfach nur die Strukturvariable "Punkte übergeben können: ?"

C-/C++-Quelltext

1
2
3
4
5
6
7
8
void BerechnePunkte(int *p_Punkte, int Bonus){
    cout << "Es gibt " << Bonus << " Bonuspunkte dazu!" << endl;
    *p_Punkte += Bonus;
}

... 
...
    BerechnePunkte(&Spieler1.Punkte, Bonus);



Dann hätte ich noch eine kurze Fragen zu Call by Value und dem Stack. Wie genau funktioniert das jetzt?

Funktion mit Parameterübergabe aufrufen -> Parameterwert wird in den Stack gelegt -> Funktion selbst erzeugt neue Variable an irgend einer Adresse und holt sich den Wert ?

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »TigerClaw25« (04.07.2017, 16:26)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

04.07.2017, 16:35

Erste Frage: "Aufwand zu hoch" ist nie ein gutes Argument, um etwas by Value, by Reference oder als Pointer zu übergeben. Es kommt darauf an, was man erreichen will und wie groß das Ding ist, was man übergibt - hier gilt übrigens, dass allein die Größe *nicht* ausreicht, um zu entscheiden, auf welche Art man es übergibt. Dazu gibt es eine sehr lange Liste im ISO-C++ Guide.

Zweite Frage: Was ist eine Strukturvariable? Falls du 'by value' meinst, dann ginge das in diesem Beispiel nicht ohne ein Return, weil "Punkte" ja nur ein kopierter Wert ist und eine Änderung dieses Werts folglich nur innerhalb der Funktion eine Auswirkung hat. Übrigens ist es sehr schlechter Stil Eingabe-Parameter innerhalb der Funktion zu ändern.

Dritte Frage: Jeder Parameter wird auf den Stack gelegt. Lokale Variablen ebenfalls. Es macht für die Funktion also keinen Unterschied, ob sie auf eine lokale Variable zugreift oder auf einen Parameter, die sind nur ein paar Byte-Adressen auseinander im Stack. Genau genommen könnte eine Funktion somit sogar auf die Parameter oder lokalen Variablen der aufrufenden Funktion zugreifen. Solche Hacks sollte man aber lieber lassen. Im Fall eines Value-Parameters wird der Inhalt kopiert in den Stack gelegt. Im Falle eines Pointers oder einer Referenz nur die Adresse der übergebenen Variablen. Daraus ergibt sich offenbar die Problematik, dass ich zu einem reinen Wert [also z.B. beim Aufruf von foobar(5);] gar keinen Pointer übergeben kann (die Zahl 5 hat schließlich keine Adresse, sondern ist eine Konstante.
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]

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

04.07.2017, 16:39

Es wird nicht erwähnt, in wie fern die Verwendung von "return" sinnvoll ist. Möchte ich eine kleine Zwischenrechnung machen, wäre die Übergabe als Wert mit einem "return" sinnvoll. Klar kann man das auch per Zeiger tun, aber für eine einzige int-Variable wäre der Aufwand doch auch zu hoch oder was denkt ihr?

In dem Teil des Buches ging es wahrscheinlich um die Übergabe an eine Funktion, nicht um die Rückgabe von einer Funktion an denjenigen, der sie aufgerufen hat.
Zeiger oder Referenzen als Parameter, die von der Funktion "zu füllen" sind, benutzt man meistens dann, wenn eine Funktion mehrere Rückgabewerte erzeugt und man diese nicht in einer Struktur oder Klasse kapseln möchte. Manche Leute benutzen auch den Rückgabewert nur um anzuzeigen, ob es geklappt hat oder nicht (aber hier wären eher Exceptions zu empfehlen) und lösen die Übergabe der eigentlichen Daten immer über Zeiger/Referenzen. Einen Zeiger zu diesem Zweck benutzt man, wenn man durch Setzen auf Null signalisieren können möchte, dass man nicht an dem Wert interessiert ist (so dass die Funktion ihn gar nicht erst berechnen muss).

Hätte man nicht auch einfach nur die Strukturvariable "Punkte übergeben können: ?"

Ja, das wäre hier auch gegangen (so wie du es in deinem Code gezeigt hast). Es gibt nicht immer die richtige Lösung. Meistens gibt es bessere und schlechtere Lösungen, aber darüber kann man sich streiten.

Dann hätte ich noch eine kurze Fragen zu Call by Value und dem Stack. Wie genau funktioniert das jetzt? Funktion mit Parameterübergabe aufrufen -> Parameterwert wird in den Stack gelegt -> Funktion selbst erzeugt neue Variable an irgend einer Adresse und holt sich den Wert ?

Such mal bei Google nach "how does a function call work in c", dann wirst du viele Informationen finden.

TigerClaw25

unregistriert

4

04.07.2017, 16:39

Mit Strukturvariable meine ich die Variablen innerhalb der Struktur ;)

@David Scherfgen
Beim Programmieren ist es so, dass man anfangs unsicher ist, ob die eigene Lösung überhaupt Sinn ergibt. Ich hatte mir überlegt, dass nach der Erzeugung einer Instanz S_Spieler und der Initialisierung der Variablen bereits Speicher reserviert ist und demnach auch Adressen zugewiesen sind. Daher hatte ich für die Lösung lediglich .Punkte übergeben per Zeiger übergeben statt die gesamte Struktur, obwohl es an sich keine Unterschied macht.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

04.07.2017, 16:41

Mit Strukturvariable meine ich die Variablen innerhalb der Struktur ;)

Du meintest einen Zeiger darauf, jedenfalls hast du das in deinem Code geschrieben.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

04.07.2017, 16:43

Du hättest auch einen Zeiger direkt auf Spieler1.Punkte übergeben können, klar. Allerdings ist das semantisch eventuell fragwürdig, da man damit ja einen Pointer auf jeden beliebigen Int übergeben könnte, was semantisch völliger Unsinn wäre.
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]

TigerClaw25

unregistriert

7

04.07.2017, 16:46

Genau. Mein Problem ist, dass ich demnächst im Bereich der Softwareentwicklung Embedded Systems tätig sein werde und ich einen schnellen Einstieg in C++ finden möchte. Dein Buch ist da ideal.Parallel dazu nutze ich Der C++ Programmierer von Breymann zum Nachschlagen. Aber manchmal hinterfrage ich einfach zu viel und dann komme ich durcheinander ;)

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

04.07.2017, 16:47

Dein Buch ist da ideal.

Der Autor ist Heiko Kalista. Leider ist er schon sehr lange nicht mehr hier im Forum aktiv.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

04.07.2017, 16:48

ich einen schnellen Einstieg in C++ finden möchte.
Nichts gegen Heiko, aber für modernes und sauberes C++ solltest du sein Buch nicht unbedingt heranziehen ;) Ich denke er würde das heute ähnlich beurteilen.
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]

TigerClaw25

unregistriert

10

04.07.2017, 16:49

Stimmt, das andere Buch zum Thema 3D war von dir, schade, dass es dazu keine aktuelle Ausgabe gibt.

"Nichts gegen Heiko, aber für modernes und sauberes C++ solltest du sein Buch nicht unbedingt heranziehen ;) Ich denke er würde das heute ähnlich beurteilen. "
Um die wichtigsten Grundlagen zu überfliegene, ist es für diese kurze Einarbeitungszeit ideal. Daher auch der Breymann parallel dazu und alles andere lerne ich in der Praxis. Der Job hat sich spontan ergeben und mit dem Buch komme ich am schnellsten ans Ziel. Parallel dazu überfliege ich auch im C++ Primer und Breymann jedes Thema noch einmal. Am Ende ist es aber die Praxis, bei der man sinnvoll lernt.

Werbeanzeige