 |
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Apophis Mini JLI'ler

Anmeldedatum: 28.08.2004 Beiträge: 28 Wohnort: Harz Medaillen: Keine
|
Verfasst am: 28.08.2004, 19:36 Titel: Probleme mit Listen (VC++, Konsolenanwendung) |
|
|
Ich habe das Buch "Jetzt lerne ich Spieleprogrammierung mit DirectX und VisualC++".
Der folgende Code ist aus diesem Buch abgetippt.
Naja, hab auch schon etwas erweitert.
MAIN
Code: | #include <stdio.h>
#include <conio.h>
#include "listen.h"
// Demonstartion der Listenfunktionen
void main(void) {
//clrscr();
//##################################################
Liste DieListe; //Liste instantieren
//##################################################
//##################################################
//neuen Knoten erzeugen, 2. Konstruktor erzeugen
Knoten *k = new Knoten("Horst", 12);
//Knoten hinzufügen
DieListe.Hinzufuegen(k);
//##################################################
//##################################################
//neuen Knoten mit einfachen Konstruktor erzeugen
k = new Knoten();
//Attribute mit Werten belegen
k->SetzeName("Heinz");
k->SetzeAlter(68);
//Knoten hinzufügen
DieListe.Hinzufuegen(k);
//##################################################
//##################################################
//Knoten in Listen ausgeben
DieListe.Ausgeben();
//##################################################
//##################################################
//DieListe.VorherigerAktuellerKnoten();
//DieListe.NaechsterAktuellerKnoten();
//##################################################
//##################################################
//DieListe.KnotenLoeschen();
//printf("\n");
//DieListe.Ausgeben();
//##################################################
//##################################################
//Die Liste löschen
DieListe.Loeschen();
//##################################################
} |
CLASS
Code: | #include <string.h>
class Knoten {
public:
//Konstruktor
Knoten(void);
Knoten(char* Name, int Alter);
//Destruktor
~Knoten(void);
//Methoden
void SetzeAlter(int Alter);
void SetzeName(char* Name);
void SetzeNachfolger(Knoten* Nachfolger);
Knoten* HoleNachfolger(void);
void SetzeVorgaenger(Knoten* Vorgaenger);
Knoten* HoleVorgaenger(void);
void Ausgabe(void);
private:
//Attribute
char* m_Name;
int m_Alter;
//Zeiger auf den nächsten Knoten
Knoten* m_Nachfolger;
//Zeiger auf den vorherigen Knoten
Knoten* m_Vorgaenger;
};
//Initialisierung der Attribute im Konstruktor
Knoten::Knoten(void) {
m_Vorgaenger = 0;
m_Nachfolger = 0;
m_Name = 0;
m_Alter = 0;
}
Knoten::Knoten(char* Name, int Alter) {
m_Vorgaenger = 0;
m_Nachfolger = 0;
//Speicher reservieren und anschlieáend kopieren
m_Name = new char[strlen(Name)+1];
strcpy(m_Name, Name);
m_Alter = Alter;
}
//Wenn Speicher reserviert wurde, muss dieser wieder
//freigegeben werden
Knoten::~Knoten() {
if(m_Name) delete m_Name;
}
//das Alter zuweisen
void Knoten::SetzeAlter(int Alter) {
m_Alter = Alter;
}
//den Namen zuweisen
void Knoten::SetzeName(char* Name) {
//Wenn Speicher reserviert wurde, muss
//dieser zuerst freigegeben werden
if (m_Name != 0) delete m_Name;
//Feld mit passender Größe reservieren
m_Name = new char[strlen(Name)+1];
strcpy(m_Name, Name);
}
//Das Attribut m_Nachfolger auf den übergebenen Wert setzen
void Knoten::SetzeNachfolger(Knoten* Nachfolger) {
m_Nachfolger = Nachfolger;
}
//Zeiger auf den Nachfolger zurückgeben
Knoten* Knoten::HoleNachfolger(void) {
return m_Nachfolger;
}
//Vorgängerzeiger setzen
void Knoten::SetzeVorgaenger(Knoten* Vorgaenger) {
m_Vorgaenger = Vorgaenger;
}
//Vorgängerzeiger zurückgeben
Knoten* Knoten::HoleVorgaenger(void) {
return m_Vorgaenger;
}
//Werte der Attribute ausgeben
void Knoten::Ausgabe(void) {
printf("Name : %s\n", m_Name);
printf("Alter: %d\n", m_Alter);
}
class Liste {
public:
Liste(void); //Konstruktor
~Liste(); //Destruktor
void Hinzufuegen(Knoten* NeuerKnoten);
void Ausgeben(void);
void Loeschen(void);
int NaechsterKnoten(void); //bool
int VorherigerKnoten(void); //bool
void ErsterKnoten(void);
void LetzterKnoten(void);
Knoten* HoleAktuller(void);
void KnotenLoeschen(void);
void NaechsterAktuellerKnoten(void); //Wandert nach rechts durch die liste
void VorherigerAktuellerKnoten(void); //Wandert nach links durch die liste
private:
Knoten* Listenende;
Knoten* Listenkopf;
Knoten* AktuellerKnoten;
};
//Den Zeiger Listenkopf und Listenende
//zu Begin mit 0 initialisieren
Liste::Liste(void) {
Listenkopf = Listenende = 0;
}
//Wenn die Liste gelöscht werden soll, müssen auch alle
//Knoten gelöscht werden
Liste::~Liste() {
Loeschen();
}
//Knoten zur Liste hinzufügen
void Liste::Hinzufuegen(Knoten* NeuerKnoten) {
//Wenn die Liste leer war, muss sowohl der Kopf-
//als auch der Endzeiger auf den 1. Knoten zeigen
if (Listenkopf == 0) {
Listenkopf = NeuerKnoten;
Listenende = NeuerKnoten;
AktuellerKnoten = NeuerKnoten;
}
//sonst wird der neue Knoten hinter dem Zeiger
//Listenende eingefügt, der Vorgänger des neuen
//Knotens ist somit der Knoten, auf dem Listenende
//mementanzeigt. Zum Schluss muss Listenende noch
//auf den neuen Knoten gesetzt werden
else {
Listenende->SetzeNachfolger(NeuerKnoten);
NeuerKnoten->SetzeVorgaenger(Listenende);
Listenende = NeuerKnoten;
AktuellerKnoten = NeuerKnoten;
}
}
//Alle Knoten der Liste ausgeben
void Liste::Ausgeben(void) {
Knoten* p = Listenkopf;
//Solange p nciht 0 ist
while(p) {
//können die Attribute ausgegeben werden
p->Ausgabe();
//und p wird auf den nächsten Knoten gestezt
p = p->HoleNachfolger();
}
}
//Alle Knoten der Liste löschen
void Liste::Loeschen(void) {
while(Listenende->HoleVorgaenger()) {
Listenende = Listenende->HoleVorgaenger();
delete Listenende->HoleNachfolger();
Listenende->SetzeNachfolger(0);
}
}
//Löscht den Knoten, auf dem AktuellerKnoten zeigt
void Liste::KnotenLoeschen(void) {
//Wenn AktuellerKnoten auf einen gültigen Knoten zeigt
if (AktuellerKnoten) {
//testen, ob das Listenende gelöscht werden soll
if (AktuellerKnoten == Listenende) {
AktuellerKnoten = Listenende->HoleVorgaenger();
delete Listenende;
Listenende = AktuellerKnoten;
//Wenn die Liste jetzte leer ist
if (Listenende == 0) {
//muss der Listenkopf auch auf 0 zeigen
Listenkopf = 0;
}
else
{
//ansonsten Nachfolgezeiger auf 0 setzen
Listenende->SetzeNachfolger(0);
}
}
//testen, ob der Listenkopf gelöscht werden soll
else if (AktuellerKnoten == Listenkopf) {
AktuellerKnoten = Listenkopf->HoleNachfolger();
delete Listenkopf;
Listenkopf = AktuellerKnoten;
//Wenn die Liste jetzt leer ist
if (Listenkopf == 0) {
//muss der Listenkopf auch auf 0 zeigen
Listenkopf = 0;
}
else
{
//ansonsten Vorgängerzeiger auf 0 setzen
Listenkopf->SetzeVorgaenger(0);
}
}
//Wenn AktuellerKnoten auf einen anderen Knoten zeigt
else
{
Knoten* p = AktuellerKnoten;
//Der Knoten soll nach dem Löschen vor dem
//gelöschten Argument stehen
AktuellerKnoten = AktuellerKnoten->HoleVorgaenger();
//Das Element, auf das p zeigt aus der Liste
//nehmen und löschen
AktuellerKnoten->SetzeNachfolger(p->HoleNachfolger());
p->HoleNachfolger()->SetzeVorgaenger(AktuellerKnoten);
delete p;
}
}
}
//Setzt AktuellerKnoten auf den nächsten Knoten
void Liste::NaechsterAktuellerKnoten(void) {
//Test ob AktuellerKnoten auf einen gültigen Knoten zeigt
if (AktuellerKnoten) {
//Wenn AktuellerKnoten auf das Listenende zeigt dann
if (AktuellerKnoten == Listenende) {
//setze AktuellerKnoten auf den ListenKopf
AktuellerKnoten = Listenkopf;
}
//Wenn AktuellerKnoten auf einen anderen Knoten zeigt dann
else
{
//setze AktuellerKnoten auf den Nachfolgenden Knoten
AktuellerKnoten = AktuellerKnoten->HoleNachfolger();
}
}
}
//Setzt AktuellerKnoten auf den vorherigen Knoten
void Liste::VorherigerAktuellerKnoten(void) {
//Test ob AktuellerKnoten auf einen gültigen Knoten zeigt
if (AktuellerKnoten) {
//Wenn AktuellerKnoten auf den Listenkopf zeigt dann
if (AktuellerKnoten == Listenkopf) {
//setze AktuellerKnoten auf den Listenende
AktuellerKnoten = Listenende;
}
//Wenn AktuellerKnoten auf einen anderen Knoten zeigt dann
else
{
//setze AktuellerKnoten auf den Vorherigen Knoten
AktuellerKnoten = AktuellerKnoten->HoleVorgaenger();
}
}
} |
Hab nun aber ein Problem.
Wie kann ich in der MAIN-Datei, also da wo auch die main drin ist, folgendes in eine
function packen?
Code: | Knoten *k = new Knoten("Horst", 12);
DieListe.Hinzufuegen(k); |
Ich will diese Function dann immer wieder mal aufrufen können.
Auch von anderen Functionen aus.
Weil ich das spätere Programm nicht in einer einziegen Datei speichern, sondern auf
mehrere aufteilen will.
Ich hoffe ihe versteht was ich meine.
Also ich will eine Function haben die dann etwa so aussieht:
Code: | void NeuerKnoten(char* Name, int Alter) {
Knoten *k = new Knoten(Name, Alter);
DieListe.Hinzufuegen(k);
} |
Wo wir gerade dabei sind, gibt es in VC++ einen ersatz für clrscr()? _________________ Guckst du hier!
Zuletzt bearbeitet von Apophis am 28.08.2004, 22:57, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
PeaceKiller JLI Master

Alter: 36 Anmeldedatum: 28.11.2002 Beiträge: 970
Medaillen: Keine
|
Verfasst am: 28.08.2004, 20:39 Titel: Re: Probleme mit Listen (VC++, Konsolenanwendung) |
|
|
Apophis hat Folgendes geschrieben: | Code: | void NeuerKnoten(char* Name, int Alter) {
Knoten *k = new Knoten(Name, Alter);
DieListe.Hinzufuegen(k);
} |
| Da hast du doch deine Funktion oder habe ich die Frage falsch vertanden? _________________ »If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside.«
– Robert X. Cringely, InfoWorld magazine |
|
Nach oben |
|
 |
Apophis Mini JLI'ler

Anmeldedatum: 28.08.2004 Beiträge: 28 Wohnort: Harz Medaillen: Keine
|
Verfasst am: 28.08.2004, 22:03 Titel: |
|
|
Eben nicht. Ich kann diese Function nicht ohne fehler aufrufen.
Wenn ich das ausführen will dann sagt er folgendes:
Code: | e:\vc++\projekte\listen\editor.cpp(10) : error C2065: 'DieListe' : nichtdeklarierter Bezeichner
e:\vc++\projekte\listen\editor.cpp(10) : error C2228: Der linke Teil von '.Hinzufuegen' muss eine Klasse/Struktur/Union sein |
Code: | void NeuerKnoten(char* Name, int Alter) {
Knoten *k = new Knoten(Name, Alter);
DieListe.Hinzufuegen(k); <--------------- Hier treten die Fehler auf
} |
_________________ Guckst du hier!
Zuletzt bearbeitet von Apophis am 28.08.2004, 22:58, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
Zyrian Super JLI'ler

Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 28.08.2004, 22:09 Titel: |
|
|
du hast 2 möglichkeiten dazu.
1. du machst DieListe global oder
2. du übergibst deiner Funktion noch einen weiteren parameter, und zwar die Adresse von DieListe oder ne Referenz darauf.
Code: |
void NeuerKnoten(char* Name, int Alter, Liste* pListe)
{
Knoten k = new Knoten(Name, Alter);
pListe->Hinzufuegen(k);
}
|
MFG
Chris _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
 |
PeaceKiller JLI Master

Alter: 36 Anmeldedatum: 28.11.2002 Beiträge: 970
Medaillen: Keine
|
Verfasst am: 28.08.2004, 22:41 Titel: |
|
|
Oder du machst es als static. _________________ »If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside.«
– Robert X. Cringely, InfoWorld magazine |
|
Nach oben |
|
 |
Apophis Mini JLI'ler

Anmeldedatum: 28.08.2004 Beiträge: 28 Wohnort: Harz Medaillen: Keine
|
Verfasst am: 28.08.2004, 22:52 Titel: |
|
|
@Zyrian
Hey danke, deine 2 idee geht. ^^ _________________ Guckst du hier! |
|
Nach oben |
|
 |
Zyrian Super JLI'ler

Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 28.08.2004, 23:04 Titel: |
|
|
np (:
dein fehler lag darin, dass die Variable DieListe in der main-Funktion deklariert wird und dementsprechend nur in dieser Funktion bekannt ist. Andere Funktionen kennen also DieListe gar net (wie du auch in der Fehlerausgabe siehst (: )
Man macht also entweder diesen Funktionen die Variable bekannt, indem man sie global deklariert (man sollte aber globale Variablen möglichst vermeiden), oder, was stiltechnisch viel besser ist, man übergibt ihnen die Adresse der Variablen, die sie bearbeiten sollen.
MFG
Chris _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
 |
Apophis Mini JLI'ler

Anmeldedatum: 28.08.2004 Beiträge: 28 Wohnort: Harz Medaillen: Keine
|
Verfasst am: 28.08.2004, 23:10 Titel: |
|
|
Ich habe etwas ähnliches schonmal selber Probiert.
Deine idee:
Code: | void NeuerKnoten(char* Name, int Alter, Liste* pListe) {
Knoten *k = new Knoten(Name, Alter);
pListe->Hinzufuegen(k);
} |
Einer meiner versuche:
Code: | void NeuerKnoten(Liste DieListe, char* Name, int Alter) {
Knoten *k = new Knoten(Name, Alter);
DieListe.Hinzufuegen(k);
} |
Wie du siehst, fast gleich. ^^
Aber nochmal zu meinem anderen Problem:
Gibt es in VC++ einen ersatz für clrscr()? _________________ Guckst du hier! |
|
Nach oben |
|
 |
The Lord of Programming Living Legend

Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 28.08.2004, 23:18 Titel: |
|
|
Apophis hat Folgendes geschrieben: | Aber nochmal zu meinem anderen Problem:
Gibt es in VC++ einen ersatz für clrscr()? |
Was meinst du mit Ersatz?
Soweit ich weiß, gibts diese Funktion auch in C++. Ich weiß allerdings nicht, welche Header man dafür braucht... _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
 |
PeaceKiller JLI Master

Alter: 36 Anmeldedatum: 28.11.2002 Beiträge: 970
Medaillen: Keine
|
Verfasst am: 28.08.2004, 23:19 Titel: |
|
|
Das müsste eigentlich gehen:
Code: | printf("\033[2J"); /* Clear the entire screen. */
printf("\033[0;0f"); /* Move cursor to the top left hand corner */ |
_________________ »If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside.«
– Robert X. Cringely, InfoWorld magazine |
|
Nach oben |
|
 |
Apophis Mini JLI'ler

Anmeldedatum: 28.08.2004 Beiträge: 28 Wohnort: Harz Medaillen: Keine
|
Verfasst am: 28.08.2004, 23:22 Titel: |
|
|
@The Lord of Programming
Also bei mir geht der nicht.
Im meiner Schule haben wir Turbo C++ (oder so).
Also diese DOS kram.
Da gibt es clrscr() in der conio.h
Aber hier bei mir geht das irgendwie nicht.
Code: | E:\VC++\Projekte\Listen\editor.cpp(15) : error C2065: 'clrscr' : nichtdeklarierter Bezeichner |
@PeaceKiller
sorry, aber geht beides nicht. _________________ Guckst du hier! |
|
Nach oben |
|
 |
Zyrian Super JLI'ler

Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 28.08.2004, 23:28 Titel: |
|
|
@Apophis
Deine Lösung geht auch. Das nennt "call by value". Ist auch bei Kleinigkeiten wie dieser Liste ok. Nur wenn du später mal grössere Variablen so übergeben möchtest, dann solltest du wissen, dass diese Variablen vorm Durchlauf dieser Funktion nochmals kopiert werden und damit dann weitergearbeitet wird. Das kann, wie gesagt, bei grösseren Variablen zu Performanceschwankungen führen (:
Ist aber hier keine grosse Sache, sag ich nur der Vollständigkeit halber
die lösung:
so long ^^
MFG
Chris _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
 |
Apophis Mini JLI'ler

Anmeldedatum: 28.08.2004 Beiträge: 28 Wohnort: Harz Medaillen: Keine
|
Verfasst am: 28.08.2004, 23:44 Titel: |
|
|
Das ist so nicht ganz richtig.
Mein versuch macht zwar keine fehler.
Tut aber auch nicht das was er soll.
Mein versuch hat nähmlich keinen neuen Knoten erzeugt. _________________ Guckst du hier! |
|
Nach oben |
|
 |
Zyrian Super JLI'ler

Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 29.08.2004, 00:01 Titel: |
|
|
achjo *gegenstirnschlag*
naja is scho spät, bin net mehr auf der höhe ^^
das funzt natürlich nit, weil die variable, die du in der main funktion übergibst, net direkt manipuliert wird. das regelst du halt indem du die adresse der zu ändernden variablen übergibst.
(hab da was zusammengeschmissen von wegen referenz und call by value )
MFG
C. _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
 |
Apophis Mini JLI'ler

Anmeldedatum: 28.08.2004 Beiträge: 28 Wohnort: Harz Medaillen: Keine
|
Verfasst am: 29.08.2004, 00:21 Titel: |
|
|
Naja, jetzt geht ja alles.
Bin ja gerade dabei C++ zu lernen.
Sowohl Privat als auch Schulisch.
Schulisch haben wir zwar gerade erst Strukturen aber Privat hab ich mit dem Buch schon fast mehr gelernt. ^^ _________________ Guckst du hier! |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|