C Frage zu einfachen Listen und Pointerarithmetik

dragonabllz

Ensign
Registriert
Mai 2011
Beiträge
254
Zuerst mal den Code:
Code:
struct element {
	struct element *next;
	int x;
};

void append(struct element *list, int nr) {
	struct element *tmp = list;
	struct element *new;

	if ((new = (struct element *) malloc(sizeof(*new))) == NULL) {
		printf("Malloc failed!");
		exit(0);
	}

	new->x = nr;
	new->next = NULL;

	if (tmp != NULL) {
		while (tmp->next != NULL) {
			tmp = tmp->next;
		}
		tmp->next = new;
	} else {
		tmp = new;
	}
}

void printliste(struct element *l) {
	struct element *liste;
	liste = l;
	printf("%d\n", liste->x);
	while (liste->next != NULL) {
		liste = liste->next;
		printf("%d\n", liste->x);
	}
}

int main(void) {
	struct element* head = NULL;

	append(head, 5);
	append(head, 6);
	append(head, 7);

	printliste(head);

	return 0;
}

Ich bin noch C Anfänger und befasse mich momentan mit Pointern und Struct.
Wie man sieht ist in der Methode "append" eine Abfrage "if(tmp != NULL)", was darauf schließt, dass wenn ein leerer Pointer auf einem Struct (siehe in der main 'head') übergeben wird, die Zeile 'tmp=new' ausgeführt wird.
Jedoch wenn ich die Main-Methode ausführe wird nix ausgegeben.
Wie kann man sich das erklären? Soweit ich das verstanden habe, überge ich mit "(append, head, 5)" den Inhalt des Pointer Head, was halt auf NULL zeigt, also die Adresse wo NULL steht übergebe ich ?
Ich kann mir das deshalb nicht erklären warum das nicht funktionieren will...
 
Soweit richtig, der Denkfehler liegt nur darin, dass head nie verändert wird. Du übergibst zwar head, aber eben weil der Wert von head übergeben wird und nicht eine Referenz auf head, bleibt er über die gesamten Funktionsaufrufe hinweg gleich.

Was kann man dagegen tun?
- Einen Pointer auf head an append übergeben, also als struct list**. Dann dessen Inhalt (effektiv also den Wert von head) in der append-Methode verändern.
- Den neuen Pointer in append zurückgeben und explizit zurückschreiben.
 
VikingGe schrieb:
Soweit richtig, der Denkfehler liegt nur darin, dass head nie verändert wird. Du übergibst zwar head, aber eben weil der Wert von head übergeben wird und nicht eine Referenz auf head, bleibt er über die gesamten Funktionsaufrufe hinweg gleich.

Was kann man dagegen tun?
- Einen Pointer auf head an append übergeben, also als struct list**. Dann dessen Inhalt (effektiv also den Wert von head) in der append-Methode verändern.
- Den neuen Pointer in append zurückgeben und explizit zurückschreiben.
Ok erstmal Danke. Jedoch verstehe ich das noch immer nicht ganz.
Gerade weil ich ja den Wert von head übergebe, müsste es ja klappen. Wenn wir uns die Funktionsdeklaration von append anschauen, sehen wir das diese ein Pointer auf einer Struktur erwartet als Parameter. Und Head ist ja genau dies: Ein Pointer auf einer Struktur.
Und indem wir einfach head übergeben, übergeben wir ja die Adresse einer Struktur, welcher in Head gespeichert ist und nicht den Inhalt der Adresse.

Das ist ja bei primitiven Datentypen ja auch so. Wenn ich z.b. sowas habe wie:
int* a = &x;
int* b = &y;

, dann habe ich die Adresse von x im Pointer a gespeichert. Wenn ich nun eien Funktion habe, z.b. swap(int* x, int* y), so rufe ich diese ja so auf: swap(a,b), sofern a und b Pointer sind.
 
dragonabllz schrieb:
Und indem wir einfach head übergeben, übergeben wir ja die Adresse einer Struktur, welcher in Head gespeichert ist und nicht den Inhalt der Adresse.
Ganz genau. head ist wie du selbst ja sagst der Pointer auf eine Struktur. Allerdings ist das nur der Datentyp. Die Struktur, oder wie du es sagst, den Inhalt, jedoch gibt es im Speicher noch nicht, der Pointer ist NULL.


Kannst du auch ganz einfach nachvollziehen, folgende Zeilen sollten schon in der main Funktion abstürzen:
Code:
struct element * head = NULL;    head->next=NULL;

Die primitivste Lösung:
Code:
    struct element head;

    head.next=NULL;
    head.x=42;
    append(&head, 5);
    append(&head, 6);
    append(&head, 7);

    printliste(&head);
Und je nachdem ob man head dazuhaben möchste, die Printfunktion anpassen.


Edit: Logischerweise geht es natürlich auch umgekehrt:
Code:
    struct element * head;
    head = (struct element *) calloc(1,sizeof(struct element));


    append(head, 5);
    append(head, 6);
    append(head, 7);

    printliste(head);
 
Zuletzt bearbeitet:
Zurück
Oben