Problem mit Doppelt verketteten Listen



  • He Liebe Community,

    Ich stecke grad voll in den Prüfungsvorbereitungen (ITA). Jetz bin ich gerade an den doppelt verketteten Listen steckengeblieben. Nach dem erstellen eines neuem elemeentes in der Liste wird zuerst eine Adresse für den nachfolger des aktuellen objektes belgt, 2 Zeilen darunter hat der Vorgänger wieder keine Adresse. Somit funktioniert das vorblättern in meiner liste nicht.
    Aber hier erstmal der code:

    class TLand
    {
    public:
      String Land;
      TLand *oVor;
      TLand *oNach;
      TLand(String Landname);
    
    };
    
    TLand::TLand(String Landname)
    {
      Land  = Landname;
      oVor  = NULL;
      oNach = NULL;
    }
    
    TLand *Neu, *Anfang, *Aktuell;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::btn_neuClick(TObject *Sender)
    {
      if(Anfang)
      {
        Neu = new TLand(edt_land->Text);
        Aktuell->oVor = Aktuell;
        Aktuell = Neu;
      }
      else
      {
        Neu = new TLand(edt_land->Text);
        Anfang=Aktuell=Neu ;
    
      }
    
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::btn_vorClick(TObject *Sender)
    {
      if(Aktuell->oVor&&Anfang)
      {
        Aktuell->oNach =Aktuell;
        Aktuell =Aktuell->oVor;
    
        edt_land->Text=Aktuell->Land;
      }
    

    Was mache ich falsch ?

    Danke schonmal im vorhinaus!

    mfg
    thps

    PS: Ich hoffe ich habe in das richtige Forum gepostet.!



  • So mal aus interesse:

    Für was steckst du greade in Prüfungsvorbereitungen?
    Ist das dein eigener Code oder hast du es bekommen?

    Das Mixen von UI Code und Funktionalität ist ein sehr schlechter Still.

    Nachtrag:

    void __fastcall TForm1::btn_vorClick(TObject *Sender) 
    { 
      if(Neu != 0) {
         if(Aktuell == Neu) Aktuell = Anfang;
         else Aktuell = Aktuell->oVor;
    
         edt_land->Text=Aktuell->Land;
      }
    

    Allerdings scheinen da mehr fehler zu sein weil deine drei Pointer werden im Code gleichgesetzt:

    Anfang=Aktuell=Neu ;
    

    Du brauchst aber sowas wie ein Start(Immer auf das erste zeigt), Ende(Immer auf das letzte zeigt) und Current(wie aktuell)


  • Mod

    Was sollen btn_neuClick und btn_vorClick genau machen? Ich kann überhaupt nicht erkennen, dass diese etwas tun, was irgendwie mit einem neuen Element oder dem Vorgehen in der Liste zu tun hat. Überhaupt kann ich nicht viel von einer Liste sehen.

    btn_neuClick erstellt korrekt ein neues Element, sofern die Liste leer ist. Wenn es aber schon Elemente gibt, machst du wirre Sachen:
    Ein neues Element wird erstellt, aber dessen Zeiger werden gar nicht initialisiert. Stattdessen wird das Vorgängereelement des aktuellen Elements ( 😕 soll "aktuell" immer das letzte sein?) auf sich selbst gesetzt, was überhaupt keinen Sinn macht, denn wie soll ein Element sein eigener Vorgänger sein? Oder soll oVor für Vorwärts stehen? Auch dann macht es keinen Sinn, der Nachfolger des letzten Elements soll ja das neue sein, nicht das alte letzte. Und was ist dann oNach? Nachwärts?

    Ebenso wirr bei btn_vorClick:
    Der Nachwärtszeiger des aktuellen (ist das nun aktuell oder das letzte?) wird wieder auf sich selbst gesetzt, was überhaupt keinen Sinn macht. Und dann setzt du korrekt das aktuelle Element auf den Nachfolger (oVor) des alten aktuellen Elements. Diesen hast du aber bei der Erstellung auf sich selbst gesetzt, wodurch nichts passiert.

    Meine Einschätzung: Du bist anscheinend auf dem Gebiet der manuellen Speicherverwaltung sehr, sehr unsicher. Such dir zunächst mal etwas einfacheres. Spiel einfach mal ein bisschen mit Pointern rum und versuch genau zu verstehen, wie das funktioniert. Den jetzigen Code deiner doppelt verketteten Liste kannst du wegwerfen, da ist zu vieles schon vom Konzept her falsch. Wenn du sicherer mit Pointern umgehen kannst, wirst du dies einsehen und kannst ein viel besseres Konzept für die Liste entwickeln.



  • @Zeus :

    Der Code stammt zu 90 % von meinem Lehrer , ich habe nur versucht den code zu ein bisschen zu erweitern(btn_vor).
    Ich schreibe Prüfungen für den Assistenten für Informatik( es geht eig nur um die Fachhochschulreife).

    Allerdings scheinen da mehr fehler zu sein weil deine drei Pointer werden im Code gleichgesetzt:

    C/C++ Code:
    Anfang=Aktuell=Neu ;

    naja die pointer werden ja nur gleich gesetzt wenn es noch kein erstes element gibt. Dann würde das ja auch stimmen. wenn es noch kein element gibt dann ist ja das Aktuelle gleich dem ersten und dem neuen!

    Das einfügen eines Elementes funktioniert auch .

    mfg

    @SeppJ

    oNach ist der Nachfolger, oVor ist der Vorgänger und Aktuelle ist nicht das Letzte sondern der aktuelle zeiger.

    Wie schon erwähnt stammt der code nur zum Teil von mir (btn_vor). Der Rest stammt von meinem Lehrer, welcher sich seiner sache jedoch ziehmlich sicher sein kann.

    Ich weis das wir den Code von ca 3Monaten im Untericht hatten und das ich damals auch das vorblättern auf die Art hinbekommen habe. Das einfügen eines neuen Elements (btn_neu) funktioniert auf jeden fall (kann ich ja beim Debuggen sehen).

    mfg



  • Oh korrekt, die Benammung ist halt total schrecklich. Da kann man schon durcheinandere kommen beim Fremdcode.

    Und das dein Leherer sowas schreibt, hast du mein Beileid und Mitgefühl aus tiefsten Herzen.

    Hast du mein Code probiert?



  • mmh noch nicht wirklich ich hab aber die funktionierende version von "meinem" Codestyl gefunden:

    class TPerson
    {
    public:
      String Vorname, Nachname;
      TPerson *oVor;
      TPerson *oNach;
      TPerson(String s_Vorname, String s_Nachname);
    };
    
    TPerson::TPerson(String s_Vorname,String s_Nachname)
    {
      Vorname = s_Vorname;
      Nachname = s_Nachname;
      oVor = NULL;
      oNach = NULL;
    }
    
    TPerson *Neu, *Anfang, *Aktuell;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::btn_NewPersonClick(TObject *Sender)
    {
      Neu = new TPerson(edt_Vorname->Text, edt_Nachname->Text);
      if(Anfang)
      {
        Aktuell->oNach = Neu;
        Neu->oVor = Aktuell;
        Aktuell = Neu;
      }
      else
      {
        Anfang = Aktuell = Neu;
      }
    //    ShowMessage(Neu->Land);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
      if(Anfang)
      {
        while(Anfang->oNach)
        {
          Anfang = Anfang->oNach;
          delete Anfang->oVor;
        }
        delete Anfang;
        Anfang = NULL;
      }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::btn_BACKClick(TObject *Sender)
    {
      if(Anfang && Aktuell->oVor)
      {
        Aktuell = Aktuell->oVor;
        edt_Vorname->Text = Aktuell->Vorname;
        edt_Nachname->Text = Aktuell->Nachname;
      }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::btn_FORWARDClick(TObject *Sender)
    {
      if(Anfang && Aktuell->oNach)
      {
        Aktuell = Aktuell->oNach;
        edt_Vorname->Text = Aktuell->Vorname;
        edt_Nachname->Text = Aktuell->Nachname;
      }
    }
    

    Ob das ein schlechter Programmierstil ist oder nicht kann ich nicht einschätzen, da ich es so gelernt habe.
    Ich hatte jedoch den Eindruck das mein Lehrer immer versucht hat uns auf einen ordentlichen Programmierstyl zu trimmen. Ob er nun diese Variante gewählt hat um uns dieses thema etwas simpler bei zubringen weis ich nicht

    mfg


Anmelden zum Antworten