Arbeit mit Datenstrukturen - ZAHLENOBJEKT



  • Hallo ,

    ersteinmal hallo allerseits. Ich habe bemerkt, dass dieses Forum eine sehr kompetente Basis für die C++ Programmierung darstellt. Ersteinmal Respekt vor eurer Arbeit.

    Leider habe ich ein Problem mit einer Programmieraufgabe. Ich habe mich schon mehrere Stunden damit beschäftigt, aber leider gelingt es mir nicht die Vorgaben zu durchdringen. Ich werde nun die Aufgabenstellung und die Vorgaben hineinkopieren. Mir geht es vor allen Dingen darum herauszufinden, wie die Vorgaben arbeiten und was sie genau machen, damit ich das Problem bzw. die Aufgaben lösen kann.

    Vielen Dank im Voraus für eure Hilfe...

    In Haskell konnten beliebig große natürliche Zahlen dargestellt werden. In C/C++ gibt es keinen Standarddatentypen, der das erlaubt. In dieser Aufgabe ist eine dynamische Datenstruktur vorgegeben, mit der eine nicht negative Zahl als Dezimalbruch mit beliebig vielen Vor- und Nachkommastellen gespeichert werden kann. Diese Datenstruktur wird aus Instanzen der zwei Strukturen TZiffer und TZahl aufgebaut:
    struct TZiffer {
    char ziffer;
    TZiffer* links;
    TZiffer* rechts;
    };
    struct TZahl {
    TZiffer* vkStelle;// Vorkommastelle
    int nkStellen; // Nachkommastellen
    int vkStellen; // Vorkommastellen
    TZiffer* aktPos; // Position in Liste
    };

    Der Dezimalbruch wird durch ein Zahlenobjekt repräsentiert, das eine Instanz der Struktur TZahl ist. Diese Struktur enthält die Anzahl der Vor- und Nachkommastellen der gespeicherten Zahl (vkStellen/nkStellen) sowie zwei Verweise (vkStelle/aktPos) auf eine doppelt verkettete Liste. Jedes Element dieser doppelt verketteten Liste hat den Typ TZiffer, speichert den Wert einer Ziffer und enthält einen Verweis auf die linke bzw. rechte Nachbarziffer. Falls keine Nachbarziffer existiert, ist der entsprechende Verweis 0. Der Wert – nicht das Zeichen! – der Ziffer wird in der Komponente ziffer gespeichert. Der Zeiger vkStelle in der Struktur TZahl verweist immer auf die Ziffer direkt vor dem Komma und legt somit die Kommaposition fest.
    Es ist bereits eine Funktion erzeugeNull in der Vorgabe enthalten, die die Datenstruktur für den Dezimalbruch 0.0 aufbaut.

    Implementieren Sie die folgenden weiteren Funktionen, die von der Funktion read in der Vorgabe benötigt werden, um einen als Text gegebenen Dezimalbruch in ein Zahlenobjekt umzuwandeln:
    •
    void zifferVorKomma(char ziffer, TZahl* zahl): Fügt in das übergebenen Zahlenobjekt zahl die übergebene Ziffer ziffer unmittelbar vor dem Komma ein. Alle anderen Ziffern vor dem Komma verschieben sich in dem Zahlenobjekt um eine Position nach links. Der Nachkommaanteil bleibt unverändert. ziffer speichert wieder den Wert der Ziffer und nicht das Zeichen.
    •
    void zifferNachKomma(char ziffer, TZahl* zahl): Fügt in das übergebenen Zahlenobjekt zahl die übergebene Ziffer ziffer unmittelbar nach dem Komma ein. Alle anderen Ziffern nach dem Komma verschieben sich in dem Zahlenobjekt um eine Position nach rechts. Der Vorkommaanteil bleibt unverändert.
    Zur Ausgabe eines als Zahlenobjekt gegebenen Dezimalbruchs auf dem Bildschirm durch die vorgegebene Funktion druckeZahl werden weitere Funktionen benötigt, die den Zeiger aktPos in der Struktur TZahl nutzen und korrekt modifizieren. Implementieren Sie diese Funktionen:
    •
    TZiffer* posLinks(TZahl* zahl): Setzt den Zeiger aktPos im Zahlenobjekt zahl auf die am weitesten links stehende Ziffer in diesem Zahlenobjekt und gibt einen Verweis auf diese Ziffer zurück.
    •
    TZiffer* posRechts(TZahl* zahl): Setzt den Zeiger aktPos im Zahlenobjekt zahl auf die am weitesten rechts stehende Ziffer in diesem Zahlenobjekt und gibt einen Verweis auf diese Ziffer zurück.
    •
    TZiffer* nachLinks(TZahl* zahl): Falls die Ziffer, auf die aktPos im Zahlenobjekt zahl verweist einen linken Nachbarn hat, so wird aktPos auf diesen Nachbarn gesetzt. Ansonsten wird aktPos nicht verändert. Die Funktion gibt den Verweis auf die Ziffer zurück, auf die aktPos dann zeigt.
    •
    TZiffer* nachRechts(TZahl* zahl): Falls die Ziffer, auf die aktPos im Zahlenobjekt zahl verweist einen rechten Nachbarn hat, so wird aktPos auf diesen Nachbarn gesetzt. Ansonsten wird aktPos nicht verändert. Die Funktion gibt den Verweis auf die Ziffer zurück, auf die aktPos dann zeigt.
    Jeder in einem Zahlenobjekt gespeicherte Dezimalbruch soll noch normalisiert werden können. Das bedeutet, dass der Vorkommaanteil mit genau einer führenden 0 beginnt und der Nachkommaanteil mit genau einer 0 endet. Diese Nullen sollen in den Variablen vkStellen und nkStellen nicht mitgezählt werden. Die oben angegebene Speicherung der 0.0 entspricht damit bereits dieser geforderten Normalisierung. Implementieren Sie eine Funktion
    void normalisiere(TZahl* zahl),
    die führende und abschließende Nullen – bis auf jeweils eine – in einem Zahlenobjekt streicht oder ergänzt, falls keine führende/abschließende 0 vorhanden ist.

    Hier noch meine Vorgaben (die ich leider nicht ganz verstehe)

    #include <stdio.h>
    #include <stdlib.h>
    
    struct TZiffer {
      char ziffer;
      TZiffer* links;
      TZiffer* rechts;
    };
    
    struct TZahl {
      TZiffer* vkStelle; // Vorkommastelle
      int nkStellen;     // Nachkommastellen
      int vkStellen;     // Vorkommastellen
      TZiffer* aktPos;   // aktuelle Position in der liste
    };
    
    // Erzeugt den Dezimalbrucch 0.0
    TZahl* erzeugeNull()
    {
      TZahl* Null;
    
      Null = (TZahl*)malloc(sizeof(TZahl));
      Null->vkStellen = 0;
      Null->nkStellen = 0;
      // Vorkommastelle mit 0 initialisieren
      Null->vkStelle = (TZiffer*)malloc(sizeof(TZiffer));
      Null->vkStelle->ziffer = 0;
      Null->vkStelle->links = 0;
      // Nachkommastelle erzeugen
      Null->vkStelle->rechts = (TZiffer*)malloc(sizeof(TZiffer));
      Null->vkStelle->rechts->links = Null->vkStelle;
      Null->vkStelle->rechts->rechts = 0;
      Null->vkStelle->rechts->ziffer = 0;
    
      return Null;
    }
    
    // Gibt 1 zurueck, falls aktPos auf die erste Nachkommastelle zeigt
    int ersteNKStelle(TZahl* zahl)
    {
      return zahl->aktPos == zahl->vkStelle->rechts;
    }
    
    void zifferVorKomma(char ziffer, TZahl* zahl)
    {
    }
    
    void zifferNachKomma(char ziffer, TZahl* zahl)
    {
    }
    
    TZiffer* posLinks(TZahl* zahl)
    {
    }
    
    TZiffer* posRechts(TZahl* zahl)
    {
    }
    
    TZiffer* nachRechts(TZahl* zahl)
    {
    }
    
    TZiffer* nachLinks(TZahl* zahl)
    {
    }
    
    void normalisiere(TZahl* zahl)
    {
    }
    
    // Zum Erzeugen eines Zahlenobjekts aus einem Text
    // Zum Beispiel: text = "12.500600"
    TZahl* read(char* text)
    {
      TZahl* zahl;
    
      zahl = erzeugeNull();
    
      while(*text != '.' && *text) {
        zifferVorKomma(*text - '0',zahl);
        text++;
      }
    
      if(!*text)
        return zahl;
    
      while(*text)
        text++;
    
      text--;
      while(*text != '.') {
        zifferNachKomma(*text - '0',zahl);
        text--;
      }
    
      return zahl;
    }
    
    // Zum Ausgeben der Ziffern eines Zahlenobjekts einschliesslich
    // des Kommas
    void druckeZahl(TZahl* zahl)
    {
      TZiffer* ziffer;
    
      ziffer = posLinks(zahl);
    
      do {
        if(ersteNKStelle(zahl))
          printf(".");
        printf("%c",ziffer->ziffer + '0');
        ziffer = nachRechts(zahl);
      }while(ziffer);
    }
    
    int main(int argc, char* argv[])
    {
      char eingabe[1024];
      TZahl* zahl;
    
      // Zum Testen der Implementierung. Die eingegebene Zahl darf nur aus
      // Ziffern und einem Punkt bestehen und sollte einen Vor- und Nachkommaanteil 
      // haben, die durch einen Punkt getrennt sind. Zum Beispiel: 47.11
      gets(eingabe);
      zahl = read(eingabe);
      druckeZahl(zahl);
      printf("\n");
      normalisiere(zahl);
      druckeZahl(zahl);
      printf("\n");
    }
    


  • Kurz gesagt: Wir sollen deine Hausaufgaben machen?

    Mit der richtigen Bezahlung vielleicht, ansonsten nein.



  • Null = (TZahl*)malloc(sizeof(TZahl)); 
      Null->vkStellen = 0; 
      Null->nkStellen = 0; 
      // Vorkommastelle mit 0 initialisieren 
      Null->vkStelle = (TZiffer*)malloc(sizeof(TZiffer)); 
      Null->vkStelle->ziffer = 0; 
      Null->vkStelle->links = 0; 
      // Nachkommastelle erzeugen 
      Null->vkStelle->rechts = (TZiffer*)malloc(sizeof(TZiffer)); 
      Null->vkStelle->rechts->links = Null->vkStelle; 
      Null->vkStelle->rechts->rechts = 0; 
      Null->vkStelle->rechts->ziffer = 0;
    

    Wenn du weißt, was hier passiert und eine Vorstellung hast, weißt du, wie du die ersten 4 Funktionen schaffst. Die anderen sind ein bisschen anders, aber auch so ähnlich.
    Ein sehr gutes onlinetutorial über die Zeiger und der dynamischen Speicherverwaltung und dynamischen Datenstrutktoren gibt es hier::

    http://www.hs-augsburg.de/~sandman/c_von_a_bis_z/c_014_000.htm#Xxx999328

    Links ist das Inhaltsverzeichniss. Wenn du das hier durchgehst(ich selber brauchte nur 60-90 minuten), brauchst du für die ersten 4 Funktionen maximal(!) nur 1h. 😉

    MFG Majin_Clodan



  • Erstmal vorne weg: Bei dem Code, den Du als 'Vorgaben' gepostet hast, handelt es sich fast ausschließlich um C (ausgenommen der Deklaration der structs). Und selbst wenn Du soviel lernst, dass Du diese Aufgabe zu 100% und ganz zügig lösen kannst, so hast Du anschließend von C++ praktisch keine Ahnung.
    Die Aufgabestellung lehnt sich auch in keiner Weise an Vorgehensweisen an, die in C++ üblich sind (z.B. Einsatz von Klassen/Strukturen und Container-Schnittstellen).

    Zur Erklärung:
    - TZahl* erzeugeNull()
    erzeugt ein Objekt von TZahl und initialisiert es. Ebenso wird jeweils ein Objekt von TZiffer für je eine Vor- und ein Nachkommastelle erzeugt und initialisiert. Die Anzahl wird jeweils mit 0 initialisiert, obwohl jeweils eine Stelle existiert (?) Der Member aktpos ist vergessen worden.

    - TZahl* read(char* text)
    es wird ein TZahl erzeugt (s.o.) dann wird solange zifferVorKomma mit dem Wert der Ziffer auf dem erzeugten TZahl-Objekt aufgerufen, bis ein Dezimal-Trenner erscheint oder der String zu Ende ist. Ist der Test zu Ende wird die Funktion verlassen. Falls nicht 'spult' er den Zeiger 'text' auf den Text bis zum Textende und ruft dann von hinten für jede Ziffer ZifferNachKomma auf. (?)

    - void druckeZahl(TZahl* zahl)
    besorgt sich mit posLinks einen Zeiger auf das TZiffer-Objekt. In der Schleife wird solange der Wert der Ziffer ausgeben und der Zeiger mit nachRechts weiter geschaltet bis dieser zu 0 wird. Wenn derweil irgendwann die Funktion ersteNKStelle true liefert, so wird noch ein '.' eingefügt.



  • Danke zunächst für eure Antworten!

    @Majin_Clodan
    Das Tutorial ist wirklich ganz gut. Ich hab es nun durchgearbeitet. Ich habe mit der Funktion posLinks begonnen. Der Zugriff auf die Elemente ist mir nun klar. Nur wie kann ich jetzt den Zeiger auf die "linkeste" Ziffer setzen??

    Mein bisheriger Ansatz dafür:

    TZiffer* posLinks(TZahl* zahl)
    {
    zahl = (TZahl*)malloc(sizeof(TZahl)); // Speicherreservierung
    zahl->aktPos->links;                  // Hier versuch ich den Zeiger zu setzen
    }
    

    Was mach ich falsch?



  • BartMan schrieb:

    zahl->aktPos->links;                  // Hier versuch ich den Zeiger zu setzen
    

    Was mach ich falsch?

    In dieser Zeile machst du gar nichts. Da könntest du genausogut "3;" in die Zeile schreiben. Da steht nur ein Wert, der keiner Variable zugewiesen wird. Der Compiler wird eine solche Zeile wegkürzen, da ohne Funktion. Tipp: "=" ist der Zuweisungsoperator! 😉



  • BartMan, hast du Werners Beitrag auch gelesen? Das ist kein bisschen C++, was du da machst.

    Wieso verwendest du nicht new und delete ? Oder Klassen? Oder C++-Cast-Operatoren wie static_cast ? Oder gleich Container?



  • TZiffer* posLinks(TZahl* zahl) 
    { 
    zahl = (TZahl*)malloc(sizeof(TZahl)); // Speicherreservierung 
    zahl->aktPos->links;                  // Hier versuch ich den Zeiger zu setzen 
    }
    

    Ja, wie gesagt, wo zeigst du den Zeiger hin?
    Ich gebe dir mal was vor und du machst dann einfach weiter:

    TZiffer* neuZiffer = (TZiffer*)malloc(sizeof(TZiffer)); /**Neuer Objektblock**/
    
        neuZiffer->links = zahl->vkStelle;   /**Zeigung Links vom neuen Objektblock ausgehend**/
    
        neuZiffer->rechts = zahl->vkStelle->rechts; /**Zeigung rechts vom neuen Objektblock ausgehend**/
    
        neuZiffer->ziffer = ziffer; /**Wert im Block, der erstellt wurde**/
    

    Versuche zu verstehen, was hier passiert und wieso es so ist. Damit die Funktion nun vollständig wird, fehlen nur noch 2 Zeilen. 😉 Aber wenn du das oben verstehst, wirst du das auch hinbekommen. 🙂

    MFG Majin_Clodan

    PS: Ich habe es in C programmiert. Kannst auch in C++ machen, aber damit hab ich bisher zu wenig gearbeitet.



  • #include <stdio.h>
    #include <stdlib.h>
    
    struct TZiffer {
      char ziffer;
      TZiffer* links;
      TZiffer* rechts;
    };
    
    struct TZahl {
      TZiffer* vkStelle; // Vorkommastelle
      int nkStellen;     // Nachkommastellen
      int vkStellen;     // Vorkommastellen
      TZiffer* aktPos;   // aktuelle Position in der liste
    };
    
    // Erzeugt den Dezimalbrucch 0.0
    TZahl* erzeugeNull()
    {
      TZahl* Null;
    
      Null = (TZahl*)malloc(sizeof(TZahl));
      Null->vkStellen = 0;
      Null->nkStellen = 0;
      // Vorkommastelle mit 0 initialisieren
      Null->vkStelle = (TZiffer*)malloc(sizeof(TZiffer));
      Null->vkStelle->ziffer = 0;
      Null->vkStelle->links = 0;
      // Nachkommastelle erzeugen
      Null->vkStelle->rechts = (TZiffer*)malloc(sizeof(TZiffer));
      Null->vkStelle->rechts->links = Null->vkStelle;
      Null->vkStelle->rechts->rechts = 0;
      Null->vkStelle->rechts->ziffer = 0;
    
      return Null;
    }
    
    // Gibt 1 zurueck, falls aktPos auf die erste Nachkommastelle zeigt
    int ersteNKStelle(TZahl* zahl)
    {
      return zahl->aktPos == zahl->vkStelle->rechts;
    }
    
    void zifferVorKomma(char ziffer, TZahl* zahl)
    {
      int x = ziffer - '0';
      TZahl* AddL;
    
      AddL = (TZahl*)malloc(sizeof(TZahl));
      ++(AddL->vkStelle);
      AddL->vkStellen = (zahl->vkStellen) +1;
      AddL->nkStellen = (zahl->nkStellen);
      zahl->aktPos = AddL->aktPos;
      // Vorkommastelle mit ziffer initialisieren
      AddL->vkStelle = (TZiffer*)malloc(sizeof(TZiffer));
      AddL->vkStelle->links = zahl->vkStelle;
      AddL->vkStelle->ziffer = x;
      AddL->vkStelle->rechts = 0;
    }
    
    void zifferNachKomma(char ziffer, TZahl* zahl)
    {
      int y = ziffer - '0';
      TZahl* AddR;
    
      AddR = (TZahl*)malloc(sizeof(TZahl));
      AddR->vkStellen = (zahl->vkStellen);
      AddR->nkStellen = (zahl->nkStellen) +1;
      ++(AddR->aktPos);
      AddR->vkStelle = zahl->vkStelle;
      // Nachkommastelle mit ziffer initialisieren
      AddR->vkStelle->rechts = (TZiffer*)malloc(sizeof(TZiffer));
      AddR->vkStelle->rechts->links = zahl->vkStelle->links;
      AddR->vkStelle->rechts->rechts = zahl->vkStelle;
    //  for (AddR->nkStellen !=0) {
    
     // }
    
      AddR->vkStelle->rechts->ziffer = y;
    
    }
    
    TZiffer* posLinks(TZahl* zahl)
    {
      while (zahl->aktPos->links)
          --(zahl->aktPos);
      return  zahl->aktPos;
    }
    
    TZiffer* posRechts(TZahl* zahl)
    {
       while (zahl->aktPos->rechts)
          ++(zahl->aktPos);   
       return  zahl->aktPos;
    }
    
    TZiffer* nachRechts(TZahl* zahl)
    {
             if (zahl->aktPos->rechts) ++(zahl->aktPos);
             else return 0;
    }
    
    TZiffer* nachLinks(TZahl* zahl)
    {
             if (zahl->aktPos->links) --(zahl->aktPos);
             else return 0;
    }
    
    void normalisiere(TZahl* zahl)
    {
          if (zahl->aktPos->links) (zahl->aktPos)--;
          //for (1) {
              //free (AddL->aktPos);
              //if ((zahl->aktPos->links->ziffer) != '0') break;
          //}
    }
    
    // Zum Erzeugen eines Zahlenobjekts aus einem Text
    // Zum Beispiel: text = "12.500600"
    TZahl* read(char* text)
    {
      TZahl* zahl;
    
      zahl = erzeugeNull();
    
      while(*text != '.' && *text) {
        zifferVorKomma(*text - '0',zahl);
        text++;
      }
    
      if(!*text)
        return zahl;
    
      while(*text)
        text++;
    
      text--;
      while(*text != '.') {
        zifferNachKomma(*text - '0',zahl);
        text--;
    
      }
      return zahl;
    
    }
    
    // Zum Ausgeben der Ziffern eines Zahlenobjekts einschliesslich
    // des Kommas
    void druckeZahl(TZahl* zahl)
    {
      TZiffer* ziffer;
    
      ziffer = posLinks(zahl);
    
      do {
        if(ersteNKStelle(zahl))
          printf(".");
        printf("%c",ziffer->ziffer + '0');
        ziffer = nachRechts(zahl);
      }while(ziffer);
    }
    
    int main(int argc, char* argv[])
    {
      char eingabe[1024];
      TZahl* zahl;
    
      // Zum Testen der Implementierung. Die eingegebene Zahl darf nur aus
      // Ziffern und einem Punkt bestehen und sollte einen Vor- und Nachkommaanteil 
      // haben, die durch einen Punkt getrennt sind. Zum Beispiel: 47.11
      gets(eingabe);
      zahl = read(eingabe);
      druckeZahl(zahl);
      printf("\n");
      normalisiere(zahl);
      druckeZahl(zahl);
      printf("\n");
    }
    

    😞 Hilfe XD



  • kibi_kibi schrieb:

    😞 Hilfe XD

    wobei? konkreten Fragen wären hilfreich.

    Der Code enthält einige schwere Fehler. Z.B.:

    kibi_kibi schrieb:

    TZiffer* posLinks(TZahl* zahl)
    {
      while (zahl->aktPos->links)
          --(zahl->aktPos);
      return  zahl->aktPos;
    }
    

    wenn Du in einer Liste einen Pointer 'weiter schaltest' so wird dieser nicht in- oder dekrementiert, sondern auf den Pointer gesetzt, den das Listen-Element vorgibt. Z.B.

    zahl->aktPos = zahl->aktPos->rechts; // aktpos auf das rechts stehende Element weiterschalten
    

    und die Rückgabe der ganz links - also am Anfang - stehenden Ziffer sollte mit

    // Setzt den Zeiger aktPos im Zahlenobjekt zahl auf die am weitesten links stehende Ziffer in diesem Zahlenobjekt und gibt einen Verweis auf diese Ziffer zurück
    TZiffer* posLinks( TZahl* zahl )
    {
        return zahl->aktPos = zahl->vkStelle;
    }
    

    .. zu erledigen sein.

    Gruß
    Werner

    PS.: bist Du BartMan?



  • Werner Salomon schrieb:

    PS.: bist Du BartMan?

    hehe nein ;P aber wir haben das gleiche Aufgabe.
    Danke für Hilfe.
    Meine konkrete Frage: was ist hier falsch?.... in Fuktionen ersteNKStelle(TZahl* zahl), zifferVorKomma(char ziffer, TZahl* zahl), zifferNachKomma(char ziffer, TZahl* zahl), nachRechts(TZahl* zahl), nachLinks(TZahl* zahl), normalisiere(TZahl* zahl).

    Ich habe versucht das zu schreiben, aber bis jetzt weiß ich nicht, ob ich das richtig mache oder nicht XD.



  • kibi_kibi schrieb:

    Meine konkrete Frage: was ist hier falsch?.... in Fuktionen ersteNKStelle(TZahl* zahl), zifferVorKomma(char ziffer, TZahl* zahl), zifferNachKomma(char ziffer, TZahl* zahl), nachRechts(TZahl* zahl), nachLinks(TZahl* zahl), normalisiere(TZahl* zahl).

    Ich habe versucht das zu schreiben, aber bis jetzt weiß ich nicht, ob ich das richtig mache oder nicht XD.

    - ersteNKStelle (s.o.)
    - zifferVorKomma "Fügt in das übergebenen Zahlenobjekt zahl die übergebene Ziffer ziffer unmittelbar vor dem Komma ein. Alle anderen Ziffern vor dem Komma verschieben sich in dem Zahlenobjekt um eine Position nach links. Der Nachkommaanteil bleibt unverändert. ziffer speichert wieder den Wert der Ziffer und nicht das Zeichen. "

    void zifferVorKomma(char ziffer, TZahl* zahl)
    {
      int x = ziffer - '0';
      // AddL = (TZahl*)malloc(sizeof(TZahl)); // Du must eine neue TZiffer erzeugen, eine TZahl hast Du ja schon
      // ++(AddL->vkStelle);  // <- das geht überhaupt nicht (s. mein Kommentar im letzen Posting)
    
      // -- Ziffer erzeugen und alle Member belegen
      TZiffer* AddL = new TZiffer;
      AddL->ziffer = x;
      TZiffer* letzteVkStelle = zahl->vkStelle;
      for( int vk = zahl->vkStellen; vk > 0; --vk, letzteVkStelle = letzteVkStelle->rechts )
          ; // letzteVKstelle über alle VK-Stellen laufen lassen, bis zur letzten; Achtung: führende 0 beachten!
      AddL->links = letzteVkStelle;
      AddL->rechts = letzteVkStelle->rechts;
    
      // -- dann die Zeiger zwischen 'letzteVKstelle' und seinem rechten Nachfolger umhängen
      letzteVkStelle->rechts->links = AddL;
      letzteVkStelle->rechts = AddL;
    
      // -- und mitzählen nicht vergessen
      ++(zahl->vkStellen);
    }
    

    (ohne Gewähr)

    BTW: was bedeute der Member TZahl::vkStellen genau?

    - zifferNachKomma
    so ähnlich sie zifferVorKomma, versuch's mal selber.

    - nachRechts, nachLinks
    siehe mein letztes Posting

    - normalisiere(TZahl* zahl)
    "Implementieren Sie eine Funktion void normalisiere(TZahl* zahl), die führende und abschließende Nullen – bis auf jeweils eine – in einem Zahlenobjekt streicht oder ergänzt, falls keine führende/abschließende 0 vorhanden ist. "

    void normalisiere( TZahl* zahl )
    {
        for( TZiffer* digit = zahl->vkStelle; zahl->vkStellen > 0 && digit->rechts->ziffer == 0; --(zahl->vkStellen) )
        {
            // rechts von der ersten 0 steht auch eine 0 also erstere entfernen
            digit->rechts->links = 0; // rechte 0 wird zur ersten 0
            zahl->vkStelle = digit->rechts;
            free( digit );
            digit = zahl->vkStelle;
        }
        TZiffer* digit = zahl->vkStelle;
        for( ; digit->rechts != 0; digit = digit->rechts )
            ; // letze Nachkommastelle suchen
        for( ; zahl->nkStellen > 0 && digit->links->ziffer == 0; --(zahl->nkStellen) )
        {
            // links von der letzen 0 steht auch eine 0 also die letzte entfernen
            digit->links->rechts = 0; // linke 0 wird zur letzen 0
            TZiffer* tmp = digit;
            digit = digit->links;
            free( tmp );
        }
    }
    

    (auch nicht getestet)
    Gruß
    Werner


Anmelden zum Antworten