74 Stimmen

Wie ändere ich einen Zeiger, der an eine Funktion in C übergeben wurde?

Ich habe also einen Code, etwa wie den folgenden, um eine Struktur zu einer Liste von Strukturen 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 in einer anderen Datei mache ich etwas wie das Folgende:

BarList * l;

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

Danach zeigt l jedoch immer noch auf EMPTY_LIST und nicht auf die geänderte Version, die innerhalb von barPush erstellt wurde. Muss ich list als Zeiger auf einen Zeiger übergeben, wenn ich sie ändern will, oder ist eine andere dunkle Beschwörung erforderlich?

74voto

geofftnz Punkte 9606

Sie müssen einen Zeiger auf einen Zeiger übergeben, wenn Sie dies tun wollen.

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 verwenden Sie es so:

BarList * l;

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

Jonathan Leffler schlug in den Kommentaren vor, den neuen Leiter der Liste 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; 
}

Die Verwendung wird:

BarList * l;

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

26voto

aib Punkte 42913

Allgemeine Antwort: Übergeben Sie einen Zeiger auf die Sache, die Sie ändern möchten.

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

18voto

Anthony Punkte 7050

Denken Sie daran, dass in C ALLES als Wert übergeben wird.

Sie geben einen Zeiger auf einen Zeiger ein, etwa so

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

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

}

5voto

dirkgently Punkte 104289

Dies ist ein klassisches Problem. Entweder wird der zugewiesene Knoten zurückgegeben oder ein Zeiger auf den Zeiger verwendet. In C sollten Sie einen Zeiger auf ein X an eine Funktion übergeben, in der Ihr X geändert werden soll. Da in diesem Fall ein Zeiger geändert werden soll, sollten Sie einen Zeiger auf einen Zeiger übergeben.

3voto

Charles E. Grant Punkte 5391

Ja, Sie müssen einen Zeiger auf den Zeiger übergeben. C übergibt Argumente als Wert, nicht als Verweis.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X