zu der Aufgabe etwas weiter unten Kundenverwaltung



  • Das ist selbst in der Uni noch so.



  • AlleNamenBelegt schrieb:

    Hier nochmal die Aufgabe: http://www.c-plusplus.net/forum/viewtopic-var-t-is-268977.html

    Das hilft nicht, aber ich sag's trotzdem: Was für eine besch***ene Aufgabe!

    Ich zitiere:

    Die Elemente eines Kundendatensatzes könnten z.B. aus Nachname, Vorname, Straße, PLZ, Wohnort und Geburtsdatum bestehen, ausschließlich Daten des Typs char-Array. Namen, Straße und Ort sollten Arrays ausreichender Länge sein, für die PLZ reicht eine Größe von 6 Zeichen und für Geburtsdaten von 11 Zeichen. Um [...] keinen Speicher unnötig zu verschwenden, sollen die Arrays dynamisch und nur dann erzeugt werden, wenn tatsächlich Daten eines neuen Kunden im System eingetragen werden müssen. Alle bei der dynamischen Speicheranforderung der char-Arrays für einen Kunden erhaltenen char-Zeiger sollen in einem Array zusammengefasst werden (siehe unten). Dieses muss ebenfalls dynamisch erzeugt werden.

    Ja was denn nun? Soll er sich mal entscheiden, ob er Arrays oder Zeiger als Elemente haben will.

    Hinweis: Falls innerhalb eines Arrays verschiedene Arten von Zeigern gespeichert werden müssen, z.B. char-Pointer und Pointer auf char-Pointer, dann kann man das Array auch als Array für void-Pointer definieren. Die einzelnen Pointer im Array sind dann vor ihrer Verwendung auf den benötigten Pointer-Typ umzucasten.

    Was für ein Dreck. 👎

    Tipp: Wenn man sich noch den Rest dessen durchliest, was Dein Lehrer da verzapft hat, kommt man zum Ergebniss, dass er folgendes sehen will:

    typedef void **Kundendatensatz;
    

    janz große Sch***e! 😮 👎

    Du könntest Deinen Lehrer vorsichtig fragen, ob Du ein anderes der Design der Datenstruktur verwenden darfst. ZB so etwas:

    #include <string>
    
    struct Kundendatensatz
    {
      std::string nachname;
      std::string vorname;
      std::string strase;
      std::string plz;
      std::string wohnort;
      std::string geburtsdatum;
      Kundendatensatz *next;
    };
    

    btw: Das SZ (in Straße) ist als Teil eines Bezeichners nicht erlaubt.

    kk



  • nee leider müssen wir das mit chararrays und pointer machen

    und ich kriegs echt nicht hin...das ist mehr als dumm 😞



  • Fellhuhn schrieb:

    Das ist selbst in der Uni noch so.

    Nein, ist es nicht - zumindest nicht zwangsweise (Ich bin mir recht sicher schon in der FH Zeit vor über 10 Jahren mit der Standardbibliothek - die aber noch nicht 100% normiert war). Wobei man hier auch unterscheiden muss, was das Ziel einer Aufgabe ist.

    Wenn das Ziel ist, auch eine dynamische Liste zu erzeugen um das Prinzip zu verstehen, ist die Standardbibliothek nicht geeignet.



  • AlleNamenBelegt schrieb:

    nee leider müssen wir das mit chararrays und pointer machen und ich kriegs echt nicht hin...das ist mehr als dumm 😞

    Wenn du etwas gegoogelt hättest, die Stichworte wurden genannt, hättest du die Erklärung bekommen. Ein Beispiel ist

    hier
    


  • asc schrieb:

    Fellhuhn schrieb:

    Das ist selbst in der Uni noch so.

    Nein, ist es nicht - zumindest nicht zwangsweise (Ich bin mir recht sicher schon in der FH Zeit vor über 10 Jahren mit der Standardbibliothek - die aber noch nicht 100% normiert war). Wobei man hier auch unterscheiden muss, was das Ziel einer Aufgabe ist.

    Vor 4 Jahren als ich von der Uni ging hatte von den Profs nur ein sehr geringer Teil von der STL überhaupt gehört und von den Tutoren die die Programmierarbeiten begleiteten hatte es keiner.



  • AlleNamenBelegt schrieb:

    und ich kriegs echt nicht hin...

    Überlege Dir mal ein paar Fragen, die man hier beantworten kann, ohne dass so eine Antwort Dir gleich einen Großteil der Arbeit Deiner Hausaufgabe abnimmt. Sonst wird der Thread hier (wahrscheinlich) auch wieder geschlossen.

    Ist Dir denn klar, wie Dein Lehrer die Daten im Speicher organisiert haben will?



  • und nur mal so nebenbei, diese Seite taucht bei Google immer ganz oben auf und das innerhalb weniger Minuten nachdem man was geschrieben hat. Daher ist es nicht besonders clever die Aufgabenstellung 1:1 abzuschreiben, vor allem nicht wenn man sich alles vorkauen läßt. 😉



  • Fellhuhn schrieb:

    und nur mal so nebenbei, diese Seite taucht bei Google immer ganz oben auf und das innerhalb weniger Minuten nachdem man was geschrieben hat. Daher ist es nicht besonders clever die Aufgabenstellung 1:1 abzuschreiben, vor allem nicht wenn man sich alles vorkauen läßt. 😉

    ich denke ich mache damit nichts falsches, wenn ich mir dafür hilfe suche? das darf mein Lehrer ruhig wissen, dass ich für sowas etwas hilfe brauch. es ist eine freiwillige Aufgabe, dass heißt ich muss sie nicht machen. Ich versuche sie aber trotzdem und darf mir da doch wohl hilfe suchen 🙂



  • Bin ich damit denn schon irgendwie nah dran? oder weit daneben?

    #include <iostream>
    
    using namespace std;
    
    int main()
    {    
    
    char *nachname= new char;
    char *vorname= new char;
    char *straße= new char;
    char plz[6];
    char *wohnort= new char;
    char geburtsdatum[11];
    
    cout<<"Nachname?";
    cin>>nachname;
    cout<<"Vorname?";
    cin>>vorname;
    cout<<"Straße?";
    cin>>straße;
    cout<<"PLZ?";
    cin>>plz;
    cout<<"Wohnort?";
    cin>>wohnort;
    cout<<"Geburtsdatum?";
    cin>>geburtsdatum;
    
    delete nachname;
    delete vorname;
    delete straße;
    delete wohnort;
    
    system("PAUSE");
    
    }
    


  • AlleNamenBelegt schrieb:

    Bin ich damit denn schon irgendwie nah dran? oder weit daneben?

    Weit daneben. Du hast anscheinend schon die Aufgabenstellung nicht verstanden. Die muss man natürlich erstmal verstehen, bevor es losgehen kann. Versuch mal ein Beispiel aufzumalen, das zeigt, was wo wie im Speicher liegt und wie verknotet ist. ZB für zwei Kundendatensätze mit jeweils Vor/Nachnahme. Objekte als Kästchen zeichnen. Je nach inhalt (Zeichen, Zeiger) kannst Du Buchstaben reinpacken oder einen Pfeil dran malen (für Zeiger), die auf irgendwas zeigen.

    Beispiel:

    #include <cstring>
    #include <iostream>
    
    int main()
    {
      char * zeiger = new char[10];
      std::strcpy(zeiger,"test");
      // X
      std::cout << zeiger;
      delete[] zeiger;
    }
    
    Zum Zeitpunkt X sieht es so im Arbeitsspeicher aus:
    
       zeiger        ein char-Array
       +---+         +---+---+---+---+---+---+---+---+---+---+
       | * |         | t | e | s | t |\0 | ? | ? | ? | ? | ? |
       +-+-+         +---+---+---+---+---+---+---+---+---+---+
         |             A
         +-------------+
    

    kk



  • int main()
    {
    char * zeiger = new char[10];
    std::strcpy(zeiger,"test");
    // X

    also aber da ist doch der name test vorgegeben? aber der kunde müsste ja sozu sagen dort was eintragen *verwirrt guck*


  • Mod

    AlleNamenBelegt schrieb:

    int main()
    {
    char * zeiger = new char[10];
    std::strcpy(zeiger,"test");
    // X

    also aber da ist doch der name test vorgegeben? aber der kunde müsste ja sozu sagen dort was eintragen *verwirrt guck*

    In Fachkreisen nennt man das ein Beispiel.



  • AlleNamenBelegt schrieb:

    also aber da ist doch der name test vorgegeben? aber der kunde müsste ja sozu sagen dort was eintragen *verwirrt guck*

    Das war auch nur ein kleines Beispiel um zu zeigen, wie so ein Bildchen aussehen kann. Ich hatte Dich ja gebeten, als Übung so ein Bildchen für ein Beispiel mit zwei Kundendatensätzen samt ihrer "Felder" selbst anzulegen. Das habe ich gemacht, weil ich glaube, dass diese Übung Dir weiterhelfen kann.

    kk



  • Den Code dazu habe ich nur so gezeigt. Darum ging es mir gar nicht. Ich würde an Deiner Stelle also versuchen, erst das Bild/Speicherlayout für ein Beispiel mit 2 Kundendatensätzen korrekt zu erstellen und dann erst darüber nachzudenken, was Du in C++ dafür schreiben musst...



  • Also so?

    int main()
    {
    
      char * nachname = new char[10]; <---- wieso wird da jetzt ne 10 rein? da vergibt man doch speicherplatz?
      char * vorname  = new char[10]
      std::strcpy(nachname,"mustermann");
      std::strcpy(vorname, "max");
    
      std::cout << nachname;
      std::cout << vorname;
      delete[] nachname;
      delete[] vorname;
    }
    
       +---+         +---+---+---+---+---+---+---+---+---+---+
       | * |         | m | u | s | t | e | r | m | a | n | n |
       +-+-+         +---+---+---+---+---+---+---+---+---+---+
         |             A
         +-------------+ 
    
       +---+         +---+---+---+---+---+---+---+---+---+---+
       | * |         | m | a | x | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
       +-+-+         +---+---+---+---+---+---+---+---+---+---+
         |             A
         +-------------+
    


  • Wie gesagt, ich will keinen C++ Code im Moment von Dir sehen. Nur ein Bild, was zwei Kundendatensätze samt "Felder" zeigt. Laut Aufgabenstellung sollen die Zeiger selbst ja ein Feld bilden, was dynamisch (also ber new[] zB) angelegt werden soll. Das stimmt schonmal bei Dir nicht, weil Du die Zeiger als einzelne Objekte getrennt voneinander aufgemalt hast. Bei einem Feld/Array stehen die Elemnte direkt hintereinander im Speicher. Denk auch an den zusätzlichen Zeiger, der die Kundendatensätze verketten soll.


  • Mod

    Wenn du das ausprobierst: Kommt da bei der Ausgabe wirklich "mustermann" raus? Immer? Auch mit Compileroptimierungen (Release-Modus)?

    Denn eigentlich ist bei char-Arrays noch ein abschließendes Nullzeichen per Konvention vorgesehen um das Ende anzuzeigen, so dass du für "mustermann" 11 Zeichen benötigst.

    Warum die 10 und nicht z.B. für max eine sparsamere 4? Ja, kannste machen. Macht man normalerweise auch. Aber das ist ein kleines bisschen schwieriger und du stolperst derzeit noch bei den einfacheren Sachen. Mach dich lieber erstmal damit vertraut.



  • Also so?

    int main()
    {
    
      char * nachname, * vorname = new char[15]; 
    
      std::strcpy(nachname,"mustermann");
      std::strcpy(vorname, "max");
    
      std::cout << nachname;
      std::cout << vorname;
      delete[] nachname;
      delete[] vorname;
    }
    
       +---+         +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
       | * |         | m | u | s | t | e | r | m | a | n | n | m | a | x | 0 | 0 |
       +-+-+         +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
         |             A
         +-------------+
    

    sorry das ich so schwer von Begriff bin 😞



  • Hehe, nein, so auch nicht.
    Zum ersten ist deine Variablendeklaration falsch:

    char * nachname, * vorname = new char[15];
    

    Diese Zeile deklariert die Variable nachname, sie hat einem zufälligen Wert und zeigt demnach auch auf einen zufälligen Bereich des Hauptspeichers. Sämtliche Zugriffe auf den Speicherbereich, auf den nachname zeigt, erzeugt undefiniertes Verhalten (weil man nicht weiß, auf was nachname denn jetzt genau zeigt).
    Die Variable vorname zeigt auf einen dynamisch erzeugten Speicherblock der Länge 15 und ist korrekt intialisiert.

    Zum zweiten kannst du nie davon ausgehen, dass du Speicher an einer bestimmten Adresse des Hauptspeichers bekommst bzw. dass zwei aufeinanderfolgende Speicheranforderungen direkt hintereinander im Hauptspeicher liegen.

    Dynamische Speicherverwaltung und Zeigerarithmetik sind für Anfänger nicht unbedingt einfach zu verstehen, man muss sich schon etwas damit auseinandersetzen.


Anmelden zum Antworten