JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=6d801f1ce559be24238163c2659f2912Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Probleme mit Listen (VC++, Konsolenanwendung)
Gehe zu Seite 1, 2, 3  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Apophis
Mini JLI'ler



Anmeldedatum: 28.08.2004
Beiträge: 28
Wohnort: Harz
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 19:36    Titel: Probleme mit Listen (VC++, Konsolenanwendung) Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
PeaceKiller
JLI Master


Alter: 36
Anmeldedatum: 28.11.2002
Beiträge: 970

Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 20:39    Titel: Re: Probleme mit Listen (VC++, Konsolenanwendung) Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Apophis
Mini JLI'ler



Anmeldedatum: 28.08.2004
Beiträge: 28
Wohnort: Harz
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 22:03    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 22:09    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
PeaceKiller
JLI Master


Alter: 36
Anmeldedatum: 28.11.2002
Beiträge: 970

Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 22:41    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Apophis
Mini JLI'ler



Anmeldedatum: 28.08.2004
Beiträge: 28
Wohnort: Harz
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 22:52    Titel: Antworten mit Zitat

@Zyrian

Hey danke, deine 2 idee geht. ^^
_________________
Guckst du hier!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 23:04    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Apophis
Mini JLI'ler



Anmeldedatum: 28.08.2004
Beiträge: 28
Wohnort: Harz
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 23:10    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 23:18    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
PeaceKiller
JLI Master


Alter: 36
Anmeldedatum: 28.11.2002
Beiträge: 970

Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 23:19    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Apophis
Mini JLI'ler



Anmeldedatum: 28.08.2004
Beiträge: 28
Wohnort: Harz
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 23:22    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 23:28    Titel: Antworten mit Zitat

@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 Wink

die lösung:
Code:

system("cls");


so long ^^
MFG
Chris
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Apophis
Mini JLI'ler



Anmeldedatum: 28.08.2004
Beiträge: 28
Wohnort: Harz
Medaillen: Keine

BeitragVerfasst am: 28.08.2004, 23:44    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 29.08.2004, 00:01    Titel: Antworten mit Zitat

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 Shocked )

MFG
C.
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Apophis
Mini JLI'ler



Anmeldedatum: 28.08.2004
Beiträge: 28
Wohnort: Harz
Medaillen: Keine

BeitragVerfasst am: 29.08.2004, 00:21    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Gehe zu Seite 1, 2, 3  Weiter
Seite 1 von 3

 
Gehe zu:  
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

Impressum