2009-04-20 12 views
34

Tak, mam kod, rodzaj jak poniżej, aby dodać struct do listy kodowanym:Jak zmodyfikować wskaźnik, który został przekazany do funkcji w C?

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 
} 

Struktury te są zdefiniowane w następujący sposób:

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

#define EMPTY_LIST NULL 

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

a następnie w kolejnym złożyć zrobić coś jak następuje:

BarList * l; 

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

jednak po tym, ja nadal wskazuje EMPTY_LIST nie zmodyfikowana wersja stworzona wewnątrz barPush. Czy muszę przekazać listę jako wskaźnik do wskaźnika, jeśli chcę go zmodyfikować, czy też jest wymagana inna ciemna inkantacja?

Odpowiedz

41

trzeba przejść na wskaźnik do wskaźnika, jeśli chcesz to zrobić.

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; 
} 

następnie używać go tak:

BarList * l; 

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

Jonathan Leffler zaproponował zwrócenie nowego szefa listy w komentarzach:

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; 
} 

Wykorzystanie staje:

BarList * l; 

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

Dzięki, doszedłem do wniosku, że to był problem, ale miałem nadzieję, że tak się nie stało;) –

+3

Alternatywnie, funkcja powinna zwrócić wskaźnik do nowej głowy listy. BarList * barPush (lista BarList *, Bar * bar) –

2

Tak, należy przekazać wskaźnik do wskaźnika. C przekazuje argumenty według wartości, a nie przez odniesienie.

6

Pamiętaj, że w C, WSZYSTKO jest przekazywane wartością.

przekazać w wskaźnik do wskaźnika, jak to

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

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

} 
2

To jest klasyczny p roblem. Zwróć przydzielony węzeł lub użyj wskaźnika wskaźnika. W C, powinieneś przekazać wskaźnik do X do funkcji, w której chcesz zmodyfikować X. W tym przypadku, ponieważ chcesz zmodyfikować wskaźnik, powinieneś przekazać wskaźnik do wskaźnika.

14

Ogólna odpowiedź: Prześlij wskaźnik do obiektu, który chcesz zmienić.

W tym przypadku byłby to wskaźnik do wskaźnika, który chcesz zmienić.

Powiązane problemy