Problem mit einfach Verketter Liste
-
Hallo,
ich habe eine kurze Frage:
Ich möchte einen FIFO-Speicher mit Hilfe einer verketten Liste realisieren
an den man beliebig viele Elemente anfügen kann.Dabei soll es drei Operationen geben:
push : ein Element am Listenanfang anfügen.
pop: soll einen Zeier auf das letzte element zurückgeben und dieses dann aus der
Liste entfernen.
allesausgeben: soll den gesamten Speicherinhalt ausgebenDie Funktionen push und allesausgeben funktionieren schon so weit.
Das Problem liegt nun bei der Funktion pop.
Das Entfernen des letzten Elements am Listenende funktioniert schon.
Die funktion liefert auch einen Zeiger auf das letzte Element zurück,
Mit ->wert lasse ich dann in der main() den Wert des Wlements ausgeben.
Der Wert wird auch wie geünscht ausgegeben, jedoch auch alle anderen Listenwerte, was ja nicht gewünscht ist, es soll ja nur der Wert des letzten Listenelements zurückgegeben werden.Wo liegt der Fehler
So hier mal der code:
# include <stdio.h> # include <stdlib.h> struct element { int wert; struct element*next;}*start=NULL; void push(wert){ //push Element struct element *neu; neu= (struct element*) malloc(sizeof(struct element)); //Falls Liste leer if (start==NULL){ start=neu; neu->next=NULL; neu->wert=wert; } else{ neu->next=start; start=neu; neu->wert=wert; } } struct element *pop(void){ //pop elemnt struct element *speicher, *speicher2; speicher=start; speicher2=speicher; while(speicher!=NULL){ printf("%d\n",speicher->wert); if (speicher->next==0) break; speicher2=speicher; speicher=speicher->next; } speicher2->next=NULL; return speicher; } int allesausgeben(void){ struct element *speicher=start; while(speicher!=NULL){ printf("%d\n",speicher->wert); speicher=speicher->next; } } int main(void){ int zahl=0; push(9); // 9 an Pufferanfang einfügen push(3); // 3 an Pufferanfang einfügen push(4); // 4 an Pufferanfang einfügen allesausgeben(); zahl=((pop())->wert); printf("%d\n",zahl); allesausgeben(); system("PAUSE"); return 0; }
Die Ausgabe erfolgt dann zu:
4
3
9
4 //Diese zeichen sollt nicht mit ausgegeben werden, verursacht von pop()
3 //Diese zeichen sollt nicht mit ausgegeben werden, verursacht von pop()
9 //Diese zeichen sollt nicht mit ausgegeben werden, verursacht von pop()
9 // nur die 9 sollt pop() ausgeben
4
3Die Ausgabe sollte eigentlich so aussehen:
4 // allesausgeben()
3 // allesausgeben()
9 // allesausgeben()
9 // pop()
4 // allesausgeben() nach pop
3 // allesausgeben() nach popWäre Dankbar für Tipps......
-
Dann mach doch das
printf
in Zeile 41 weg.Du musst an deinem Einrückungsstil arbeiten.
Danke das du die Code-Tags benutzt hast. Nimm aber ruhig den C-Button. Dann wird es farbig und bint.
-
malloc99 schrieb:
Wo liegt der Fehler
pop()
ist Quark.
Mal Dir Deine queue auf ein Blatt und denk nochmal drüber nach.
Denk auch an den Sonderfall, dass nur ein Element in der Liste ist.Eigentlich darst Du pop() auch nur aufrufen, wenn start!=NULL.
Aktivier auch die Warnungen in Deinem Compiler/ Deiner IDE:
push()
s Parameter hat keinen Typ(Z.12),allesausgeben()
hat einen Rückgabewertint
, gibt aber nix zurück(Z.55/61).Alles kleines Hilfsmittel: bau
asserts
ein:#include <assert.h> void allesausgeben(void){ assert(start!=NULL); struct element *speicher=start; while(speicher!=NULL){ printf("%d\n",speicher->wert); speicher=speicher->next; } void f(){ if(start) // guter Stil. allesausgeben(); }}
-
Ok,
Danke für die schnelle Hilfe, werd den Code noch mal überarbeiten.
Bei " Pop" eines Elements hab ich auch noch free() vergessen, muss auch noch rein.
-
So mal ein Update,
den Sonderfall dass nur 1 Element vorhanden verarbeitet pop nun auch.
Ist kein Element vorhanden, wird das programm mit assert fehlercode beendet.Noch eine frage zum Speicher freigeben:
ich gebe mit pop ja einen Zeiger auf das letzte listenelement zurück, nach der Konsolenausgabe gebe ich den Speicherbereich dann wieder mit free frei.
Gibt es eine Möglichkeit die Speicherfreigabe mit in die Funktion pop () einzubauen?
Hier noch mal ein Codeupdate:
# include <stdio.h> # include <stdlib.h> # include <assert.h> struct element { int wert; struct element*next; }*start=NULL; void push(wert){ //push Element struct element *neu; neu= (struct element*) malloc(sizeof(struct element)); if (start==NULL){ start=neu; neu->next=NULL; neu->wert=wert; } else{ neu->next=start; start=neu; neu->wert=wert; } } struct element *pop(void){ //pop elemnt struct element *speicher, *speicher2; assert(start!=NULL); speicher=start; speicher2=speicher; if(speicher->next==NULL){ // Sonderfall es gibt nur ein Listenelement start=NULL; return speicher; } while(speicher!=NULL){ if (speicher->next==0) break; speicher2=speicher; speicher=speicher->next; } speicher2->next=NULL; return speicher; } void allesausgeben(void){ struct element *speicher=start; assert(start!=NULL); while(speicher!=NULL){ printf("%d\n",speicher->wert); speicher=speicher->next; } } void ausgabe(void){ if(start) allesausgeben(); } int main(void){ int zahl=0; struct element *last; //push(9); // 9 an Pufferanfang einfügen //push(3); // 3 an Pufferanfang einfügen //push(4); // 4 an Pufferanfang einfügen ausgabe(); // Erste ausgabe der 3 Elemente last=pop(); // Ausgabe/Löschen des letzten Listenelements printf("%d\n",last->wert); free(last); // Speicher des oben gelöschten Elements freigeben ausgabe(); system("PAUSE"); return 0; }
Gruß
malloc99
-
malloc 99 schrieb:
ich gebe mit pop ja einen Zeiger auf das letzte listenelement zurück, nach der Konsolenausgabe gebe ich den Speicherbereich dann wieder mit free frei.
Gibt es eine Möglichkeit die Speicherfreigabe mit in die Funktion pop () einzubauen?
Ja.
Wenn Duint
in die Liste steckst, solltest Du auch nurint
rausbekommen. Sonst ist das ganze ja eine Art "Factory" für Listenelemente.
Oder ist das Teil der Aufgabenstellung?malloc 99 schrieb:
struct element *pop(void){ //pop elemnt struct element *speicher, *speicher2; assert(start!=NULL); speicher=start; speicher2=speicher; if(speicher->next==NULL){ // Sonderfall es gibt nur ein Listenelement start=NULL; return speicher; } while(speicher!=NULL){ if (speicher->next==0) break; speicher2=speicher; speicher=speicher->next; } speicher2->next=NULL; return speicher; }
Das scheint mir immer noch komplizierter als nötig.
Ich wette, Du kannst das auf die Hälfte der Zeilen eindampfen, wenn Du Dich wirklich nochmal anstrengst!Los komm: Mein Bildschirm ist zu klein für sowas!
-
Warte immer noch auf die Erleuchtung......
wenigstes ein return weniger.....
popupdate:
struct element *pop(void){ //pop element struct element *speicher=start, *speicher2=start; assert(start!=NULL); speicher2->next=NULL; if(speicher2->next==NULL) start=NULL; while(speicher!=NULL){ if(speicher->next!=NULL){ speicher2=speicher; speicher=speicher->next; } else break; } speicher2->next=NULL; return speicher; }
Gruß
malloc99
-
malloc 99 schrieb:
Warte immer noch auf die Erleuchtung......
wenigstes ein return weniger.....
popupdate:
struct element *pop(void){ //pop element struct element *speicher=start, *speicher2=start; assert(start!=NULL); speicher2->next=NULL; if(speicher2->next==NULL) start=NULL; while(speicher!=NULL){ if(speicher->next!=NULL){ speicher2=speicher; speicher=speicher->next; } else break; } speicher2->next=NULL; return speicher; }
Naja, wahrscheinlich habe ich das Maul zu voll genommmen, was das Verkürzen anbelangt.
Aber den Vorschlag,
pop()
zu ändern inint pop(){ // .... int i = xyz->next->wert; free(xyz->next); xyz->next=NULL; return i; }
Hast du mitbekommen?
-
Ja hab ich mitbekommen,
stimmt ja die rückgabe des int wertes reicht in diesem Fall ja.
Hätte man eine struct mit mehr elementen, die man zurückgeben will,
zb. wert, name , datum.....
kann man das free dann aber nicht in pop() reinziehen.
Deshalb habs ich mal rausgelassen
Vielen Dank für die gute Unterstützung , einfach klasse..
Gruß
malloc 99
-
Globale Variablen sind Schrott.