2016-10-04 2 views
2

Я пытаюсь добавить элементы в начало списка. В основном, я пытаюсь сделать здесь:C++ Добавить элементы в список со всеми возможными способами

  • Начните с нулевого списка;

  • Считать номер;

  • Функция вызова, в которой создается новый узел для хранения номера, а следующий указатель указывает на нуль;

  • Если список пуст, то этот новый узел в начале списка (и единственного элемент)

  • Если есть несколько элементов, то эти новые узловые точек к главе списка и становится новый руководитель.

Моя функция делает то, что я хочу (по крайней мере, я могу видеть, что в отладчике), но после того, как он возвращает мой список пуст, и голова нуль снова.

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 &lst, int num){ 
    node *newnode = new node(); 
    newnode->data=num; 
    newnode->next=lst; 
    lst=newnode; 
} 

я намеренно избегал использовать ООП, шаблоны, ЬурейиЕ и т.д. как можно больше, чтобы получить «чистую» коду, так что я может понять, как все работает.

+0

Вы передаете копию указателя в списке. Изменение копии не изменяет исходную переменную. Передайте указатель по ссылке. –

ответ

2

Вам нужна ссылка на указатель varibable: узел * & список

void insert_front(node* &lst, int num){ 
    node *newnode = new node(); 
    newnode->data=num; 
    newnode->next=lst; 
    lst=newnode; 
} 

Если вы не используете ссылку вы будете изменяющей копию «LST» указатель, так что список будет продолжайте указывать на старый фронт после выхода из этой функции. Параметр ссылки в C++ имеет префикс «&». В одиночном старом C (не в вашем случае) вам понадобится указатель на указатель.

+0

Я НЕ знал, что это возможно: D Спасибо! –

+0

Объясните _why_ это необходимо. –

+0

Действительно, хотя бы какой-то элемент, объясняющий * что * пошло не так, был бы намного более ценным, чем проходимое исправление. –

0

Не передавайте по ссылке, так как вы не можете назначить ему.

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(&head, n); // head will always change every time you add to the front 
    cin >> n; 
} 
+0

Почему бы не передать указатель по ссылке? Вы можете назначить параметры, переданные по ссылке. –

+0

Вы можете пойти в любом случае. Передача указателем более явна для вызывающего, что «это параметр ввода/вывода, и он может меняться», чем ссылка. Компилятор генерирует один и тот же код в любом случае. – selbie

+0

Спасибо, это очень полезно :) –

0

Вы передаете список по значению.

Смотреть это для аналогии:

int x; 
void modify_x_where_x_is_passed_by_reference(int & 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(&x); // the address of x 

// But when your variable is a pointer! 
int * y; 
void modify_y_where_y_is_passed_by_reference(int* & 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(&y); // the address of y 
+0

Отличное объяснение и очень полезно. Спасибо! –

Смежные вопросы