Einfach verkette Liste
-
Ich versuche eine einfach verkettete Liste zu programmieren. Ich lese dazu von der Konsole die Anzahl der zu speichernden Elemente ein und reserviere entsprechend Speicher. Dann versuche ich die Elemente zu verketten. Es klappt aber leider nicht wie gewollt. Kann mir jemand sagen wo mein Fehler liegt?
#include <stdio.h> #include <stdlib.h> #include <string.h> struct produkt { char name [20]; int preis; //Aufgabe a) struct produkt * next; } * pointer; struct produkt * start_pointer = NULL; void ausgabe (struct produkt *); int main(int argc, char** argv) { int anzahl; printf("\nWieviele Produkte möchten Sie einlesen: "); scanf("%d", &anzahl); pointer = (struct produkt *) malloc (anzahl * sizeof (struct produkt)); int i; for(i = 0; i < anzahl; i++) { printf ("\n\nGib den Produktnamen ein: "); getchar(); gets (pointer -> name); printf ("\nGib den Preis in Euro ein: "); scanf ("%d", &(pointer->preis)); pointer->next = start_pointer; start_pointer = pointer+i; printf("\nName: %s", pointer->name); printf("\nPreis: %d", pointer->preis); printf("\nNext: %p", pointer->next); } ausgabe(pointer); free (pointer); return 0; } void ausgabe (struct produkt * pointer) { while(pointer != NULL) { printf ("\nDas Produkt %s hat den Preis %d", pointer->name, pointer->preis); pointer = pointer->next; } }
-
Also, scheinbar muss man für jedes neue Element den Speicher im Heap explizit erzeugen. anzahl * sizeof (struct produkt) erzeugt nur ein produkt, dass anzahl mal so groß ist wie über die Konsole eingelesen.
Gibt es vll. andere Wege das Problem zu lösen? pointer++ bzw. pointer+i oder so was?Momentan hab ich diese Lösung...
for(i = 0; i < anzahl; i++) { pointer = (struct produkt *) malloc (sizeof (struct produkt)); printf ("\n\nGib den Produktnamen ein: "); ... ...}
-
Huiuiui...
Was genau funktioniert denn nicht?
Ich hab irgendwie das Gefühl, dass du bei deinen Pointer-Zuweisungen nicht mehr weißt, wo du stehst. Also wo genau ist pointer grad, und wo start_pointer. Und vor allem, was sind das?
-
Du fragst die Endekennung deiner Liste ab, setzt sie aber nicht korrekt.
typedef struct _Produkt { char name [20]; int preis; //Aufgabe a) struct _Produkt * next; } Produkt; void ausgabe (Produkt *); main() { int anzahl; Produkt *liste,*pointer; printf("\nWieviele Produkte möchten Sie einlesen: "); scanf("%d", &anzahl); pointer = liste = calloc (anzahl, sizeof *liste); while( anzahl-- ) { printf ("\n\nGib den Produktnamen ein: "); getchar(); gets (pointer -> name); printf ("\nGib den Preis in Euro ein: "); scanf ("%d", &(pointer->preis)); printf("\nName: %s", pointer->name); printf("\nPreis: %d", pointer->preis); printf("\nNext: %p", anzahl?pointer++->next=pointer+1:0 ); } ausgabe(liste); free (liste); return 0; } void ausgabe (Produkt *pointer) { while( pointer ) { printf ("\nDas Produkt %s hat den Preis %d", pointer->name, pointer->preis); pointer = pointer->next; } }
-
Wutz schrieb:
printf("\nNext: %p", anzahl?pointer++->next=pointer+1:0 );
Das ist schlecht. ANSI C garantiert Dir nicht, wann genau der Postinkrement ausgeführt wird. Du evaluierst in einem Statement die Variable pointer zweimal und bei einem hast Du einen Postinkrement. Der kann nun nach aber auch vor der zweiten Evaluation ausgeführt werden. Besser ist also:
printf("\nNext: %p", anzahl?pointer->next=pointer+1:0 ); pointer++;
[/quote]
Grundsätzlich ist das aber ein schlechtes Beispiel für eine verkette Liste, weil ja schon ein Array vorhanden ist. Zur Übung sollten also die einzelnen Elemente der Liste auch einzeln erzeugt werden:
TYPE *rootPointer = new TYPE; TYPE *cursor = rootPointer; while( irgendwas ) { ... // hier die Struktur, auf die cursor zeigt, füllen cursor->next = new TYPE; cursor = cursor->next; }
So ähnlich kann das gemacht werden. Und zur Übung macht Ihr das Freigeben der Liste selber.
Viel Spaß.
mfg Martin
-
Soso. Die Vorrangregeln sind dir aber schon bekannt?
Wenn man vorher die Gesamtgröße eines benötigten Speicherbereiches kennt, grenzt es schon an Masochismus statt eines malloc mehrere zu verwenden, zumal auch das free viel einfacher und weniger fehlerbehaftet verwendet werden kann.
new ist kein ANSI C.
-
Wutz schrieb:
Soso. Die Vorrangregeln sind dir aber schon bekannt?
Natürlich. Nur beachte folgendes:
int i=0; int array[10]; array[i++] = i;
array[0] darf danach entweder 0 oder 1 enthalten.
Such mal die Beschreibung vom Postincrement im Ansi C Standard.
Wutz schrieb:
Wenn man vorher die Gesamtgröße eines benötigten Speicherbereiches kennt, grenzt es schon an Masochismus statt eines malloc mehrere zu verwenden, zumal auch das free viel einfacher und weniger fehlerbehaftet verwendet werden kann.
Richtig, aber der Threadstarter wollte eine Linkliste üben. Wenn ich schon vorher weiß, wieviele Elemente meine Liste enthält, macht auch die Linkliste keinen Sinn. Es sollte also ein praxisrelevantes Beispiel geübt werden.
Wutz schrieb:
new ist kein ANSI C.
Na gut. dann sollte der Threadstarter halt malloc stattdessen benutzen.
mfg Martin