2016-04-05 26 views
0

Ich habe einige Einträge gefunden, um Zeiger als Referenz zu übergeben, habe sie aber nicht wirklich verstanden.C-Zeiger als Referenz übergeben?

Ich habe diese Funktion geschrieben, um einen Knoten in eine verkettete Liste einzufügen. Es scheint innerhalb der Funktion zu arbeiten, aber die Änderungen des linkedList Zeigers beeinflussen den Zeiger nicht zurück in der Hauptfunktion. Gibt es eine einfache Lösung? Im Klassenraumbeispiel wird der Zeiger linkedList global deklariert, aber ich dachte, es wäre besser, ihn weiterzugeben, damit ich mehr als eine verknüpfte Liste erstellen kann.

void insert(node* linkedList, int value) 
{ 
    node* newNode = malloc(sizeof(node)); 

    if (newNode == NULL) 
    { 
     // failed to make node 
     printf("Failed to insert new node!\n"); 
     return; 
    } 

    newNode->n = value; 

    printf("\n"); 
    printf("Before insert: \n"); 
    printf("\n"); 

    printf("linkedList ptr : %p\n", linkedList); 
    printf("linkedList->n : %i\n", linkedList->n); 
    printf("LinkedList->next : %p\n", linkedList->next); 

    printf("\n"); 
    printf("newNode ptr : %p\n", newNode); 
    printf("newNode->n : %i\n", newNode->n); 
    printf("newNode->next : %p\n", newNode->next); 

    newNode->next = linkedList; 
    linkedList = newNode; 

    printf("\n"); 
    printf("After insert: \n"); 
    printf("\n"); 

    printf("linkedList ptr : %p\n", linkedList); 
    printf("linkedList->n : %i\n", linkedList->n); 
    printf("LinkedList->next : %p\n", linkedList->next); 

    printf("\n"); 
    printf("newNode ptr : %p\n", newNode); 
    printf("newNode->n : %i\n", newNode->n); 
    printf("newNode->next : %p\n", newNode->next); 
} 
+1

Sicher gibt es eine einfache Lösung - loswerden 'void einfügen' und den Kopf zurück. –

+1

Oder verwenden Sie einen Doppelzeiger und aktualisieren Sie den Wert mithilfe der Referenz. – Haris

+0

Ich wollte das auch vorschlagen. Habe gerade die neue verknüpfte Liste zurückgegeben.Verwenden Sie so: 'list = einfügen (Liste, Nummer)' – nielsbot

Antwort

1

Ich denke, eine einfache Lösung wäre, um Ihre Funktion zu ändern, um die neue Liste Kopf zurück:

Node * insert(struct Node * list, int value) 
{ 
    ... 
} 

Verwendung wie folgt aus:

myList = insert(myList, someNumber)


Es ist schwer um den gewünschten Anwendungsfall ohne Bilder zu erklären. Sie möchten einen Zeiger auf Ihren Listenkopfzeiger an insert() übergeben. Innerhalb insert() können Sie dann ändern, worauf dieser Zeigerzeiger zeigt (um es zu dereferenzieren), um Ihren Listenkopf zu ändern.

Erklären Sie Ihre Funktion wie folgt aus:

void insert(struct Node ** ioList, int value) { ... } 

Hier ioList ist vom Typ Node **, die einen Zeiger auf einen Zeiger auf eine Node ist. (Eine Daumenregel: lesen Typen von rechts nach links)

Nennen Sie es wie folgt aus:

struct Node * myList = /*create list here*/ ; 
insert(&myList, /*some number*/); 

Der & Operator erzeugt einen Zeiger auf das Argument ist. Also bekommen wir einen Zeiger auf myList. (Was ist ein Zeiger auf eine Node)

Jetzt haben wir einen Zeiger, der auf myList zeigt.

Innen insert, zuweisen *ioList zu verändern, was ioList Punkte (myList):

// make myList point to the new list head: 
*ioList = /*new list head*/ 
+0

Ich merke, dass ich das Problem lösen könnte, indem ich den Zeiger zurückgebe, aber diese Lösung scheint eleganter. Ich fühlte mich, als würde ich nur den Dreh raus bekommen, aber ich denke, ich muss ein bisschen arbeiten, um meinen Kopf um Zeiger auf Zeiger zu bekommen ... –

+0

In Ihrem Code, wo Sie insert() aufrufen, werden Sie den Wert von ändern Ihr Listenzeiger ... Es ist schwieriger zu verwalten und Fehler im Code zu finden, wo dies geschieht. Ich würde persönlich die erste Option verwenden, um den neuen Listenkopf zurückzugeben. – nielsbot

0

Pointers Punkt an eine Stelle im Speicher. Ihre Funktion erstellt einen neuen Speicherort und weist ihn einem Zeiger zu, der als Wert übergeben wurde. Ich nehme an, Sie versuchen, einen neuen Knoten zu Ihrer bestehenden verknüpften Liste hinzuzufügen.

Ihre Funktion funktioniert leider nicht so, da Sie Ihrer verknüpften Liste jedes Mal eine neue Adresse zuweisen.

Ich mag die Verwendung von Sparse-Arrays. Wenn Sie die maximale Größe Ihrer Liste kennen, sind sie einfacher zu verwenden als ein zusammenhängender Speicherplatz, der Strukturen speichert, die später erneut zugewiesen werden müssen.

void insert(struct node* list[], int *currentIndex, int value) 
{ 
    struct node * newNode; 

    newNode = malloc(sizeof(node)); 
    list[*currentIndex++] = newNode; 

    .... 
} 
+0

Ich untersuche verknüpfte Listen als Teil einer Programmieraufgabe in CS50. Der Grund für die Verwendung von verketteten Listen scheint zu sein, dass man die Größe der Liste vorher nicht kennen muss. Man mallocs nur einen neuen Knoten, wie es der Liste hinzugefügt wird. Der Knoten im Beispiel enthält nur eine Ganzzahl und einen Zeiger auf den nächsten Knoten. –

Verwandte Themen