einfach verkettete Listen erstellen
-
Hallo liebe Community!!
Ich versuche mich derzeit an einer verketteten Liste, um mein Horizont zu erweitern
Jedoch habe ich bereits bei der Erstellung diverse Fehler, die ich selbst nicht ausfindig machen kann.Mein Kenntnisstand:
1 1/2 Semester C-ProgrammierungAufgabe:
Dynamische Erstellung einer einfach verketteten Liste, welche anschließend verwaltet werden soll.Compiler:
MS-CompilerBisheriger Code:
#include <stdio.h> #include <stdlib.h> void abfrage(char *wahl, int *werte); void erstellen(char wahl,int werte,struct listeElement *start,struct listeElement *neuesElement); typedef struct listeElement{ int zahl; struct listeElement *weiter; }data,*pdata; int main(void){ int ianzahl; int *panzahl=&ianzahl; char cplatz; char *pplatz=&cplatz; struct listeElement neuesElement; struct listeElement *pneuesElement=&neuesElement; struct listeElement start; struct listeElement *pstart=&start; printf("Verkettete Listen\n=================\n\n"); abfrage(pplatz,panzahl); erstellen(cplatz,ianzahl,pstart,pneuesElement); if(cplatz == 'v'){ printf("Das 1. Element hat den Wert: %d", pstart->zahl); printf("Das 2. Element hat den Wert: %d", pstart->weiter->zahl); printf("Das 3. Element hat den Wert: %d", pstart->weiter->weiter->zahl); } else{ printf("Das 1. Element hat den Wert: %d", pneuesElement->zahl); printf("Das 2. Element hat den Wert: %d", pneuesElement->weiter->zahl); printf("Das 3. Element hat den Wert: %d", pneuesElement->weiter->weiter->zahl); } system("PAUSE"); return 0; } void abfrage(char *pwahl, int *pwerte){ printf("Wieviele Elemente sollen erstellt werden?\n"); scanf("%d", pwerte); fflush(stdin); printf("\nSollen die Werte (v)or oder (n)ach dem zuletzt eingegebenen\n" "Element eingefuegt werden?\n"); do{ scanf("%c", pwahl); fflush(stdin); if(!(*pwahl=='v' || *pwahl=='n')) printf("Ungueltige Eingabe! Entweder (v) fuer vor oder (n) fuer nach eingeben!\n"); }while(!(*pwahl=='v' || *pwahl=='n')); } void erstellen(char wahl,int werte,struct listeElement *fstart,struct listeElement *fneuesElement){ int i; if(wahl=='v'){ for(i=werte;i>=1;i--){ fneuesElement = (pdata)malloc(sizeof(data)); if (fneuesElement == NULL) { printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } printf("Das %d. Element: ",i); scanf("%d", &(fneuesElement->zahl)); fflush(stdin); if(i==werte) fneuesElement->weiter=NULL; else fneuesElement->weiter=fstart; fstart=fneuesElement; } } else{ for(i=1;i<=werte;i++){ fneuesElement = (pdata)malloc(sizeof(data)); if (fneuesElement == NULL) { printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } printf("Das %d. Element: ",i); scanf("%d", &(fneuesElement->zahl)); if(i==1) fneuesElement->weiter=NULL; else fstart->weiter=fneuesElement; fstart=fneuesElement; } } return; }
Fehlerquelle:
Die Funktion "erstellen".Diese habe ich versucht vereinfacht aufzubauen um Fehlerquellen zu finden, dabei habe ich 3 fixe Elemente erstellt.
void erstellen(char wahl,int werte,struct listeElement *fstart,struct listeElement *fneuesElement){ fneuesElement = (pdata)malloc(sizeof(data)); fneuesElement->zahl=20; printf("Das 1. Element: %d\n",fneuesElement->zahl); fneuesElement->weiter=NULL; fstart=fneuesElement; fneuesElement = (pdata)malloc(sizeof(data)); fneuesElement->zahl=15; printf("Das 2. Element: %d\n",fneuesElement->zahl); fneuesElement->weiter=fstart; fstart=fneuesElement; fneuesElement = (pdata)malloc(sizeof(data)); fneuesElement->zahl=15; printf("Das 3. Element: %d\n",fneuesElement->zahl); fneuesElement->weiter=fstart; fstart=fneuesElement; }
In der main habe ich testweise die Werte abgefragt, jedoch kommt schon beim ersten Element ein zufällig generierter Wert. Die pointer innerhalb der Elemente scheinen auch nicht auf die jeweils nächsten Elemente zu zeigen.
Der Compiler liefert mir foldenden Fehler:
"Unbehandelte Ausnahme bei 0x013c1469 in SSH3.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcccccccc."
Ich bin dankbar für jeden TIPP und Verbesserungsvorschlag.
-
Den Wert von pstart bekommst du so nicht aus erstellen raus.
Entweder du nimmst den Rückgabewertstruct listeElement * erstellen(char wahl,int werte,struct listeElement *fstart,struct listeElement *fneuesElement){ ... return fstart; } ... pstart = erstellen(.....);
oder einen Doppelzeiger
void erstellen(char wahl,int werte,struct listeElement **fstart,struct listeElement *fneuesElement){ ... return fstart; } ... erstellen(cplatz,ianzahl,&pstart,pneuesElement);
Wozu übergibst du an
erstellen
überhauptfneuesElement
, wenn du es erst in erstellen anlegst?Wozu brauchst du diese Variablen in main?
int *panzahl=&ianzahl; char *pplatz=&cplatz; struct listeElement neuesElement; struct listeElement *pneuesElement=&neuesElement; struct listeElement start;
Und eine leere Liste initialisiert man mit NULL
struct listeElement *pstart=NULL;
Dein Programm ist ziemlich Durcheinander und wenig struckturiert.
Schreibe eine Funktion zum erzeugen eines neuen Elementes und eine zum anhängen.
Funktionen wie erstellen sollten sich nicht mit 'v' oder 'n' rumplagen.
Dafür gibt es 0 oder 1.
-
vielen vielen dank DirkB! Zu meiner überraschung musste ich nach und nach feststellen wie Recht du doch hast
nachdem ich mir den codesalat den ich hier aufgetischt habe nochmal durchgesehen hab muss ich zugeben, dass viel verkehrt war :SHeute morgen hatte ich das Programm mit dem doppelpointer für kurze zeit zum laufen bekommen, jedoch hab ich mich entschieden weiter zu optimieren.. nun wird wieder ein Fehler verursacht, sodass der start-pointer nicht in die main gelangen kann
Möchte die Funktionen am liebsten ohne Rückgabewerte, nur mit pointern handhaben(Da es mein erstes programm mit pointern ist, wollt ich mal ausgiebig drauf eingehen..)
#include <stdio.h> #include <stdlib.h> void abfrage(int *fpiplatz, int *fpianzahl); void erstellen(int fiplatz,int fianzahl,struct listeElement **fppstart); void eingabe(int fiplatz,int fianzahl,struct listeElement **fppstart); typedef struct listeElement{ int izahl; struct listeElement *pweiter; }data,*pdata; int main(void){ int ianzahl,iplatz; struct listeElement *pstart=NULL; printf("Verkettete Listen\n=================\n\n"); abfrage(&iplatz,&ianzahl); erstellen(iplatz,ianzahl,&pstart); eingabe(iplatz,ianzahl,&pstart); if(iplatz==1){ while(ianzahl>1){ int i=ianzahl; printf("Das %i. Element hat den Wert: %i\n",i, pstart->izahl); pstart=pstart->pweiter; i--; } } else{ while(ianzahl>1){ int i=ianzahl; printf("Das %i. Element hat den Wert: %i\n",i, pstart->izahl); pstart=pstart->pweiter; i--; } } system("PAUSE"); return 0; } void abfrage(int *fpiplatz, int *fpianzahl){ printf("Wieviele Elemente sollen erstellt werden?\n"); scanf("%i", fpianzahl); fflush(stdin); printf("\nSollen die Werte vor(1) oder nach(0) dem zuletzt eingegebenen\n" "Element eingefuegt werden?\n"); do{ scanf("%i", fpiplatz); fflush(stdin); if(!(*fpiplatz==1 || *fpiplatz==0)) printf("Ungueltige Eingabe! Entweder (1) fuer vor oder (0) fuer nach eingeben!\n"); }while(!(*fpiplatz==1 || *fpiplatz==0)); } void erstellen(int fiplatz,int fianzahl,struct listeElement **fppstart){ int i; //Die Elemente werden vor das zuletzt eigegebene gesetzt if(fiplatz==1){ for(i=fianzahl;i>=1;i--){ struct listeElement *neuesElement = (pdata)malloc(sizeof(data)); if (neuesElement == NULL) { printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } if(i==1) neuesElement->pweiter=NULL; if(i!=fianzahl) neuesElement->pweiter=(*fppstart); (*fppstart)=neuesElement; } } //Die Elemente werden nach das zuletzt eigegebene gesetzt else{ for(i=1;i<=fianzahl;i++){ struct listeElement *neuesElement = (pdata)malloc(sizeof(data)); if (neuesElement == NULL) { printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } if(i==1) neuesElement->pweiter=NULL; else neuesElement->pweiter=(*fppstart); (*fppstart)=neuesElement; } } return; } void eingabe(int fiplatz,int fianzahl,struct listeElement **fppstart){ int i; struct listeElement **temp=fppstart; if(fiplatz==1){ for(i=fianzahl;i>=1;i--){ printf("Das %i. Element: ",i); scanf("%i", &((*fppstart)->izahl)); fflush(stdin); (*fppstart)=((*fppstart)->pweiter); } } else{ for(i=1;i>=fianzahl;i++){ printf("Das %i. Element: ",i); scanf("%i", &((*fppstart)->izahl)); fflush(stdin); (*fppstart)=((*fppstart)->pweiter); } } fppstart=temp; }
-
In Zeile 115 fehlt der *
-
danke nochmals DirkB!
Da steckte der Fehler! Nun läuft die Erstellung der verketteten Liste, jedoch nur mit Elementen die ich vor(1) das zuletzt erstellte anfüge.
Ich habe mir für die "nach"-Variante zeichnungen angefertigt, schritt für schritt durchgegangen,... bin aber leider wieder mit meinem Latein am Ende
meine Überlegung:
einen temporären pointer nutzen, um die liste zu erstellen. Den Startpointer beim ersten element lassen.hier die explizite Variante des Codes um die "erstellen"-Funktion zu testen.
#include <stdio.h> #include <stdlib.h> void erstellen(int fiplatz,int fianzahl,struct listeElement **fppstart); typedef struct listeElement{ int izahl; struct listeElement *pweiter; }data,*pdata; int main(void){ int ianzahl=3,iplatz=0; struct listeElement *pstart=NULL; printf("Verkettete Listen\n=================\n\n"); erstellen(iplatz,ianzahl,&pstart); pstart->izahl=10; pstart->pweiter->izahl=5; pstart->pweiter->pweiter->izahl=22; printf("1.Element= %i\n",pstart->izahl); printf("2.Element= %i\n",pstart->pweiter->izahl); printf("3.Element= %i\n",pstart->pweiter->pweiter->izahl); system("PAUSE"); return 0; } void erstellen(int fiplatz,int fianzahl,struct listeElement **fppstart){ int i; //Die Elemente werden vor das zuletzt eigegebene gesetzt if(fiplatz==1){ for(i=fianzahl;i>=1;i--){ struct listeElement *neuesElement = (pdata)malloc(sizeof(data)); if (neuesElement == NULL) { printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } if(i==1) neuesElement->pweiter=NULL; if(i!=fianzahl) neuesElement->pweiter=(*fppstart); (*fppstart)=neuesElement; } } //Die Elemente werden nach das zuletzt eigegebene gesetzt else if(fiplatz==0){ struct listeElement *neuesElement = (pdata)malloc(sizeof(data)); struct listeElement *temp = neuesElement; (*fppstart)=neuesElement; for(i=1;i<=fianzahl;i++){ if(i!=1){ struct listeElement *neuesElement = (pdata)malloc(sizeof(data)); } if (neuesElement == NULL) { printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } if(i!=1){ temp->pweiter=neuesElement; } if(i==fianzahl){ neuesElement->pweiter=NULL; } temp=neuesElement; } } return; }
iplatz(Zeile 12) kann auf 1 gesetzt werden, um die "vor"-Variante zu durchlaufen.
PS:
Ich habe mir heute noch Code::Blocks geholt und habe den code mit dem GNU-Complier durchlaufen. Dabei zeigt er so einige Warnungen und Errors aufBei dem ausschnitt von oben wäre das:
D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c|3|warning: 'struct listeElement' declared inside parameter list| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c|3|warning: its scope is only this definition or declaration, which is probably not what you want| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c||In function 'main':| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c|17|warning: passing argument 3 of 'erstellen' from incompatible pointer type| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c|3|note: expected 'struct listeElement **' but argument is of type 'struct listeElement **'| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c|32|error: conflicting types for 'erstellen'| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c|3|note: previous declaration of 'erstellen' was here| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c||In function 'erstellen':| D:\Program Files (x86)\CodeBlocks\projekte\neuSSH3\main.c|58|warning: unused variable 'neuesElement'| ||=== Build finished: 1 errors, 4 warnings ===|
-
Du benutzt listeElement, bevor du es definiert hast. Zieh die Definition (Zeilen 6-9) weiter vor.
-
SeppJ schrieb:
Du benutzt listeElement, bevor du es definiert hast. Zieh die Definition (Zeilen 6-9) weiter vor.
Danke, das behebt die warnings und den error
Sooo, habs, sieht aber noch sehr unübersichtlich aus find ich ^^
Nun werd ich mich mal an die verwaltungsfunktionen machen.#include <stdio.h> #include <stdlib.h> typedef struct listeElement{ int izahl; struct listeElement *pweiter; }data,*pdata; void abfrage(int *fpiplatz, int *fpianzahl); void erstellen(int fiplatz,int fianzahl,struct listeElement **fppstart); void eingabe(int fiplatz,int fianzahl,struct listeElement **fppstart); int main(void){ int ianzahl=0,iplatz=-1; struct listeElement *pstart=NULL; printf("Verkettete Listen\n=================\n\n"); abfrage(&iplatz,&ianzahl); erstellen(iplatz,ianzahl,&pstart); eingabe(iplatz,ianzahl,&pstart); if(iplatz==1){ while(ianzahl>=1){ printf("Das %i. Element hat den Wert: %i\n",ianzahl, pstart->izahl); pstart=pstart->pweiter; ianzahl--; } } else{ int i=1; while(i<=ianzahl){ printf("Das %i. Element hat den Wert: %i\n",i, pstart->izahl); pstart=pstart->pweiter; i++; } } system("PAUSE"); return 0; } void abfrage(int *fpiplatz, int *fpianzahl){ printf("Wieviele Elemente sollen erstellt werden?\n"); scanf("%i", fpianzahl); fflush(stdin); printf("\nSollen die Werte vor(1) oder nach(0) dem zuletzt eingegebenen\n" "Element eingefuegt werden?\n"); do{ scanf("%i", fpiplatz); fflush(stdin); if(!(*fpiplatz==1 || *fpiplatz==0)) printf("Ungueltige Eingabe! Entweder (1) fuer vor oder (0) fuer nach eingeben!\n"); }while(!(*fpiplatz==1 || *fpiplatz==0)); } void erstellen(int fiplatz,int fianzahl,struct listeElement **fppstart){ int i; //Die Elemente werden vor das zuletzt eigegebene gesetzt if(fiplatz==1){ for(i=fianzahl;i>=1;i--){ struct listeElement *neuesElement = (pdata)malloc(sizeof(data)); if (neuesElement == NULL) { printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } if(i==1) neuesElement->pweiter=NULL; if(i!=fianzahl) neuesElement->pweiter=(*fppstart); (*fppstart)=neuesElement; } return; } //Die Elemente werden nach das zuletzt eigegebene gesetzt else if(fiplatz==0){ struct listeElement *temp = NULL; for(i=1;i<=fianzahl;i++){ struct listeElement *neuesElement = (pdata)malloc(sizeof(data)); if(i==1) (*fppstart)=neuesElement; if(neuesElement == NULL){ printf("Nicht genug Speicher fuer %d. Element vorhanden.",i); return; } if(i!=1){ temp->pweiter=neuesElement; } if(i==fianzahl){ neuesElement->pweiter=NULL; } temp=neuesElement; } } return; } void eingabe(int fiplatz,int fianzahl,struct listeElement **fppstart){ int i; struct listeElement *temp=(*fppstart); if(fiplatz==1){ for(i=1;i<=fianzahl;i++){ printf("Das %i. Element: ",i); scanf("%i", &((*fppstart)->izahl)); fflush(stdin); (*fppstart)=((*fppstart)->pweiter); } } else if(fiplatz==0){ for(i=1;i<=fianzahl;i++){ printf("Das %i. Element: ",i); scanf("%i", &((*fppstart)->izahl)); fflush(stdin); (*fppstart)=((*fppstart)->pweiter); } } (*fppstart)=temp; }
-
ich sags ja... nur trottel, könnt ihr alle kein englisch
-
_-- schrieb:
ich sags ja... nur trottel, könnt ihr alle kein englisch
mr. englisch höchstpersönlich? spiel dich hier nicht auf, denn wenn du streit suchst bist hier fehl am platz.
-
stacc89 schrieb:
mr. englisch höchstpersönlich?
eher weniger... war ein äußerst schlechter schüler...
stacc89 schrieb:
spiel dich hier nicht auf
scheiß auf dichstacc89 schrieb:
bist hier fehl am platz.
tja, was soll ich sagen es ist einfach eine katastrophe! wer bringt euch sowas bei, oder bist du dilettant? ich gehe auch nicht davon aus, dass du noch nicht die 5. klasse besucht hast und die sieben nötigen wörter im duden nicht gefunden hast! sich mit solchen leuten rumzuschlagen ist ein trauerspiel und verdient meine höchstachtung! meine befürchtung ist, dass die lehrer es teilweise schon aufgegeben haben - würde ich auch wenn ich einfach tippe, dass du eher noch einer der besseren in deiner klasse bist
ich denke es ist für uns alle besser wenn ich mir sowas einfach nicht mehr reinzieh.