@Remy реснички правильно, но что-то о своих звездочками предполагает, что вы имеете в виду что-то вроде этого в C:
int remove_first(node_t** head)
{
if (head == NULL || *head == NULL) return -1;
node_t* save = *head;
*head = save->next;
free(save);
return 0;
}
Мы передаем двойной указатель на функцию по причине. Если мы прошли один указатель, мы будем делать это:
int remove_first(node_t* head)
{
if (head == NULL) return -1;
node_t* save = head;
head = save->next;
free(save); // bad idea
return 0;
}
// before function call:
head->node->next->NULL
// during function call
head->node->next->NULL
head---^
// before return:
head->NULL next->NULL // (anyone can correct this line, but we can still free that node I believe)
head-------------^
// after return:
head->NULL next->NULL
Единый указатель просто создает копию указателя головы, а не изменяющего оригинал, который никогда не двигался.
С двойным указателем:
// before function call:
head->node->next
// during function call
head->node->next
head--^
// before return:
head->next
head--^
// after return:
head->next
С головой двойного указателя является адрес оригинальной головы, мы де-ссылка двойного указателя на доступ к исходной головке ponter, а не копия. Таким образом, мы можем направить исходный указатель.
Я не уверен, на каком языке вы бы использовали две звездочки. Вы имеете в виду * head = * head-> next? – synchronizer