Passage de listes chaînées en argument

Résolu
dwld Messages postés 4 Date d'inscription   Statut Membre Dernière intervention   -  
dwld Messages postés 4 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour à tous !

Je m'explique :

Le programme crée 2 listes chaînées contenant des nombres, puis on recherche les éléments identiques aux deux listes et on les copie dans une troisième liste chaînée appelée 'listeCommune'.

Mes problèmes :

1- Je ne comprend pas pourquoi je suis obligé de mettre un '&' devant 'nouveauElement->val' lorsque j'assigne la valeur entrée par l'utilisateur.

2- Je ne comprend pas pourquoi dans ma fonction 'rechercher' ma 'liste3' est bien modifiée (voir l'affichage 'TEST' que je fais dans ma fonction) alors que quand je reviens dans mon 'main', ma liste chaînée 'listeCommune' n'a pas été modifiée !? Je passe pourtant mes listes sous forme de pointeur de liste !? Pourquoi ça fonctionne pour ma fonction 'ajouter' et ça modifie bien la liste originale et ça ne fonctionne pas pour ma fonction 'rechercher' et ça ne modifie pas la liste originale ???

Voici mon code :


#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define N 3 

typedef struct element 
{ 
    int val; 
    struct element *nxt; 
} element, *llist; 

llist ajouter(llist liste, int i) 
{ 

    /* On crée un nouvel élément */ 
    llist nouveauElement = malloc(sizeof(element)); 

    /* On assigne la valeur au nouvel élément */ 
    printf("\n\nIntroduisez la %d(ere/eme) valeur : ",i); 
    scanf("%d", &nouveauElement->val);//Pourquoi ça marche pas sans le & ?? 

    nouveauElement->nxt = NULL; 

    /* On ajoute en fin, donc aucun élément ne va suivre */ 
    if(liste == NULL) 
    { 
        liste = nouveauElement; 
    } 
    else 
    { 
        /* Sinon, on parcourt la liste à l'aide d'un pointeur temporaire et on 
        indique que le dernier élément de la liste est relié au nouvel élément */ 
        llist temp = liste; 
        while(temp->nxt != NULL) 
        { 
            temp = temp->nxt; 
        } 
        temp->nxt = nouveauElement; 
    } 
    nouveauElement = NULL; 
    free(nouveauElement); 

    return liste; 
} 

void afficher(llist liste) 
{ 
    int i; 
    llist tmp = liste; 
    /* Tant que l'on n'est pas au bout de la liste */ 

    for(i = 1; tmp != NULL; i++) 
    { 
        /* On affiche */ 
        printf("\n\nLa %d(ere/eme) valeur est : %d", i, tmp->val); 
        /* On avance d'une case */ 
        tmp = tmp->nxt; 
    } 
} 

llist rechercher(llist liste1, llist liste2, llist liste3) 
{ 
    llist tmp1 = liste1; 
    /* Tant que l'on n'est pas au bout de la liste */ 
    while(tmp1 != NULL) 
    { 
        llist tmp2 = liste2; 

        while (tmp2 != NULL) 
        { 
            if (tmp1->val == tmp2->val) 
            { 
                llist nouveauElement = malloc(sizeof(element)); 

                /* On assigne la valeur au nouvel élément */ 
                nouveauElement->val = tmp2->val; 

                nouveauElement->nxt = NULL; 

                if(liste3 == NULL) 
                { 
                    liste3 = nouveauElement; 
                } 

                else 
                { 
                    /* Sinon, on parcourt la liste à l'aide d'un pointeur temporaire et on 
                    indique que le dernier élément de la liste est relié au nouvel élément */ 
                    llist temp=liste3; 
                    while(temp->nxt != NULL) 
                    { 
                        temp = temp->nxt; 
                    } 
                    temp->nxt = nouveauElement; 
                } 
                nouveauElement = NULL; 
                free(nouveauElement); 
            } 
            tmp2 = tmp2->nxt; 
        } 
        tmp1 = tmp1->nxt; 
    } 
    printf("\n-------------------TEST-----------------"); 
    afficher(liste3);//Pourquoi ici ça marche ?? 
    printf("\n-------------------TEST-----------------\n"); 
    return liste3; 
} 


main() 
{ 
    llist maListe1 = NULL; 
    llist maListe2 = NULL; 
    llist listeCommune = NULL; 
    int i = 0; 

    printf("\nENTREZ LES VALEURS DE LA PREMIERE LISTE :\n"); 
 printf("----------------------------------------"); 

    for(i = 1; i <= N; i++) 
    { 
        maListe1 = ajouter(maListe1, i); 
    } 

    printf("\nENTREZ LES VALEURS DE LA DEUXIEME LISTE :\n"); 
 printf("----------------------------------------"); 

    for(i = 1; i <= N; i++) 
    { 
        maListe2 = ajouter(maListe2, i); 
    } 

    printf("\nLES VALEURS DE LA PREMIERE LISTE SONT :\n"); 
 printf("--------------------------------------"); 
    afficher(maListe1);// Ici aussi ça marche !! 

    printf("\n\nLES VALEURS DE LA DEUXIEME LISTE SONT :\n"); 
 printf("--------------------------------------"); 
    afficher(maListe2);// Et ici aussi !!?? 

    rechercher(maListe1, maListe2, listeCommune); 

    printf("\n\nLES VALEURS DE LA LISTE COMMUNE SONT :\n"); 
 printf("-------------------------------------"); 
    afficher(listeCommune);// Et pourquoi ici ça marche pas ?? 

} 




Merci de me mettre sur la voie...
A voir également:

6 réponses

KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
1) Tu utilises le &, dans ton scanf car c'est le pointeur dont on a besoin.
Par exemple : tu aurais : int n; scanf("%d",&n); pour récupérer un entier.

2) Dans ton code, le résultat de rechercher est obtenu dans le return liste3; il ajoute à la liste3 passée en paramètre les éléments communs de liste1 et liste2, mais ne modifie pas directement liste3.
Ainsi, listeCommune=rechercher(maListe1, maListe2, NULL); fait ce que tu veux.

Remarque : j'ai pas trop regardé pourquoi mais rechercher(maListe1, maListe2, maListe2); plante alors que rechercher(maListe1, maListe2, maListe1); marche
1
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Un forum c'est fait pour poser des questions, alors pas de soucis ;)

1) une chaîne de caractères c'est un pointeur char* donc pas de soucis, alors qu'un int, il faut lui mettre un & devant pour savoir quel est son pointeur (voir aussi : scanf)
Ici ton nouveauElement->val c'est un int, donc tu dois lui mettre un & devant.

2) Pour que ça modifie directement ta listeCommune, tu peux faire ceci :
llist rechercher(llist liste1, llist liste2, llist &liste3) { ... }

Remarque : dans ce cas, ça ne sert plus à rien de faire return liste3;
1
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Je ne l'avais pas dit, mais pour tester j'ai du faire (llist) malloc(sizeof(element);
Sinon ça me mettait une erreur.

Dans ajouter, ta liste est modifiée car tu utilises maListe1=ajouter(maListe1, i);
Mais en fait elle n'est modifiée que grace au return liste; dans ajouter.
Si tu avais juste ajouter(maListe1, i); rien ne serait ajouté.
Sauf bien sûr si tu mettais un & dans llist ajouter(llist &liste, int i)
1
dwld Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
Tout d'abord, un grand merci pour ta réponse.

Ensuite :

1) pour le '&', ce que je ne comprend pas c'est que si au lieu de mettre un 'int val' dans ma structure je mettais un 'char nom [31]', par exemple, alors je n'ai pas besoin de mettre le '&'. Pourquoi lorsque j'affecte un entier je dois le mettre et pourquoi lorsque c'est une chaîne de caractères, il n'est pas nécessaire de le mettre et cela fonctionne très bien ?

2) Ok, le problème est que ma 'liste3' que je lui passe en paramètre est en réalité ma 'listeCommune' si tu regarde bien. Donc, cela devrait modifié directement ma 'listeCommune' puisque je la passe par pointeur ! Non ?! Il est possible de contourner le problème en faisant :

listeCommune=rechercher(maListe1, maListe2, listeCommune);

comme tu le propose.Cependant, ça ne m'aide pas à comprendre pourquoi ma fonction ne la modifie pas directement.

PS : Je pose beaucoup de question, mais c'est parce que j'aime bien comprendre ce que je fais et je ne veux pas seulement que ça fonctionne, mais je veux comprendre pourquoi ça fonctionne et pourquoi ça ne fonctionne pas.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dwld Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
1) Pour ce qui est du '&' j'ai compris maintenant. Y'a plus rien a dire. C'est clair comme de l'eau de roche et j'aurais du y penser.

2) Par contre, pour ce qui est du rechercher, je dois t'avouer que j'avais déjà pensé au coup du '&liste3', mais ça ne marche pas. Il m'affiche le warning :

warning: passing argument 3 of 'rechercher' from incompatible pointer type

et ensuite le programme plante.
0
dwld Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
MERCI
0