Почему для вставки в список требуется указатель на указатель - PullRequest
0 голосов
/ 06 июня 2018

Учебник описывает алгоритм вставки таким образом, мой вопрос, не может ли он быть реализован второй функцией, показанной ниже, которая не включает указатель на указатель, вместо этого работает с * l и l.

void insert (list **l, int d)
{
    list *p; 

    p = malloc(sizeof(list)); 
    p.data = x;
    p.next = *l; 
    *l = p;
}


void insert1 (list *l, int d){
    list *p;
    p = malloc(sizeof(list));
    p.data = x;
    p.next = l;
    l = p; 
}

Ответы [ 3 ]

0 голосов
/ 06 июня 2018

Все передается по значению в C. Это включает в себя ваш указатель.Таким образом, когда вы говорите l = p; в конце вашей функции, это не влияет на вызывающего insert1().Вы просто изменяете локальную переменную insert1() (которая содержит указатель).

Однако, когда вы говорите *l = p; в конце insert(), вы записываете указатель в памятьместо, которое контролируется абонентом.Вызывающая сторона обычно делает что-то похожее на это:

list* myList = ...;
insert(&myList, ...);

При этом *l = p; напрямую изменяет значение myList в вызывающей стороне, позволяя вызывающей стороне фактически видеть эффект.

0 голосов
/ 06 июня 2018

Почему для вставки в список требуется указатель на указатель? это потому, что если вы сделаете это изменение в *l, это повлияет и на вызов функции, и это то, что мы намерены, если вы хотите связать узлы,Этот *l = p; в приведенном ниже коде изменит узел head в функции calling, вероятно main().

void insert (list **l, int x) { /*. .. */ }

Если вы передадите только указатель, как вы сделали в секундукод *l не изменяется в вызывающей функции.Этот l = p; не меняет head узел в вызывающей функции.

0 голосов
/ 06 июня 2018

Нет, вы не можете.Проблема с insert1 заключается в следующей строке:

l = p;

Это установит значение l в p, но l является только локальной функцией-переменной, содержащей значениеуказатель на список.Изменение l здесь не будет иметь никакого эффекта вне функции.Поэтому, если у меня есть код вроде:

list *myList = /* ... */;
insert1(myList, 0);

Указатель myList здесь не будет изменен.С другой стороны, с кодом:

list *myList = /* ... */;
insert(&myList, 0);

Указатель myList будет обновлен, чтобы указывать на вновь вставленное значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...