2017-10-20 41 views
1

J'ai deux façons d'insérer un noeud depuis le début. Le premier fonctionne tandis que le second ne fonctionne pas. Peux-tu m'expliquer pourquoi?Liste liée: Insertion depuis le début

(La liste comporte déjà des éléments et la tête est le nœud de la tête de cette liste)

Et j'ai la tête initialisé comme ce

list *head = new list; 

void push(list **head, int info) 
    { 
    list *node=new list; 
    node->data=info; 
    node->next=*head; 
    *head=node; 
    } 
    push(&head,5); 

et la suivante est

void push(list *head, int info) 
    { 
    list *node=new list; 
    node->data=info; 
    node->next=head; 
    head=node; 
    } 
    push(head,5); 
+2

votre second passe le pointeur 'head' par valeur, donc' head = node' n'a pas d'effet, est-ce cela que vous voulez dire? – user463035818

+0

Dans le 2ème cas, vous passez le 'head' (qui est un pointeur) mais pas l'adresse de celui-ci. Ainsi, le changement de 'head'happens" localement "dans' push() 'mais pas sur' 'original'' 'head'. – Scheff

+0

Par défaut, les arguments sont passés * par valeur *, ce qui signifie qu'ils sont copiés. Maintenant, si vous modifiez une copie, l'original ne changera pas, non? Alors que pensez-vous qui se passe lorsque vous, dans la deuxième fonction, modifiez la * copie * ('head') d'une variable? –

Répondre

0

Insérer Si un noeud se trouve au début d'une liste chaînée, vous devez mettre à jour le pointeur head, c'est-à-dire l'adresse du premier noeud.

Votre implémentation interrompue ne met jamais à jour le pointeur de tête en dehors de la fonction, seulement la copie locale de celle-ci, donc l'implémentation est incomplète.

1

La première reçoit un pointeur - le pointeur de tête, tandis que la seconde version reçoit une copie du pointeur de tête. Par conséquent, la première version est capable de modifier le pointeur de tête, tandis que la seconde ne peut modifier la copie locale ici: head = node.

Pour faire la deuxième version de travail, vous pouvez accepter le pointeur head par référence: il suffit de choisir la signature de la fonction à void push(list * & head, int info)(notez le &). Vous voudrez peut-être lire plus sur pointers et references.

0

les exemples de code ci-dessous vous montrent la base de l'argumentation en passant par valeur et par référence:

par pointeur:

foo(int* ref) 
{ 
    *ref = 1; 
} 

void main(void) 
{ 
    int bar = 0; 
    foo(&bar); 
    print("%d",bar); //print 1 
} 

par valeur:

// this 'int val' will be created on the stack when the function get called and 
// the value passed to the function will be copied to the temporary val argument 
foo(int val) 
{ 
    val = 1; 
} 

void main(void) 
{ 
    int bar = 0; 
    foo(bar); 
    print("%d",bar); //print 0 
} 

Dans le premier exemple, nous passer un pointeur vers un int (qui contient l'adresse de 'bar' depuis le menu principal) et donc quand on modifie la variable pointée par le refe Nous modifions en fait le 'bar' de la main.

Toutefois, dans le deuxième exemple nous passons la valeur de « bar » à copier dans une variable temporaire appelée « val » (« val » existent que dans la fonction « foo » et n'est pas le même que 'barre' dans le principal) ainsi quand nous le modifions, rien n'est visible de la main.

Vos exemples sont identiques à cela, sauf que pour vous:

  • 'int bar' est 'liste * tête'
  • 'int * ref' est 'la liste ** tête'
  • ' int val 'est' list * head '

J'espère que vous avez eu l'idée. Sinon, vous lisez sur les pointeurs et les références, pas la notion la plus simple en C/C++. Que voulez-vous dire par «ne fonctionne pas»?

+0

Je comprends parfaitement votre exemple. Je connaissais aussi ton exemple, mais ce qui me déroute, c'est que lorsque tu passes en valeur, tu passes une variable pour qu'elle soit copiée. Mais j'envoie l'adresse de la variable dans 'push (head, 5);' Tout comme vous avez passé par référence dans le cas du pointeur. Donc, quel que soit le changement qui se produit, il devrait arriver à la vraie tête aussi bien? .. –

+0

Okay Maintenant, je l'ai compris. Merci –

+0

Parce que vous voulez modifier un pointeur, vous devez passer l'adresse de ce pointeur et vous avez un pointeur vers le pointeur vers la liste –