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-Programmierung

    Aufgabe:
    Dynamische Erstellung einer einfach verketteten Liste, welche anschließend verwaltet werden soll.

    Compiler:
    MS-Compiler

    Bisheriger 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ückgabewert

    struct 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 überhaupt fneuesElement , 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 :S

    Heute 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 auf 😕 Bei 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 ===|
    

  • Mod

    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 dich

    stacc89 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.


Anmelden zum Antworten