Frage

Ich habe also einen Code, der wie folgt ist, um einer Liste von Strukturen eine Struktur hinzuzufügen:

void barPush(BarList * list,Bar * bar)
{
    // if there is no move to add, then we are done
    if (bar == NULL) return;//EMPTY_LIST;

    // allocate space for the new node
    BarList * newNode = malloc(sizeof(BarList));

    // assign the right values
    newNode->val = bar;
    newNode->nextBar = list;

    // and set list to be equal to the new head of the list
    list = newNode; // This line works, but list only changes inside of this function
}

Diese Strukturen sind wie folgt definiert:

typedef struct Bar
{
    // this isn't too important
} Bar;

#define EMPTY_LIST NULL

typedef struct BarList
{
    Bar * val;
    struct  BarList * nextBar;
} BarList;

Und dann mache ich in einer anderen Datei so etwas wie Folgendes:

BarList * l;

l = EMPTY_LIST;
barPush(l,&b1); // b1 and b2 are just Bar's
barPush(l,&b2);

Danach verweist L jedoch immer noch auf leere_list, nicht auf die modifizierte Version, die in Barpush erstellt wurde. Muss ich die Liste als Zeiger an einen Zeiger weitergeben, wenn ich ihn ändern möchte, oder ist eine andere dunkle Beschwörung erforderlich?

War es hilfreich?

Lösung

Sie müssen einen Zeiger an einen Zeiger weitergeben, wenn Sie dies tun möchten.

void barPush(BarList ** list,Bar * bar)
{
    if (list == NULL) return; // need to pass in the pointer to your pointer to your list.

    // if there is no move to add, then we are done
    if (bar == NULL) return;

    // allocate space for the new node
    BarList * newNode = malloc(sizeof(BarList));

    // assign the right values
    newNode->val = bar;
    newNode->nextBar = *list;

    // and set the contents of the pointer to the pointer to the head of the list 
    // (ie: the pointer the the head of the list) to the new node.
    *list = newNode; 
}

Dann benutze es so:

BarList * l;

l = EMPTY_LIST;
barPush(&l,&b1); // b1 and b2 are just Bar's
barPush(&l,&b2);

Jonathan Leffler schlug vor, den neuen Kopf der Liste in den Kommentaren zurückzugeben:

BarList *barPush(BarList *list,Bar *bar)
{
    // if there is no move to add, then we are done - return unmodified list.
    if (bar == NULL) return list;  

    // allocate space for the new node
    BarList * newNode = malloc(sizeof(BarList));

    // assign the right values
    newNode->val = bar;
    newNode->nextBar = list;

    // return the new head of the list.
    return newNode; 
}

Verwendung wird:

BarList * l;

l = EMPTY_LIST;
l = barPush(l,&b1); // b1 and b2 are just Bar's
l = barPush(l,&b2);

Andere Tipps

Generische Antwort: Geben Sie einen Zeiger an das, was Sie ändern möchten.

In diesem Fall wäre es ein Zeiger auf den Zeiger, den Sie ändern möchten.

Denken Sie daran, in C wird alles von Wert übergeben.

Sie übergeben einen Zeiger an einen Zeiger wie diesen

int myFunction(int** param1, int** param2) {

// now I can change the ACTUAL pointer - kind of like passing a pointer by reference 

}

Ja, Sie müssen einen Zeiger an den Zeiger weitergeben. C übergibt Argumente nach Wert, nicht durch Bezugnahme.

Dies ist ein klassisches Problem. Geben Sie entweder den zugewiesenen Knoten zurück oder verwenden Sie einen Zeiger des Zeigers. In C sollten Sie einen Zeiger auf ein X an eine Funktion übergeben, in der Ihr X geändert werden soll. In diesem Fall sollten Sie einen Zeiger an einen Zeiger weitergeben, da ein Zeiger geändert werden soll.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top