Brauche etwas Hilfe mit verketteten Listen!
-
Hallo,
ich habe vorgestern 2 Bücher über C/C++ zum Geburtstag gekriegt (von Stefan Zerbst fals das euch was sagt). Habe schon sehr viel Positives darüber gehört und ich selber find es auch sehr gut, aber ich habe da ein Problem:
Ich habe bisher alles soweit verstanden, aber bei den verketteten Listen komme ich nicht klar. Im Buch steht folgender Code:#define XXX_RESULT int #define XXX_OK 0 #define XXX_MEMORY_ERROR 1 #define XXX_OUT_OF_BOUNDS 2 XXX_RESULT xxx_List_Create(XXXList **pp_list) { *pp_list = (XXXList*)malloc (sizeof(XXXList)); if (*pp_list == NULL) return XXX_MEMORY_ERROR; (*pp_list)->data = NULL; (*pp_list)->next = NULL; returnXXX_OK; }
Ich weiss nicht ob ich das richtig verstanden habe, aber stimmt es, wenn ich annehme ,dass da erst das Zeug definiert wird (ist mir klar) und dann eine int Funktion mit Namen xxx_list_create initialisiert wird mit einem Parameter?
Wenn ja, ist das soweit klar, aber da kommt auch schon die nächste Frage:
was soll das: XXXList **pp_list ??
warum denn ** ?
Das wär erstmal meine Frage. Dann verstehe ich den Rest vielleicht auch.
MFG Muffin Man
-
XXXList ** p; deklariert einen Zeiger auf einen Zeiger auf XXXList. Vielleicht wirds in der Anwendung klarer. Man würde dann ungefähr so schreiben:
XXXList * listptr; int result = XXX_List_Create(&listptr); if (result != XXX_OK) // mööp error
Dazu bleibt zu sagen, dass das nicht gerade berauschender Stil ist, ums mal vorsichtig auszudrücken. Das nutzt eigentlich nur den Teil von C++, der auch in C enthalten ist. Von daher ist von diesem Buch (oder beiden) abzuraten, wenn man damit C++ lernen will.
-
Ah, Danke
das Buch beschäftigt sich nicht hauptsächlich mit C++ an sich, sondern mit DirectX und DirectDraw und so das aber halt mit C++ programmiert.
Aber dann hätte ich noch ne Frage, warum wird dann später nur *pp_list geschrieben?
Oder erwartet die Funktion im Rückgabewert einen Pointer der ein Pointer auf *pp_list ist?
-
Wenn Du dir ein einfache Liste implementiren willst, versuch es mal damit:
struct node { char *zeile; node *prev, *next; }; class my_list { private: node *_liste; node *start; node *end; node *itt; int lang; public: my_list(); ~my_list(); bool anh(char *value); bool find(char *value); bool del(char *value, int numb); void show(void); }; my_list::my_list() { _liste=new node; _liste->next=NULL; _liste->prev=NULL; start=_liste; end=_liste; lang=0; } my_list::~my_list() { _liste=end; while(_liste->prev!=NULL) { _liste->zeile="NULL"; _liste=_liste->prev; delete _liste->next; } _liste->zeile=NULL; end=_liste; } bool my_list::anh(char *value) { end->zeile=value; end->next=new node; _liste=end->next; _liste->next=NULL; _liste->prev=end; end=_liste; lang++; return true; } bool my_list::del(char *value, int numb) { return true; } void my_list::show(void) { _liste=start; do { cout<<_liste->zeile<<";"<<endl; _liste=_liste->next; }while(_liste->next!=NULL); }
Die ist zwar noch etwas bugig, aber Du kannst schon werte einfügen und sie Dir anzeigen lassen.
-
Danke gleichfalls werde ich mir mal angucken. Aber im Moment wollte ich nur erstmal dieses Beispiel verstehen.
-
Muffin Man schrieb:
Ah, Danke
das Buch beschäftigt sich nicht hauptsächlich mit C++ an sich, sondern mit DirectX und DirectDraw und so das aber halt mit C++ programmiert.Du machst aber den Eindruck als bräuchtest du ein Buch, was sich hauptsächlich mit C++ beschäftigt.
Aber dann hätte ich noch ne Frage, warum wird dann später nur *pp_list geschrieben?
Guck nochmal auf den Code von mir, wie man diese Funktion wahrscheinlich aufruft. Du wirst feststellen, dass es dort einen Zeiger auf einen Listenknoten gibt (ich hab ihn listptr genannt). Dann übergebe ich der Funktion die Adresse dieses Zeigers.
Die Aufgabe der Funktion ist es jetzt, den Zeiger zu ändern. Ihr wurde die Adresse übergeben, dh ein Zeiger auf dieses Zeiger. Jetzt greifen wir in die absolute C++-Grundlagenkiste und fragen uns, wie kommen wir von einem Zeiger auf das was er zeigt? Mit dem * Operator.OK systematisch. pp_list zeigt während dieses konkreten Aufrufes auf listptr. Mit *pp_list komm ich also an listptr und kann ihn verändern.
Mit C++ Mitteln ist das ganze viel einfacher, und würde ungefähr so aussehen:
void create_list(List*& node_ptr) // Übergabe des Zeigers per Referenz { // new wirft bei Fehlschlag eine Exception, dh wir müssen uns nicht schon an dieser //Stelle um die Fehlerabfrage kümmern node_ptr = new List; node_ptr->data = node_ptr->next = 0; } // Aufruf: List* list_ptr; create_list(list_ptr);
Und das nutzt nur wenige Dinge, noch nichtmal beispielsweise, dass es Konstruktoren und Templates gibt.
Oder erwartet die Funktion im Rückgabewert einen Pointer der ein Pointer auf *pp_list ist?
Rückgabewert wovon? Need more input.
-
Naja, das in der Klammer hinter dem Funktionsnamen verlangt er doch als Rückgabewert, wenn die Funktion abgebrochen werden soll, oder?
-
Nein, das sind die Parameter der Funktion. Der Rückgabetyp steht vor dem Funktionsnamen.
-
Ups, ja, klar, sorry habe ich verwechselt dann ist klar.