2013-02-20 2 views
0

Я недавно пытался узнать C/C++. Я написал простую связанную программу списка, которая должна работать, и на самом деле это происходит, но только тогда, когда заголовок связанного списка (node* mother) является глобальной переменной и не используется в качестве параметра для функции (void new_node(int number)) - эта функция является конструктором (Я использую синтаксис C).C++ global vs локальная переменная как заголовок в связанном списке

Эта программа ниже работает отлично, но я не могу создать более одного связанного списка:

#include <iostream> 
#include <stdlib.h> 
#include <stdio.h> 

using namespace std; 


struct node { 
    node * next; 
    int number; 
}; 


node * mother = NULL; 

void new_node(int number) 
{ 
    node * newNode = (node*) malloc(sizeof(node)); 

    newNode -> next = NULL; 
    newNode -> number = number; 

    if (mother == NULL){ 
     mother = newNode; 
    } 
    else{ 
     node* temp = mother; 
     while(temp->next != NULL){ 
      temp = temp->next; 
     } 
     temp->next = newNode; 
    } 
} 

void destroy(){ 
    node* ntemp = mother; 
    mother = NULL; 
    node* t; 

    while(ntemp != NULL){ 
     t = ntemp->next; 
     free(ntemp); 
     ntemp = t; 
    } 
} 

void printAll(){ 
    node *tmp; 
    tmp = mother; 
    while (tmp != NULL){ 
     cout <<"value is : " << tmp->number <<endl; 
     tmp = tmp->next; 
    } 

} 

int main() 
{ 
    cout <<"size is " << sizeof(node*) <<endl; 

    new_node(5); 
    new_node(17); 
    new_node(-54); 
    new_node(3); 
    new_node(4); 
    new_node(-24); 
    new_node(10); 
    printAll(); 
    return 0; 
} 

И если я использую однако node* mother в качестве аргумента функционировать new_node, она не работает - это только печатает размер узла:

#include <iostream> 
#include <stdlib.h> 
#include <stdio.h> 

using namespace std; 


struct node { 
    node * next; 
    int number; 
}; 

void new_node(node* mother, int number){ 
    node * newNode = (node*) malloc(sizeof(node)); 

    newNode -> next = NULL; 
    newNode -> number = number; 

    if (mother == NULL){ 
     mother = newNode; 
    } 
    else{ 
     node* temp = mother; 
     while(temp->next != NULL){ 
      temp = temp->next; 
     } 
     temp->next = newNode; 
    } 
} 

void destroy(node * mother){ 
    node* ntemp = mother; 
    mother = NULL; 
    node* t; 

    while(ntemp != NULL){ 
     t = ntemp->next; 
     free(ntemp); 
     ntemp = t; 
    } 
} 

void printAll(node * mother){ 
    node *tmp; 
    tmp = mother; 
    while (tmp != NULL){ 
     cout <<"value is : " << tmp->number <<endl; 
     tmp = tmp->next; 
    } 

} 

int main() 
{ 
node * mother = NULL; 

    cout <<"size is " << sizeof(node*) <<endl; 

    new_node(mother, 5); 
    new_node(mother, 17); 
    new_node(mother, -54); 
    new_node(mother, 3); 
    new_node(mother, 4); 
    new_node(mother, -24); 
    new_node(mother, 10); 
    printAll(mother); 
    return 0; 
} 

ВЫХОДА ПЕРВОЙ ПРОГРАММЫ:

size is 8 
value is : 5 
value is : 17 
value is : -54 
value is : 3 
value is : 4 
value is : -24 
value is : 10 

ВЫВОД ВТОРОЙ ПРОГРАММЫ:

size is 8 

Вопрос в том, почему эта программа ведет себя так по-разному?

+2

Не кричите нам, пожалуйста. –

+0

Что показывает вам ваш отладчик? – StarPilot

+0

Спасибо, что ответили ребятами. Ты мне очень помог - я не хотел кричать - просто выражение моего разочарования - я обязательно сделаю это спокойно в следующий раз :). –

ответ

0

Попробуйте изменить г new_node к этому:

void new_node(node** mother, int number){ 
    node * newNode = (node*) malloc(sizeof(node)); 

    newNode -> next = NULL; 
    newNode -> number = number; 

    if (*mother == NULL){ 
     *mother = newNode; 
    } 
    else{ 
     node* temp = *mother; 
     while(temp->next != NULL){ 
      temp = temp->next; 
     } 
     temp->next = newNode; 
    } 
} 

и главный к этому:

int main() 
{ 
node * mother = NULL; 

    cout <<"size is " << sizeof(node*) <<endl; 

    new_node(&mother, 5); 
    new_node(&mother, 17); 
    new_node(&mother, -54); 
    new_node(&mother, 3); 
    new_node(&mother, 4); 
    new_node(&mother, -24); 
    new_node(&mother, 10); 
    printAll(mother); 
    return 0; 
} 

Вы должны передать указатель на указатель на узел в вашей new_node функции, потому что в противном случае только копия mother указателя изменится в new_node функции, в то время как mother в основном будут такими же.

0

Это потому, что когда вы устанавливаете mother в этой строке:

mother = newNode; 

в вашей new_node функции, она устанавливает локальную копию mother, а не переменной, которую вы прошли в

Вам нужно. используйте ссылку node * &mother или двойную стрелку node ** mother, чтобы иметь возможность изменить оригинал mother при его поступлении.

0

Дело в том, что внутри функции, называемой «new_node», вы работаете только с копией указателя. Таким образом, изменения не сохраняются после выхода функции. Чтобы изменить указатель вместо его копии внутри функции Вы должны использовать следующую декларацию вашей функции:

void new_node(node*& mother, int number)

Это единственное изменение, чтобы сделать вашу вторую программу работы.

0

Каждый раз, когда вы звоните new_node(), создается локальная копия mother, и любые изменения в ней теряются при выходе из функции. Вот почему ваш список никогда не создается.

Самое простое решение, чтобы просто изменить

void new_node(node* mother, int number) 

в

void new_node(node* &mother, int number) // pass-by-reference - Google it! 

, и вы получите результат, который вы хотите. Зачем? & в node* &mother сообщает компилятору, что вы хотите, чтобы функция использовала фактическую переменную mother, которую вы передаете, а не ее копию.

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