2009-04-20 6 views
34

Por lo tanto, tienen algo de código, algo así como lo siguiente, para agregar una estructura a una lista de estructuras:¿Cómo modifico un puntero que se ha pasado a una función en 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 
} 

Estas estructuras se definen como sigue:

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

#define EMPTY_LIST NULL 

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

y luego en otro solicito hacer algo como lo siguiente:

BarList * l; 

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

sin embargo, después de esto, l sigue apuntando a EMPTY_LIST, no la versión modificada creada en el interior de barPush. ¿Tengo que pasar la lista como un puntero a un puntero si quiero modificarlo, o se necesita algún otro conjuro oscuro?

Respuesta

41

Tiene que pasar un puntero a un puntero si usted quiere hacer esto.

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

Entonces utilizar de esta manera:

BarList * l; 

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

Jonathan Leffler sugirió devolver la nueva cabeza de lista en los comentarios:

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

de uso es:

BarList * l; 

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

Gracias, pensé que este era el problema, pero esperaba que no lo fuera;) –

+3

Como alternativa, haga que la función devuelva el puntero al nuevo encabezado de la lista. BarList * barPush (lista BarList *, barra * barra) –

2

Sí, debe pasar un puntero al puntero. C pasa argumentos por valor, no por referencia.

6

Recuerde, en C, TODO se pasa por valor.

se pasa en un puntero a un puntero, como este

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

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

} 
2

Este es un p clásico roblem. Devuelva el nodo asignado o use un puntero de puntero. En C, debe pasar un puntero a una X a una función donde desea que se modifique su X. En este caso, dado que desea que se modifique un puntero, debe pasar un puntero a un puntero.

14

Respuesta genérica: Pase un puntero a la cosa que desea cambiar.

En este caso, sería un puntero al puntero que desea cambiar.

Cuestiones relacionadas