Thesi
Lt. Junior Grade
- Registriert
- Mai 2009
- Beiträge
- 259
Hallo CB-Community,
ich habe mich daran gewagt C++ zu lernen und stehe noch ganz am Anfang.
Vorab: Ich weis, dass es sehr viel Text ist, aber ich hoffe dennoch, dass sich jemand findet, der sich Zeit nimmt und mir helfen kann. Vielen Dank schon mal!!
Die wichtigen Stellen im Code, sind der struct, main(), dateneingabe() und alterscheck();
Frage steht ganz unten in fett, damit sie sich vom restlichen Text abhebt.
Ich habe im Internet eine Aufgabe gefunden bei dem ein Glücksspiel programmiert werden soll, bei dem eine Zufallszahl generiert wird und dann 2 Spieler eine Zahl eingeben. Derjenige, der näher an der Zahl dran ist gewinnt.
Ich habe das ganze etwas abgewandelt. Es gibt nur einen Spieler, der um einen gewissen Einsatz gegen das Casino spielt. Somit wird nur die Zahl des Spielers über die Konsole eingegeben. Die Zahl des Casinos und die "Gewinnzahl" werden zufällig generiert.
Hiermit hatte ich auch in meiner ersten Version keine Probleme. Allerdings hatte ich dort sehr viel in der main Funktion stehen.
funktionierende Version 1:
Da ich aber immer wieder lese, dass man möglichst wenig in die main Funktion schreiben soll, um seinen Code zum einen besser lesbar zu gestalten und zum anderen um einzelne Funktion besser wiederzufinden, wollte ich die Dateneingabe und den Alterscheck auslagern.
Hierbei hatte ich das Problem, dass er immer wieder in den Fall "ialter<18" gelaufen ist, auch wenn man ein Alter >18 eingegeben hat.
Hier der Code dazu:
nicht funktionierende Version 2:
Ich habe mir dann an verschiedenen Stellen im Code den Wert und die Speicheradresse von ialter ausgeben lassen.
Hierbei bin ich dann darauf gestoßen, dass die Speicheradresse für spieler.ialter in Main eine andere ist als spieler.ialter in dateingabe().
Allerdings ist die Speicheradresse für spieler.ialter in dateneingabe() und alterscheck() die gleiche.
Meine Lösung für das Problem war, dass ich im struct Spieler für jede Variable noch einen Pointer angelegt habe und die Dateneingaben dann über die Pointer gelöst habe. Damit funktionieren die ausgelagerten Funktionen auch einwandfrei.
Funktionierende Version 3:
Jetzt zur eigentlichen Frage.
Kann mir jemand das mit Speicherzuweisung erklären? Ich verstehe das nicht.
Ich erzeuge doch das Objekt spieler in Main. Damit werden dann doch auch automatisch die Variablen ialter etc. für diese Spielerinstanz angelegt und ihnen eine Speicheradresse zugewiesen.
Dann übergebe ich dieses Spieler-Element an die anderen Funktionen.
Wieso haben die Variablen dann in dateneingabe() eine andere Speicheradresse?
Dies bedeutet ja, dass diese Variablen neu angelegt wurden und zwar an einer anderen Speicheradresse. Somit existiert spieler.ialter 2 Mal.
Einmal in der Speicheradresse von der Main Funktion und einmal in der Speicheradresse von den externen Funktionen,
Wie kann das aber sein, wenn ich nur 1 Instanz vom Typ Spieler erzeuge?
Ich versteh es einfach nicht
Edit: gerade beim Absenden des Posts ist mir noch eine Idee gekommen, welche auch funktioniert.
Wenn ich alterscheck(spieler) nicht in Main aufrufe sondern in dateneingabe(), dann funktionier alles ohne Pointer.
Allerdings löst das mein Verständnisproblem mit den unterschiedlichen Speicheradressen von main und den anderen Funktionen immer noch nicht
Ansonsten bin ich auch offen für jeden weiteren Tipp bzgl. meines Codes, da ich ja noch ganz am Anfang meines Lernweges stehe.
Nochmal vielen Dank an diejenigen, die sich alles durchgelesen haben!!!
Gruß
thesi
ich habe mich daran gewagt C++ zu lernen und stehe noch ganz am Anfang.
Vorab: Ich weis, dass es sehr viel Text ist, aber ich hoffe dennoch, dass sich jemand findet, der sich Zeit nimmt und mir helfen kann. Vielen Dank schon mal!!
Die wichtigen Stellen im Code, sind der struct, main(), dateneingabe() und alterscheck();
Frage steht ganz unten in fett, damit sie sich vom restlichen Text abhebt.
Ich habe im Internet eine Aufgabe gefunden bei dem ein Glücksspiel programmiert werden soll, bei dem eine Zufallszahl generiert wird und dann 2 Spieler eine Zahl eingeben. Derjenige, der näher an der Zahl dran ist gewinnt.
Ich habe das ganze etwas abgewandelt. Es gibt nur einen Spieler, der um einen gewissen Einsatz gegen das Casino spielt. Somit wird nur die Zahl des Spielers über die Konsole eingegeben. Die Zahl des Casinos und die "Gewinnzahl" werden zufällig generiert.
Hiermit hatte ich auch in meiner ersten Version keine Probleme. Allerdings hatte ich dort sehr viel in der main Funktion stehen.
funktionierende Version 1:
Code:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <Windows.h>
using namespace std;
//global variables
struct Spieler{
int ialter, ikontostand;
string svname, snname;
char cgeschlecht;
};
//function prototypes
void gluecksspiel(Spieler);
int main()
{
//local variables
Spieler spieler;
//Eingabe der persoenlichen Daten.
cout << "Geben Sie bitte Ihren Namen, Ihr Alter und Ihr Geschlecht (m/w) ein." << endl;
cout << "Vorname: ";
cin >> spieler.svname;
cout << "Nachname: ";
cin >> spieler.snname;
cout << "Alter: ";
cin >> spieler.ialter;
cout << "Geschlecht: ";
cin >> spieler.cgeschlecht;
//Check, ob Spieler ueber 18 und geschlechtsspezifische Begruessung.
if (spieler.ialter < 18){
cout << "Hallo " << spieler.svname << "! Leider ist Glueckspiel erst ab 18 erlaubt." << endl;
}
else if (spieler.ialter >= 18 && (spieler.cgeschlecht == 'm' || spieler.cgeschlecht == 'M')){
cout << "Guten Tag Herr " << spieler.snname << "!" << endl << "Wie viel Geld moechten Sie einzahlen: ";
cin >> spieler.ikontostand;
cout << "\nViel Spass beim Gluecksspiel." << endl;
gluecksspiel(spieler);
}
else if (spieler.ialter >= 18 && (spieler.cgeschlecht == 'w' || spieler.cgeschlecht == 'W')){
cout << "Guten Tag Frau " << spieler.snname << "!" << endl << "Wie viel Geld moechten Sie einzahlen: ";
cin >> spieler.ikontostand;
cout << "\nViel Spass beim Gluecksspiel." << endl;
gluecksspiel(spieler);
}
//Manuelles Schliessen der Anwendung
cout << "Zum Beenden der Anwendung Enter druecken...";
cin.sync();
cin.get();
return 0;
}
//function definitions
void gluecksspiel(Spieler spieler){
//local variables
int irand, icasino, ispieler, idiffcasino, idiffspieler, ibet;
char cweiterspielen, ceinzahlen;
do{
//Wetteinsatz festlegen
bet:
cout << "Wie viel wollen Sie setzen: ";
cin >> ibet;
if (ibet <= spieler.ikontostand && ibet > 0){
spieler.ikontostand -= ibet;
}
else{
cout << "Eingabe unggueltig.";
goto bet;
}
//Zufallszahl und Casinozahl generieren
irand = rand() % 100 + 1;
icasino = rand() % 100 + 1;
//Spielertipp (Zahl) einlesen
cout << "Bitte geben Sie ihren Tipp zwischen 1 und 100 ein: ";
cin >> ispieler;
//Berechnung des "Abstandes" zwischen der Casinozahl und der Gewinnzahl
idiffcasino = irand - icasino;
if (idiffcasino < 0)
idiffcasino = idiffcasino *(-1);
//Berechnung des "Abstandes" zwischen des Spielertipps und der Gewinnzahl
idiffspieler = irand - ispieler;
if (idiffspieler < 0)
idiffspieler = idiffspieler *(-1);
//Ermittlung des Gewinners
//Spieler gewinnt
if (idiffcasino > idiffspieler){
cout << "Sie haben gewonnen!" << endl << "Die gesuchte Zahl war " << irand << endl << "Ihr Tipp war " << ispieler << " und das Casino hat " << icasino << " getippt." << endl
<< "Damit liegen Sie um " << idiffcasino - idiffspieler << " naeher an der richtigen Zahl." << endl;
spieler.ikontostand += 2 * ibet;
}
//Casino gewinnt
else if (idiffcasino < idiffspieler){
cout << "Sie haben verloren!" << endl << "Die gesuchte Zahl war " << irand << endl << "Ihr Tipp war " << ispieler << " und das Casino hat " << icasino << " getippt." << endl
<< "Damit lag das Casino um " << idiffspieler - idiffcasino << " naeher an der richtigen Zahl." << endl;
}
//Unentschieden
else{
cout << "Unentschieden" << endl << "Die gesuchte Zahl war " << irand << endl << "Ihr Tipp war " << ispieler << " und das Casino hat " << icasino << " getippt." << endl
<< "Damit lagen Sie genauso nahe an der richtigen Zahl wie das Casino." << endl;
spieler.ikontostand += ibet;
}
//Check ob noch Geld zum Spielen da ist.
//Falls ja, kann er frei entscheiden, ob er weiterspielen will oder nicht
if (spieler.ikontostand >0){
cout << "Moechten Sie weiterspielen? (j/n)";
cin >> cweiterspielen;
}
//Sonst muss er entweder erneut Geld einzahlen oder gehen.
else{
cout << "Sie haben kein Geld mehr. \nMoechten Sie weiteres Geld einzahlen? (j/n)" << endl;
cin >> ceinzahlen;
switch (ceinzahlen)
{
case 'J':
case 'j':
cout << "Wie viel moechten Sie einzahlen: ";
cin >> spieler.ikontostand;
break;
case 'N':
case 'n':
cout << "Ohne Geld koennen Sie leider nicht weiterspielen. Auf Wiedersehen" << endl;
break;
}
}
} while (spieler.ikontostand > 0 && (cweiterspielen != 'n' && cweiterspielen != 'N'));
cout << "Vielen Dank fuer Ihren Besuch! Auf Wiedersehen." << endl;
}
Da ich aber immer wieder lese, dass man möglichst wenig in die main Funktion schreiben soll, um seinen Code zum einen besser lesbar zu gestalten und zum anderen um einzelne Funktion besser wiederzufinden, wollte ich die Dateneingabe und den Alterscheck auslagern.
Hierbei hatte ich das Problem, dass er immer wieder in den Fall "ialter<18" gelaufen ist, auch wenn man ein Alter >18 eingegeben hat.
Hier der Code dazu:
nicht funktionierende Version 2:
Code:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <Windows.h>
using namespace std;
//global variables
struct Spieler{
int ialter, ikontostand;
string svname, snname;
char cgeschlecht;
};
//function prototypes
void dateneingabe(Spieler);
void alterscheck(Spieler);
void gluecksspiel(Spieler);
int main()
{
//local variables
Spieler spieler;
dateneingabe(spieler);
alterscheck(spieler);
//Manuelles Schliessen der Anwendung
cout << "Zum Beenden der Anwendung Enter druecken...";
cin.sync();
cin.get();
return 0;
}
//function definitions
void dateneingabe(Spieler spieler)
{
//Eingabe der persoenlichen Daten.
cout << "Vorname: ";
cin >> spieler.svname;
cout << "Nachname: ";
cin >> spieler.snname;
cout << "Alter: ";
cin >> spieler.ialter;
cout << "Geschlecht: ";
cin >> spieler.cgeschlecht;
}
void alterscheck(Spieler spieler)
{
//Check, ob Spieler ueber 18 und geschlechtsspezifische Begruessung.
if (spieler.ialter < 18){
cout << "Hallo " << spieler.svname << "! Leider ist Glueckspiel erst ab 18 erlaubt." << endl;
}
else if (spieler.ialter >= 18 && (spieler.cgeschlecht == 'm' || spieler.cgeschlecht == 'M')){
cout << "Guten Tag Herr " << spieler.snname << "!" << endl << "Wie viel Geld moechten Sie einzahlen: ";
cin >> spieler.ikontostand;
cout << "\nViel Spass beim Gluecksspiel." << endl;
gluecksspiel(spieler);
}
else if (spieler.ialter >= 18 && (spieler.cgeschlecht == 'w' || spieler.cgeschlecht == 'W')){
cout << "Guten Tag Frau " << spieler.snname << "!" << endl << "Wie viel Geld moechten Sie einzahlen: ";
cin >> spieler.ikontostand;
cout << "\nViel Spass beim Gluecksspiel." << endl;
gluecksspiel(spieler);
}
}
void gluecksspiel(Spieler spieler){
//wie in Code 1
}
Ich habe mir dann an verschiedenen Stellen im Code den Wert und die Speicheradresse von ialter ausgeben lassen.
Hierbei bin ich dann darauf gestoßen, dass die Speicheradresse für spieler.ialter in Main eine andere ist als spieler.ialter in dateingabe().
Allerdings ist die Speicheradresse für spieler.ialter in dateneingabe() und alterscheck() die gleiche.
Meine Lösung für das Problem war, dass ich im struct Spieler für jede Variable noch einen Pointer angelegt habe und die Dateneingaben dann über die Pointer gelöst habe. Damit funktionieren die ausgelagerten Funktionen auch einwandfrei.
Funktionierende Version 3:
Code:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <Windows.h>
using namespace std;
//global variables
struct Spieler{
int ialter, ikontostand;
string svname, snname;
char cgeschlecht;
int *pointeralter = &ialter, *pointerkontostand = &ikontostand;
string *pointervname = &svname, *pointernname = &snname;
char *pointergeschlecht = &cgeschlecht;
};
//function prototypes
void dateneingabe(Spieler);
void alterscheck(Spieler);
void gluecksspiel(Spieler);
int main()
{
//local variables
Spieler spieler;
dateneingabe(spieler);
alterscheck(spieler);
//Manuelles Schliessen der Anwendung
cout << "Zum Beenden der Anwendung Enter druecken...";
cin.sync();
cin.get();
return 0;
}
//function definitions
void dateneingabe(Spieler spieler)
{
//Eingabe der persoenlichen Daten.
cout << "Geben Sie bitte Ihren Namen, Ihr Alter und Ihr Geschlecht (m/w) ein." << endl;
cout << "Vorname: ";
cin >> *spieler.pointervname;
cout << "Nachname: ";
cin >> *spieler.pointernname;
cout << "Alter: ";
cin >> *spieler.pointeralter;
cout << "Geschlecht: ";
cin >> *spieler.pointergeschlecht;
}
void alterscheck(Spieler spieler)
{
//Check, ob Spieler ueber 18 und geschlechtsspezifische Begruessung.
if (spieler.ialter < 18){
cout << "Hallo " << spieler.svname << "! Leider ist Glueckspiel erst ab 18 erlaubt." << endl;
}
else if (spieler.ialter >= 18 && (spieler.cgeschlecht == 'm' || spieler.cgeschlecht == 'M')){
cout << "Guten Tag Herr " << spieler.snname << "!" << endl << "Wie viel Geld moechten Sie einzahlen: ";
cin >> spieler.ikontostand;
cout << "\nViel Spass beim Gluecksspiel." << endl;
gluecksspiel(spieler);
}
else if (spieler.ialter >= 18 && (spieler.cgeschlecht == 'w' || spieler.cgeschlecht == 'W')){
cout << "Guten Tag Frau " << spieler.snname << "!" << endl << "Wie viel Geld moechten Sie einzahlen: ";
cin >> spieler.ikontostand;
cout << "\nViel Spass beim Gluecksspiel." << endl;
gluecksspiel(spieler);
}
}
void gluecksspiel(Spieler spieler){
//wie Code 1
/
Jetzt zur eigentlichen Frage.
Kann mir jemand das mit Speicherzuweisung erklären? Ich verstehe das nicht.
Ich erzeuge doch das Objekt spieler in Main. Damit werden dann doch auch automatisch die Variablen ialter etc. für diese Spielerinstanz angelegt und ihnen eine Speicheradresse zugewiesen.
Dann übergebe ich dieses Spieler-Element an die anderen Funktionen.
Wieso haben die Variablen dann in dateneingabe() eine andere Speicheradresse?
Dies bedeutet ja, dass diese Variablen neu angelegt wurden und zwar an einer anderen Speicheradresse. Somit existiert spieler.ialter 2 Mal.
Einmal in der Speicheradresse von der Main Funktion und einmal in der Speicheradresse von den externen Funktionen,
Wie kann das aber sein, wenn ich nur 1 Instanz vom Typ Spieler erzeuge?
Ich versteh es einfach nicht
Edit: gerade beim Absenden des Posts ist mir noch eine Idee gekommen, welche auch funktioniert.
Wenn ich alterscheck(spieler) nicht in Main aufrufe sondern in dateneingabe(), dann funktionier alles ohne Pointer.
Allerdings löst das mein Verständnisproblem mit den unterschiedlichen Speicheradressen von main und den anderen Funktionen immer noch nicht
Ansonsten bin ich auch offen für jeden weiteren Tipp bzgl. meines Codes, da ich ja noch ganz am Anfang meines Lernweges stehe.
Nochmal vielen Dank an diejenigen, die sich alles durchgelesen haben!!!
Gruß
thesi
Zuletzt bearbeitet: