IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Problème avec les listes chaînées


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut Problème avec les listes chaînées
    Salut tout le monde ...
    Je viens de débuter en listes chaînées et au polycopie du prof j'ai voulu vérifier un simple exercice sur l'insertion des éléments et leur affichage ensuite .... Mais à l'exécution il y avait un comportement indéfini

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #include<stdio.h>
    #include<string.h>
    typedef struct Noeud
    {
            char mot[15];
            struct Noeud *suivant;
    }noeud ;
    void inser(char s[],noeud *fin)
    {
         noeud *nouveau;
         int i;
         nouveau=(noeud*)malloc(sizeof(noeud));
         nouveau->suivant = NULL;
         for(i=0;i<strlen(s);i++)
         nouveau->mot[i]=s[i];
         fin->suivant=nouveau;
         fin=nouveau;
    }
    void aff(noeud *p)
    {
         int i;
         while(p!=NULL)
         {
         for(i=0;i<strlen(p->mot);i++)
         printf("%c",p->mot[i]);
         p=p->suivant;
         }
    }
    main()
    {
          noeud *debut,*fin;
          char Z[]="faculte";
          char ch[15];
          int i;
          debut=(noeud*)malloc(sizeof(noeud));
     
          for(i=0;i<strlen(Z);i++)
          debut->mot[i]=Z[i];
     
          debut->suivant=NULL;
          fin=debut;
          printf("saisir les mot : \n");
          i=0;
          do
          {
                         gets(ch);
                         inser(ch,fin);
                         i++;
          }
          while (i!= 3);
     
          aff(debut);
     
          getchar();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    saisir les mot :
    des
    science
    info
    faculteinfox☺=
    Alors ou est le problème ?

    Une autre question au code il y avait comme ça

    A la place de ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char Z[]="faculte";
    debut->mot[i]=Z[i];
    Mais je l'ai changé car il y avait une erreur lors de la compilation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    incompatible types in assignment
    Alors pourquoi l'erreur ?

  2. #2
    Gf6HqmTW
    Invité(e)
    Par défaut
    Dans un premier temps jeune brimborion je vais te demander ce que dirait ta mere si elle apprenait que tu parle de string sur des forums jusqu'à 2H27 du matin ?
    Et sinon pour ton probleme alors c'est simple comme bonjour !
    Tu ne remplaces jamais le "noeud *fin" qui se trouve dans ton main au moment ou tu fais un "inser" car ce pointeur est passé par valeur, c'est comme si la case sur lequel il pointait etait passée elle par adresse ceci dit toutes modifications que tu peut apporter à fin dans ta fonction inser n'a court que dans cette derniere !

    pour rectifier le tire il faudrait soit qu'apres ton appel de fonction du déclare que fin=fin->suivant (apres l'appel hein, pas à la fin du code de la fonction) ou alors que tu appel fin par adresse et non par valeur ayant ainsi un pointeur vers un pointeur à gerer ce qui est plus chiant mais un poil plus rigoureux ...

    En gros ce qui se passe en ce moment c'est que tu n'avances pas dans ta chaine au remplissage et remplis à chaque fois la case juste apres debut laissant par ailleurs les cases préremplis se perdre dans le cosmos ...
    Par contre je ne vois pas pourquoi ta fonction afficher ne s'arrete pas apres FaculteInfo et continue à essayer d'afficher une case alors qu'elle devrait tomber sur un null ...
    Mais essai déja de corriger ca et dis nous ce qu'il en est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #include<stdio.h>
    #include<string.h>
    typedef struct Noeud
    {
            char mot[15];
            struct Noeud *suivant;
    }noeud ;
    void inser(char s[],noeud *fin)
    {
         noeud *nouveau;
         int i;
         nouveau=(noeud*)malloc(sizeof(noeud));
         nouveau->suivant = NULL;
         for(i=0;i<strlen(s);i++)
         nouveau->mot[i]=s[i];
         fin->suivant=nouveau;
         fin=nouveau;      //<--- Voila le probleme, cette ligne ne fait rien sur le fin passé en parametre ...
    }
    void aff(noeud *p)
    {
         int i;
         while(p!=NULL)
         {
         for(i=0;i<strlen(p->mot);i++)
         printf("%c",p->mot[i]);
         p=p->suivant;
         }
    }
    main()
    {
          noeud *debut,*fin;
          char Z[]="faculte";
          char ch[15];
          int i;
          debut=(noeud*)malloc(sizeof(noeud));
          
          for(i=0;i<strlen(Z);i++)
          debut->mot[i]=Z[i];
          
          debut->suivant=NULL;
          fin=debut;
          printf("saisir les mot : \n");
          i=0;
          do
          {
                         gets(ch);
                         inser(ch,fin);
                         i++;
          }
          while (i!= 3);
          
          aff(debut);
             
          getchar();
    }
    J'espere que ca t'aide ^^

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par yous18 Voir le message
    Salut tout le monde ...
    Je viens de débuter en listes chaînées et au polycopie du prof j'ai voulu vérifier un simple exercice sur l'insertion des éléments et leur affichage ensuite
    Déjà, pour du code de prof, c'est pas fameux...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Project   : Forums
    Compiler  : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `inser':
    main.c:12: warning: implicit declaration of function `malloc'
    main.c:14: warning: comparison between signed and unsigned
    main.c: In function `aff':
    main.c:24: warning: comparison between signed and unsigned
    main.c: At top level:
    main.c:30: warning: return type defaults to `int'
    main.c:30: warning: function declaration isn't a prototype
    main.c: In function `main':
    main.c:37: warning: comparison between signed and unsigned
    main.c:55: warning: control reaches end of non-void function
    Linking console executable: console.exe
    Process terminated with status 0 (0 minutes, 7 seconds)
    0 errors, 7 warnings
    L'exemple de code est calamiteux... Il y a des bons tutoriels sur les listes chainées sur ce site, et j'ai fait ça...

    Et puis, je rappelle que pour copier une chaine, on utilise strcpy() et pour l'afficher, printf() avec "%s". Je ne veux plus voir ces boucles infâmes... On ne se lance pas dans les listes chainées si on ne maitrise pas les bases du C...

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Voici quelques corrections. Pose des questions si tu ne comprends pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    #include <stdio.h>
    /* -tc- necessaire pour malloc() */
    #include <stdlib.h>
    #include <string.h>
     
    #define MAX_TAILLE_MOT 15u
     
    typedef struct Noeud
    {
        char mot[MAX_TAILLE_MOT];
        struct Noeud *suivant;
    }
    noeud;
     
    /* -tc- on crée une structure liste pour se faciliter la vie */
    typedef struct Liste
    {
        noeud *debut;
        noeud *fin;
    }
    liste;
     
    void inser(liste *lst, char const s[])
    {
        /* -tc- on verifie que les parametres sont valides (programmation
           defensive */
        if (lst != NULL && s != NULL)
        {
            noeud *nouveau = NULL;
     
            /* -tc- le cast de la valeur retournee par malloc() est inutile voir
               meme deconseille */
            nouveau = malloc(sizeof *nouveau);
            /* -tc- il faut TOUJOURS verifier la valeur retournee par malloc() */
            if (nouveau != NULL)
            {
                size_t i;
     
                nouveau->suivant = NULL;
                /* -tc- copie de la chaine: attention aux debordements. Tu
                   peux aussi utiliser strncpy() ou strncat() pour plus de
                   confort. */
                for(i = 0; i < MAX_TAILLE_MOT - 1 && i < strlen(s);i++)
                {
                    nouveau->mot[i] = s[i];
                }
                nouveau->mot[i] = '\0';
                /* -tc- alternative plus evidente:
                    
                    nouveau->mot[0] = '\0';
                    strncat(nouveau->mot, s, MAX_TAILLE_MOT - 1);
                 */
     
                if (lst->debut != NULL && lst->fin != NULL)
                {
                    lst->fin->suivant = nouveau;
                    lst->fin = nouveau;
                }
                else
                {
                    lst->debut = nouveau;
                    lst->fin = nouveau;
                }
            }
        }
    }
     
    void aff(liste *lst)
    {
        if (lst != NULL)
        {
            noeud *p = lst->debut;
            while(p != NULL)
            {
                printf("%s\n",p->mot);
                p = p->suivant;
            }
        }
    }
     
    /* -tc- Si tu fait de l'allocation dynamique, il faut prevoir de liberer la
       memoire. */
    void liber(liste *lst)
    {
        if (lst != NULL)
        {
            noeud *p = lst->debut;
            noeud *tmp = NULL;
     
            while (p != NULL)
            {
                tmp = p;
                p = p->suivant;
                free(tmp);
            }
            lst->debut = NULL;
            lst->fin = NULL;
        }
    }
     
    /* -tc- elimine le caractere de fin de ligne saisi par fgets() et purge le
     * tampon du flux entrant si necessaire (saisie tronquee) */
    void fclean(char tampon[], FILE *fp)
    {
        if (tampon != NULL && fp != NULL)
        {
            char *pc = strchr(tampon, '\n');
     
            if (pc != NULL)
            {
                *pc = 0;
            }
            else
            {
                int c;
     
                while ((c = fgetc(fp)) != '\n' && c != EOF)
                {
                }
            }
        }
    }
     
    /* -tc- main() revoie un entier de type int, TOUJOURS. */
    int main(void)
    {
        liste ma_liste = {NULL, NULL};
        char ch[15] = "";
        int i;
     
        inser(&ma_liste, "faculte");
     
        printf("saisir les mot: \n");
     
        for (i = 0; i < 3; i++)
        {
            fgets(ch, sizeof ch, stdin);
            fclean(ch, stdin);
            inser(&ma_liste, ch);
        }
        aff(&ma_liste);
        liber(&ma_liste);
     
        return EXIT_SUCCESS;
    }
    Thierry

  5. #5
    Gf6HqmTW
    Invité(e)
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Je ne veux plus voir ces boucles infâmes... On ne se lance pas dans les listes chainées si on ne maitrise pas les bases du C...
    Je me permet d'intervenir ...
    Notre cher ami yous18 semble etre un etudiant en train d'essayer d'apprendre des concepts tels que celui des listes chainées car ses profs les lui présentent.
    Le concept de liste chainée est indépendant de tout langage, pour ma part je le ai appris en langage algorithmique puis en pascal et avant même d'avoir jamais produit une seule ligne de C/C++/Autre (preciser).
    A mon avis Yous à posté ici car son prof lui à appris les Listes Recursives (ou listes chainées c'est idem) en se basant sur le langage C pour porter ses exemples
    Il ne s'est pas lancé dans des StrCopy pour ne pas embrouiller ses etudiant en leur apprenant des le début qu'une chaine, quoi qu'il arrive, lorsqu'elle est copiée l'est, au niveau machine, par des iteration multiples et pas en une operation comme le suggere StrCopy.
    Bien sur le code de son prof est pas top mais je pense qu'il est bon de répondre d'abords à la question que ce pose un etudiant qui cherche a comprendre un concept independant des notions de syntaxe ou te portabilité du code en nomre ISO-120069 plutôt que de l'embrouiller en remettant en cause des portions de code moches mais fonctionnelles !

    Ceci dit c'est juste mon avis mais je le partage ...

  6. #6
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par GuJman Voir le message
    Je me permet d'intervenir ...
    Notre cher ami yous18 semble etre un etudiant en train d'essayer d'apprendre des concepts tels que celui des listes chainées car ses profs les lui présentent.
    Le concept de liste chainée est indépendant de tout langage, pour ma part je le ai appris en langage algorithmique puis en pascal et avant même d'avoir jamais produit une seule ligne de C/C++/Autre (preciser).
    A mon avis Yous à posté ici car son prof lui à appris les Listes Recursives (ou listes chainées c'est idem) en se basant sur le langage C pour porter ses exemples
    Il ne s'est pas lancé dans des StrCopy pour ne pas embrouiller ses etudiant en leur apprenant des le début qu'une chaine, quoi qu'il arrive, lorsqu'elle est copiée l'est, au niveau machine, par des iteration multiples et pas en une operation comme le suggere StrCopy.
    Bien sur le code de son prof est pas top mais je pense qu'il est bon de répondre d'abords à la question que ce pose un etudiant qui cherche a comprendre un concept independant des notions de syntaxe ou te portabilité du code en nomre ISO-120069 plutôt que de l'embrouiller en remettant en cause des portions de code moches mais fonctionnelles !

    Ceci dit c'est juste mon avis mais je le partage ...
    C'est strcpy() et non StrCopy()! L'approche "copier un tableau de caractères via une boucle" est louable s'il est motivé par les objectifs que tu avances. Dès lors, il faut apprendre à l'étudiant à écrire ce type de boucles correctement en faisant attention à:
    • empêcher les débordement de tampon
    • ajouter manuellement le caractère nul '\0' en fin de chaine


    Par ailleurs, le PO utilise strlen() qui utilise également une boucle pour déterminer la longueur de la chaine.

    J'attire ton attention sur le fait que la boucle suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(i=0;i<strlen(Z);i++)
          debut->mot[i]=Z[i];
    est fausse! Et pour les raisons suivantes:
    • si strlen(Z) est supérieure à sizeof mot, on a un débordement de tampon (grave)
    • La chaine mot, après copie, ne se termine pas par le caractère nul (grave)
    • strlen() renvoie un entier de type size_t (non signé) et i est défini comme un entier de type i. Mon compilateur refuse de les comparer sans conversion explicite. Dans ce contexte, je préfère définir i comme un entier de type size_t (évitant ainsi la conversion).
    • strlen() est exécuté à chaque tour de boucle (c'est pas terrible point de vue performance de l'algo)


    La boucle suivante est correcte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(void)
    {
        char const *Z = "faculte";
        char mot[15];
        size_t i;
        const size_t TAILLE_Z = strlen(Z);
     
        /* -tc- Du point de vue de la lisibilite, je conseille de toujours utiliser
            les accolades */
        for (i = 0; i < sizeof mot - 1 && i < TAILLE_Z; i++)
        {
            mot[i] = Z[i];
        }
        /* -tc- Il est egalement possible d'initialiser le tableau lors de la 
            definition, ce qui evite d'avoir a placer le caractere nul explicitement
            avec l'instruction suivante */
        mot[i] = '\0';
     
        /* Suite du code */
     
        return EXIT_SUCCESS;
    }
    Quelques soient les objectifs pédagogiques poursuivis, il est très important de faire attention à la lisibilité du code. Ainsi:
    • Z ne dit pas grand chose sur la nature, la valeur ou l'utilise de la chaine de caractère sur laquel il pointe.
    • L'usage systématique d'accolades avec des structures de contrôle telles que for, while, do ... while, etc. aide à la lisibilité et à la maintenance du code.


    Thierry

  7. #7
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par GuJman Voir le message
    Tu ne remplaces jamais le "noeud *fin" qui se trouve dans ton main au moment ou tu fais un "inser" car ce pointeur est passé par valeur, c'est comme si la case sur lequel il pointait etait passée elle par adresse ceci dit toutes modifications que tu peut apporter à fin dans ta fonction inser n'a court que dans cette derniere !
    merci cher ami et désole pour le retard ... mais mon prof dans le cour des pointeurs nous a dit que si on fais passer un pointeur la modification sera fait ... et ici la case sur lequel pointait fin va être modifier ...
    Peux-tu encore m'explique ce point car je pence qu'il est très important pour bien comprendre ces liste chainée
    P.S dans le polycopie le prof ne met pas "noeud *fin" dans les arguments de la fonction inser c'est moi qui l'ai ajoute car quand je compilais il y avait `fin' undeclared (first use in this function)

  8. #8
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    J'attire ton attention sur le fait que la boucle suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(i=0;i<strlen(Z);i++)
    debut->mot[i]=Z[i];
    est fausse!
    merci Thierry ...et le prof avait ecrit comme ça
    Mais je l'ai changé car il y avait une erreur lors de la compilation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    incompatible types in assignment
    alors tu peux me l'expliquer ?
    et merci pour ton code mais il est un peu fort pour mon niveau ... car je voulais juste des base sur le liste chainée

  9. #9
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    debut->mot est un tableau de caractères. Tu ne peux pas copier un litéral chaine de caractères directement dans un tableau en précédant de cette manière. Il faut utiliser strncat() ou strncpy() pour cela.

    Le seul moment où tu peux initialiser un tableau de caractères avec une chaine litérale, c'est au moment de la définition du tableau. Ainsi tu peut faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char tableau[15] = "Salut, dvp!";
    qui est strictement équivalent à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char tableau[15] = {'S', 'a', 'l','u', 't', ',', ' ', 'd', 'v', 'p', '!', '\0'};
    Thierry

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Citation Envoyé par TC
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char tableau[11] = {'S', 'a', 'l','u', 't', ',', ' ', 'd', 'v', 'p', '!', '\0'};
    Sauf que ça fait douze caractères, ça...

  11. #11
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Oui, mille excuse, j'étais parti pour agrandir la taille de mon tableau, mais je me suis perdu en route. C'est maintenant corrigé!

    Thierry

  12. #12
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par GuJman Voir le message
    Tu ne remplaces jamais le "noeud *fin" qui se trouve dans ton main au moment ou tu fais un "inser" car ce pointeur est passé par valeur, c'est comme si la case sur lequel il pointait etait passée elle par adresse ceci dit toutes modifications que tu peut apporter à fin dans ta fonction inser n'a court que dans cette derniere !
    quelq'un peut m'expliquer cela ?
    moi je sais que si on passe par adresse la modification sera fait ...

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par yous18 Voir le message
    quelq'un peut m'expliquer cela ?
    moi je sais que si on passe par adresse la modification sera fait ...
    http://emmanuel-delahaye.developpez....difie_variable

  14. #14
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    merci
    mais a ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    void modif(int *p)
    {
         *p=*p+10;
    }
     
     
    main()
    {
          int x=10;
          int *p=&x;
          modif(p);
          printf("X = %d",*p);
    getch();
    //return 0;
    }
    j'ai eu la valeur X = 20 ... ça veut dire que meme que le pointeur est passé en valeur est modifié !!!
    alors pourquoi "noeud *fin" ne sera pas modifier dans la fonction inser

  15. #15
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par yous18 Voir le message
    merci
    mais a ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    void modif(int *p)
    {
         *p=*p+10;
    }
     
     
    main()
    {
          int x=10;
          int *p=&x;
          modif(p);
          printf("X = %d",*p);
    getch();
    //return 0;
    }
    j'ai eu la valeur X = 20 ... ça veut dire que meme que le pointeur est passé en valeur est modifié !!!
    alors pourquoi "noeud *fin" ne sera pas modifier dans la fonction inser
    Pourquoi? p est effectivement passé par valeur à ta fonction qui, par ailleurs, ne modifie que la valeur de x et pas celle de p. Au passage: la forme que tu utilise pour définir la fonction main() n'est pas valide en C. main() retourne TOUJOURS un entier de type int.

    Thierry

  16. #16
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    merci thierry
    et j'ai verifié par ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(void)
    {
          int x=10;
          int *p=&x;
          printf("La valeur de p est = %d\n",p);
          modif(p);
          printf("X = %d\n",*p);
          printf("La valeur de p est = %d",p);
    getch();
    return 0;
    }
    Je vx savoir ce qui se passe réellement quand on passe par adresse et non par valeur ? Car en cour on me dit juste que les pointeurs ils permet de modifié les variable dans une fonction. Mais ils ne précisent pas comment ça marche ...
    pour la main tjrs je défini pas son type de retours et sa marche très bien !!!

  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par yous18 Voir le message
    merci thierry
    et j'ai verifié par ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(void)
    {
          int x=10;
          int *p=&x;
          printf("La valeur de p est = %d\n",p);
          modif(p);
          printf("X = %d\n",*p);
          printf("La valeur de p est = %d",p);
    getch();
    return 0;
    }
    Je vx savoir ce qui se passe réellement quand on passe par adresse et non par valeur ? Car en cour on me dit juste que les pointeurs ils permet de modifié les variable dans une fonction. Mais ils ne précisent pas comment ça marche ...
    Je fatigue... J'ai déjà donné un lien qui explique comment ça se passe. Tu ne l'as évidemment pas lu...

    Rappel : http://emmanuel-delahaye.developpez....difie_variable

    Tous les passages de paramètres se font par valeur en C. Si tu veux modifier la valeur d'un pointeur, il faut passer son adresse. Evidemment, le paramètre doit être du bon type...


    pour la main tjrs je défini pas son type de retours et sa marche très bien !!!
    C'est interdit en C99. Le type doit être explicite.

  18. #18
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Je fatigue... J'ai déjà donné un lien qui explique comment ça se passe. Tu ne l'as évidemment pas lu...

    Rappel : http://emmanuel-delahaye.developpez....difie_variable
    .
    oui j'ai déja lu ton lien ... mais je crois que tu me comprend pas ... je suis pas un pro .... je savoir théoriquement comment ça se passe

  19. #19
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par yous18 Voir le message
    mais a ce code
    Ce code est incomplet et mal écrit.
    Ton code corrigé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    #include <stdio.h>
     
    void modif (int *p)
    {
       *p = *p + 10;
    }
     
    int main (void)
    {
       int x = 10;
       int *p = &x;
       modif (p);
       printf ("X = %d\n", *p);
     
       return 0;
    }
    j'ai eu la valeur X = 20 ... ça veut dire que meme que le pointeur est passé en valeur est modifié !!!
    alors pourquoi "noeud *fin" ne sera pas modifier dans la fonction inser
    Non. Ca veut dire, et c'est normal, que la valeur pointée a été modifiée.

    Le pointeur n'a pas été modifié. La preuve :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    #include <stdio.h>
     
    void modif (int *p)
    {
       *p = *p + 10;
    }
     
    int main (void)
    {
       int x = 10;
       int *p = &x;
       printf ("X = %d\n", *p);
       printf ("p = %p\n", (void*)p);
       modif (p);
       printf ("X = %d\n", *p);
       printf ("p = %p\n", (void*)p);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    X = 10
    p = 0022FF70
    X = 20
    p = 0022FF70
     
    Press ENTER to continue.

  20. #20
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par yous18 Voir le message
    oui j'ai déja lu ton lien ... mais je crois que tu me comprend pas ... je suis pas un pro .... je savoir théoriquement comment ça se passe
    Qu'est-ce que tu ne comprends pas ? Tu veux que je fasse un copié-collé de mon article ?

    Quels sont les mots ou expressions que tu ne comprends pas ?

Discussions similaires

  1. problème avec les listes chaînées : suite
    Par ChPr dans le forum Langage
    Réponses: 11
    Dernier message: 18/09/2013, 10h08
  2. problème avec les listes chaînées.
    Par ChPr dans le forum Langage
    Réponses: 3
    Dernier message: 12/09/2013, 15h54
  3. Problème avec les listes chaînées
    Par Kawada dans le forum C
    Réponses: 2
    Dernier message: 06/05/2012, 17h20
  4. [TP 7] Problème avec les listes chaînées (error 202)
    Par thelinekioubeur dans le forum Turbo Pascal
    Réponses: 4
    Dernier message: 06/12/2006, 23h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo