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 :

un problème de passage de paramétres


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut un problème de passage de paramétres
    Salut ! je veux faire une procédure en C qui défile le premier élément d'une liste chaînée et renvoi ça valeur dans une variable de type entier, sachant que je veux détruire cette élément de la liste âprés avoir récupérer ça valeur.
    le probléme c'est que la liste passé en parametre ne change pas, voila le 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
    17
    18
    struct elt {
        int val ;
        struct elt *suiv ;
    };
    typedef struct elt* liste;
     
    void defiler_l_int(liste l,int* x)
    {    liste q = l ;
         liste p = l;
         p=l->suiv;
        if(q!=NULL) {*x=q->val;
                    l=p;
                    q->suiv=NULL;
                    free(q);
                    }
     
     
    }
    et quand je fais ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void defiler_l_int(liste* l,int* x)
    {    liste q = *l ;
         liste p = *l;
         p=l->suiv;
        if(q!=NULL) {*x=q->val;
                    l=p;
                    q->suiv=NULL;
                    free(q);
                    }
     
     
    }
    il y a il erreur qui s'affiche pour me dire que
    `suiv' has not been declared
    dans l'instruction suivante:c'est quoi le problème ! aidez moi svp !

  2. #2
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 872
    Par défaut
    La variable q n'etant pas un pointeur, la comparer a NULL ou tenter de faire un free dessus n'a aucun sens.

    Comme ce n'est pas un pointeur, pour acceder a ces elements tu ne dois pas utiliser "->" mais ".".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    liste *q;
    q->val;
     
    list p;
    p.val;
    Donc reprenons ton code et modifions-le un peu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void defiler_l_int(liste* l,int* x)
    {
      liste *q = l ;
      liste *p = l->suiv;
     
      if (q != NULL) {
         *x = q->val;
         l = p; //cette ligne n'a juste aucun sens
         q->suiv = NULL; //celle-la non plus d'ailleurs...
         free(q); //pourquoi veux-tu liberer la memoire ici ?
      }
    }

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Citation Envoyé par imperio Voir le message
    La variable q n'etant pas un pointeur, la comparer a NULL ou tenter de faire un free dessus n'a aucun sens.

    La variable q EST un pointeur !

    Comme dans beaucoup d'écoles, on lui apprend à faire ce qu'il ne faut pas faire en C : masquer un pointeur dans un typedef. : typedef struct elt* liste;.

  4. #4
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 872
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    La variable q EST un pointeur !

    Comme dans beaucoup d'écoles, on lui apprend à faire ce qu'il ne faut pas faire en C : masquer un pointeur dans un typedef. : typedef struct elt* liste;.
    Oups ! Effectivement je n'avais pas du tout fait gaffe au typedef...

    Citation Envoyé par mohsenuss91 Voir le message
    Que ce que je dois faire!
    Réflechir me semble être une bonne piste. Donc la question est plutôt : qu'est-ce que toi tu veux faire ?

  5. #5
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut
    J'ai pas compris l'erreur suivante
     `suiv' has not been declared 
    malgré que dans la structure le suiv existe!

  6. #6
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 872
    Par défaut
    Ton erreur decoule directement de la remarque qu'a fait Obsidian.

  7. #7
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    La variable q EST un pointeur !

    Comme dans beaucoup d'écoles, on lui apprend à faire ce qu'il ne faut pas faire en C : masquer un pointeur dans un typedef. : typedef struct elt* liste;.
    Si j’enlève le typedef struct ça marche pas :/

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Il ne s'agit pas de faire les choses au hasard et de se lamenter parce que "ça ne marche pas", mais de réfléchir un peu.

    La struct elt définit un maillon de la liste.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct elt
    {
        int val ;
        struct elt *suiv ;
    }Maillon;
    Maintenant, il faut définir la liste. On peut se contenter d'un pointeur, mais pour la clarté, il convient de bien distinguer les maillons et la liste (qui est une collection ordonnée de maillons). Une structure a l'avantage d'accentuer son caractère particulier et finalement la clarté du code. De plus, on pourra éventuellement y ajouter d'autres informations qui peuvent apparaitre utiles (pointeur de queue, nombre d'éléments,...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct
    {
       Maillon * tete;
    } Liste;
    A noter que cela respecte le critère d'Obsidian puisque maintenant Liste n'est pas un pointeur mais un struct

    Maintenant, on peut discuter de la fonction defiler_l_int():
    -A- Si la liste est vide ne rien faire (discutable )
    -B- Sinon
    ---1- Renvoyer la valeur stockée dans la cellule de tête de la liste
    ---2- Sauver la position de la cellule suivant la cellule de tête
    ---3- Détruire la cellule de tête
    ---4- La nouvelle tête de liste est celle dont on a sauvé la position

    B4 modifie la tête de liste, donc on doit avoir l'adresse de la liste pour opérer cette modification. Le prototype de la fonction doit être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void defiler_l_int(Liste * l,int * x)
    En ne s'occupant pas (pour l'instant) de l'étape A, on a alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void defiler_l_int(Liste * l,int * x)
    {
      Maillon suivant;
      //si la liste n'est pas vide :
      *x = l->tete->val;
      suivant = l->tete->suiv;
      free(l->tete);
      l->tete = suivant;
    }
    L'étape A est discutable, car comment savoir que la valeur obtenue (normalement retournée par *x) n'est pas n'importe quoi ce qui serait le cas si la liste était vide. On sera donc amené de toute façon à tester si la liste est vide avant l'appel de la fonction ou à tester si la valeur retournée est valide après l'appel à cette fonction (qui alors doit retourner un indicateur)
    Dans cette dernière option,le prototype serait
    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
    int defiler_l_int(Liste * l,int * x)
    {
      Maillon * suivant;
      if(l==NULL || l->tete==NULL) return 0;
      *x = l->tete->val;
      suivant = l->tete->suiv;
      free(l->tete);
      l->tete = suivant;
      return 1;
    } 
    //------------------------
       Liste liste = {NULL};
       int x;
      //.... Ajouter des éléments à la liste
       while(defiler_l_int(&liste, &x))
       {
          printf("%d \n",x);
       }

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Je confirme, le typedef chainon *liste; est une horreur qui cause bien plus de problèmes qu'elle n'en résout. La méthode de diogene, avec une structure pour le chaînon et une pour la liste, est bien plus compréhensible.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut
    J'ai essayé avec ça
    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
     
    #include<stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <windows.h>
    typedef struct elt
    {
        int val ;
        struct elt *suiv ;
    }Maillon;
     
     
    typedef struct
    {
       Maillon * tete;
    } Liste;
     
     
    int defiler_l_int(Liste * l,int * x)
    {
      Maillon * suivant;
      if(l==NULL || l->tete==NULL) return 0;
      *x = l->tete->val;
      suivant = l->tete->suiv;
      free(l->tete);
      l->tete = suivant;
      return 1;
    }
    //------------------------
     
     
    main()
    {   Liste l = {NULL},p;
    p=(Liste) malloc(sizeof(struct Liste));
        p->tete->val=6;
       int x;
      //.... Ajouter des éléments à la liste
       while(defiler_l_int(&l, &x))
       {
          printf("%d \n",x);
       }
        getch();
        }
    et il y a des problémes:
    invalid application of `sizeof' to incomplete type `Liste' |
    conversion to non-scalar type requested|
    invalid type argument of `->'|
    au niveau de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    p=(Liste) malloc(sizeof(struct Liste));

  11. #11
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut
    @imperio : ok, je veux supprimer à chaque fois le nœud d’où j'ai récupéré la valeur, donc si je récupère toutes la valeurs la liste sera NULL.
    mais dans ce code aussi ça m'affiche que :
    `suiv' has not been declared 
    pour: et que
    `val' has not been declared 
    pour:
    et que
    `suivl' has not been declared 
    pour:@Obsidian : Que ce que je dois faire!

Discussions similaires

  1. Réponses: 19
    Dernier message: 09/06/2006, 10h03
  2. Problème de passage de paramètres à une procedure
    Par momo62 dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 22/12/2005, 15h22
  3. [template] problème de passage de paramètres
    Par vinny_the_true dans le forum C++
    Réponses: 2
    Dernier message: 14/12/2005, 01h15
  4. Réponses: 9
    Dernier message: 13/05/2005, 03h13
  5. problème de passage de paramêtre sous mozilla
    Par mat10000 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 27/09/2004, 10h48

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