verkettete Liste
-
Hey Leute,
ich hab kleines Problem mit meinem Programm.
Ich möchte eine einfach verkettete Liste erstellen.
Das Erstellen hat soweit auch geklappt, wenn ich die Liste jetzt jedoch ausgeben möchte klappt es nicht.
Ich wollte zunächst nur die "Nutzdaten" aus der ersten Struktur, wo mein Head-Zeiger drauf zeigt ausgeben.
Ich bekomme jedoch immer das Falsche heraus.Ich habe es dann mit Speicheradresse ausgeben versucht.
Am Anfang ist noch alles richtig, sobald ich aber aus der Funktion "erstellen" herausgehe und in "ausgeben" rein, verändert sich die Adresse.
Wenn es vorher bsp.: 1000 war, gibt er mir dann die Adresse 1004 aus. Und da steht natürlich irgendwas drin.Ich hoffe mir kann dabei einer helfen.
PS.: Bin Anfänger also beschimpft mich ruhig
Quellcode ist im Anhang.
Vielen Dank im voraus.
#include <stdlib.h> #include <stdio.h> typedef struct liste { int nutzdaten; struct liste *next; }liste; void liste_erstellen(liste *phead,liste *ptail); void liste_ausgeben(liste *phead); int main(void) { liste phead, ptail; int ieingabe; do{ system("cls"); printf("Bitte waehlen Sie aus: \n"); printf("1 Liste erstellen\n"); printf("2 Element hinzufuegen\n"); printf("3 Element suchen(Rueckgabe ist Position)\n"); printf("4 Anzahl der Elemente\n"); printf("5 Alle Elemente ausgeben\n"); printf("6 komplette Liste loeschen\n"); printf("7 Element entfernen\n"); printf("0 Programm beenden\n"); printf("\n\ngewaehlte Zahl: "); scanf("%i", &ieingabe); switch (ieingabe){ case 1: system("cls"); printf("gewaehlte Zahl: %i\n\n", ieingabe); liste_erstellen(&phead,&ptail); system("pause"); break; case 9: //Test Case system("cls"); printf("gewaehlte Zahl: %i\n\n", ieingabe); liste_ausgeben(&phead); system("PAUSE"); break; case 0: break; default: break; } }while(ieingabe!=0); return 0; } void liste_erstellen(liste *phead,liste *ptail){ liste *neuesElement, *pnext=NULL; int ianzahl, ieingabe; printf("Wie viele Nutzdaten wollen Sie eingeben? "); scanf("%i", &ianzahl); for(int i=0; i<ianzahl; i++){ neuesElement=(liste*)malloc(sizeof(liste)); if(i==0){ phead = neuesElement; } else{ pnext->next = neuesElement; } printf("Geben Sie die zu speichernden Nutzdaten ein: "); scanf("%i", &ieingabe); neuesElement->nutzdaten = ieingabe; neuesElement->next = ptail; pnext = neuesElement; } } void liste_ausgeben(liste *phead){ printf("%i\n", &phead); printf("%i\n", phead->nutzdaten); }
-
#include <stdlib.h> #include <stdio.h> typedef struct liste { // Wozu hier dem struct den Namen "struct liste" geben, wenn du doch sowieso sofort ein typedef machst? int nutzdaten; struct liste *next; } liste; // doofer Name, dies ist doch nur ein Element einer Liste, keine Liste void liste_erstellen(liste *phead,liste *ptail); // Etwas komische Aufteilung der Funktionalität, aber spielen wir mal mit void liste_ausgeben(liste *phead); // Besser wären Funktionen mit klareren Aufgaben, wie Element hinzufügen, Elemente löschen, nächstes Element zurückgeben, usw. // Daraus kann man dann komplexere Funktionen zusammensetzen int main(void) { // Wenigstens mal ein Anfänger, der seine Liste nicht global macht. Juhu! liste phead, ptail; // Lol, ungarische Notation. Und dann auch noch falsch // Sollten phead und ptail nicht Pointer sein? int ieingabe; do{ system("cls"); printf("Bitte waehlen Sie aus: \n"); // Warum eine Monsterfunktion wie printf, wenn's hier doch ein puts täte? printf("1 Liste erstellen\n"); printf("2 Element hinzufuegen\n"); printf("3 Element suchen(Rueckgabe ist Position)\n"); printf("4 Anzahl der Elemente\n"); printf("5 Alle Elemente ausgeben\n"); printf("6 komplette Liste loeschen\n"); printf("7 Element entfernen\n"); printf("0 Programm beenden\n"); printf("\n\ngewaehlte Zahl: "); scanf("%i", &ieingabe); switch (ieingabe){ case 1: system("cls"); printf("gewaehlte Zahl: %i\n\n", ieingabe); liste_erstellen(&phead,&ptail); system("pause"); break; case 9: //Test Case system("cls"); printf("gewaehlte Zahl: %i\n\n", ieingabe); liste_ausgeben(&phead); system("PAUSE"); break; case 0: break; default: // Rück mal konsistenter ein! Warum hat default hier eine andere tiefe als die anderen cases? break; } }while(ieingabe!=0); return 0; } void liste_erstellen(liste *phead,liste *ptail){ liste *neuesElement, *pnext=NULL; int ianzahl, ieingabe; printf("Wie viele Nutzdaten wollen Sie eingeben? "); scanf("%i", &ianzahl); for(int i=0; i<ianzahl; i++){ // Du nutzt offensichtlich C99, warum definierst du dann nicht alle Variablen erst // dort wo du sie wirklich brauchst? Das wäre viel übersichtlicher. neuesElement=(liste*)malloc(sizeof(liste)); // Warum hier ein Cast? Unnötig. Verschleiert mögliche Fehler! if(i==0){ phead = neuesElement; // Fehler: Hier änderst du deine lokale Variable. Die Änderung wird niemals nach außen getragen. } else{ pnext->next = neuesElement; } printf("Geben Sie die zu speichernden Nutzdaten ein: "); scanf("%i", &ieingabe); neuesElement->nutzdaten = ieingabe; neuesElement->next = ptail; // Sollte ptail nicht irgendwie auch geändert werden? pnext = neuesElement; } } void liste_ausgeben(liste *phead){ printf("%i\n", &phead); // Formatspezifizierer für Pointer ist %p. Du gibst die Adresse deiner lokalen Variablen aus. printf("%i\n", phead->nutzdaten); }
Es sind hier schon viel schlimmere erste Versuche einer verketteten Liste stolz vorgezeigt worden. Insgesamt jedoch trotzdem zu viele Fehler und schlechte Designentscheidungen, als das man noch versuchen sollte, dies noch zu retten. Gnadenschuss. Dann nochmal gründlich lernen, wie das mit Funktionen, Funktionsparametern und Pointern als Funktionsparametern geht. Dann nochmal versuchen, dieses Mal den Tipp befolgen, der Liste ein sauberes Interface mit Funktionen mit klar abgegrenzten Aufgabenstellungen zu verpassen. Diese Funktionen lassen sich dann auch viel einfacher auf Fehler überprüfen. Außerdem vorher genauer Gedanken machen, was für Elemente deine Liste benötigt und wozu sie gut sind und was dies für deine Funktionen bedeutet. Dein ptail ist in deinem Programm irgendwie dabei, ohne dass du selber so recht weißt, wozu und was du überhaupt damit machen möchtest. Außerdem solltest du vorzugsweise den Kernelementen der Liste noch ein eigenes struct spendieren, anstatt eine lose Ansammlung von Variablen in einer Funktion zu haben.