Как изменить указатель, который был передан в функцию в C?

StackOverflow https://stackoverflow.com/questions/766893

  •  12-09-2019
  •  | 
  •  

Вопрос

Итак, у меня есть какой -то код, вроде следующего, чтобы добавить структуру в список структур:

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
}

Эти структуры определяются следующим образом:

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

#define EMPTY_LIST NULL

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

А потом в другом файле я делаю что -то вроде следующего:

BarList * l;

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

Однако после этого L по -прежнему указывает на ementle_list, а не модифицированную версию, созданную внутри Barpush. Должен ли я пройти список в качестве указателя на указатель, если я хочу его изменить, или требуется какое -то другое мрачное заклинание?

Это было полезно?

Решение

Вам нужно передать указатель указатель, если вы хотите это сделать.

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

Затем используйте это так:

BarList * l;

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

Джонатан Леффлер предложил вернуть новую главу списка в комментариях:

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

Использование становится:

BarList * l;

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

Другие советы

Общий ответ: передайте указатель на то, что вы хотите изменить.

В этом случае это будет указатель на указатель, который вы хотите изменить.

Помните, в C все передается по цене.

Вы передаете указатель на указатель, как это

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

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

}

Да, вы должны передать указатель на указатель. C проходит аргументы по значению, а не по ссылке.

Это классическая проблема. Либо верните выделенный узел, либо используйте указатель указателя. В C вы должны передать указатель на x к функции, в которой вы хотите, чтобы ваш x был изменен. В этом случае, поскольку вы хотите, чтобы указатель был изменен, вы должны передать указатель на указатель.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top