#c #list
#c #Список
Вопрос:
Я пытаюсь добавить элементы в начало списка. По сути, то, что я пытаюсь здесь сделать, это:
-
Начните с нулевого списка;
-
Прочитайте число;
-
Вызов функции, в которой создается новый узел для хранения числа, а следующий указатель указывает на null;
-
Если список пуст, то этот новый узел является началом списка (и единственным элементом)
-
Если элементов больше, то этот новый узел указывает на начало списка и становится новым заголовком.
Моя функция делает то, что я хочу (по крайней мере, я вижу это в отладчике), но после ее возврата мой список пуст, а заголовок снова равен нулю.
struct node{
int data;
node *next;
};
void insert_front(node *list, int num){
node * newnode = new (node);
newnode->data = num;
newnode->next = nullptr;
if (list == nullptr)
list = newnode;
else{
newnode->next = list;
list = newnode;
}
}
int main()
{
int n;
node *head = nullptr;
cout << "Input numbers to store (0 finishes input): ";
cin >> n;
while (n != 0){
insert_front(head, n);
cin >> n;
}
return 0;
}
Также пробовал это, но он даже не компилируется:
void insert_front(node amp;lst, int num){
node *newnode = new node();
newnode->data=num;
newnode->next=lst;
lst=newnode;
}
Я намеренно избегал использования ООП, шаблонов, typedef и т. Д., Насколько это возможно, Чтобы получить «более чистый» код, чтобы я мог понять, как все работает.
Комментарии:
1. Вы передаете копию указателя на список. Изменение копии не изменяет исходную переменную. Передайте указатель по ссылке.
Ответ №1:
Вам нужна ссылка на переменную указателя: узел * amp; список
void insert_front(node* amp;lst, int num){
node *newnode = new node();
newnode->data=num;
newnode->next=lst;
lst=newnode;
}
Если вы не используете ссылку, вы будете изменять копию своего указателя «lst», поэтому список будет продолжать указывать на старый фронт после выхода из этой функции. Ссылочный параметр в c имеет префикс символа «amp;». В одном старом C (не в вашем случае) вместо этого вам понадобится указатель на указатель.
Комментарии:
1. Я НЕ знал, что это возможно: D Спасибо!
2. Объясните, почему это необходимо.
3. Действительно, по крайней мере, какой-то элемент, объясняющий, что пошло не так, был бы гораздо более ценным, чем приемлемое исправление.
4. Сделано @Гонки на орбите и giant_teapot
5. Завершены гонки на орбите и @giant_teapot 🙂
Ответ №2:
Вы передаете список по значению.
Смотрите Это для аналогии:
int x;
void modify_x_where_x_is_passed_by_reference( int amp; x_ref);
void modify_x_where_x_is_passed_by_a_pointer( int * x_ptr);
// Usage
modify_x_where_x_is_passed_by_reference( x );
modify_x_where_x_is_passed_by_a_pointer( amp;x ); // the address of x
// But when your variable is a pointer!
int * y;
void modify_y_where_y_is_passed_by_reference( int* amp; y_ref);
void modify_y_where_y_is_passed_by_a_pointer( int* * y_ptr);
// Usage
modify_y_where_y_is_passed_by_reference( y );
modify_y_where_y_is_passed_by_a_pointer( amp;y ); // the address of y
Комментарии:
1. Отличное объяснение и очень полезное. Спасибо!
Ответ №3:
Не передавайте по ссылке, поскольку вы не можете назначить ей.
node* insert_front(node* list, int val)
{
node* n = new node();
n->data = val;
n->next= list;
return n; // return the new head of the list
}
Затем при вставке:
while (n != 0){
head = insert_front(head, n); // head will always change every time you add to the front
cin >> n;
}
Или, в качестве альтернативы, вы можете также обновить свою функцию вставки list
, чтобы отразить новый заголовок, но вам придется передать указатель на сам указатель заголовка:
void insert_front(node** pList, int val)
{
node* n = new node();
n->data = val;
n->next= *pList;
*pList= n;
}
while (n != 0){
insert_front(amp;head, n); // head will always change every time you add to the front
cin >> n;
}
Комментарии:
1. Почему бы не передать указатель по ссылке? Вы можете назначить параметры, передаваемые по ссылке.
2. Вы можете пойти любым путем. Передача по указателю более явна для вызывающего абонента, что «это параметр ввода / вывода, и он может измениться», чем ссылка. Компилятор генерирует один и тот же код в любом случае.
3. Спасибо, это очень полезно 🙂