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 :

Genericité en C


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut Genericité en C
    Bonjour a tous, j'aimerais faire une liste générique, mais j'ai un peu de mal...
    Je voudrais instancier cette liste generique en liste de caractere.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typedef struct t_Liste{
       void * Ptr_val;         // pointeur sur un type de valeur desire
       struct t_Liste* Suiv; // pointeur sur element suivant
    } t_Liste;
    J'ai une fonction ajouter_fin, qui ajoute un element en fin de liste:
    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
     
     /* ajoute un pointeur sur valeur en fin de liste*/
     int Ajouter_fin(t_Liste * L, void * Ptr_valeur)
     {
       t_Liste * temp;
       // attribuer de l'espace
       temp=(t_Liste*)malloc(sizeof(struct t_Liste));
     
     if (L == NULL) /* si liste vide*/
       {
         L=temp;
         L->Ptr_val = Ptr_valeur; //pointer valeur
         L->Suiv = NULL; //fin de liste
       }
       else
       {
         temp=L;
         while (temp->Suiv != NULL) {
             temp=temp->Suiv;
         }
         /*on est arrive a la fin de la liste*/
         temp->Ptr_val=Ptr_valeur;
         temp->Suiv=NULL;
       }
       return 0;
     }
    et mon main:
    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
     
    int main()
    {
     
        struct t_Liste * Liste_char;
        Liste_char = (t_Liste*)malloc(sizeof(struct t_Liste));
        Liste_char = NULL;
        char vide; //pour vider le saut ligne du buffer
        char * c;
        c=(char *)malloc(sizeof(char));
     
        printf("Taper le caractere a ajouter: \n");
        *c=getchar();
        while (*c != '0') {
          vide=getchar();
          Ajouter_fin(Liste_char,c);
          c=(char *)malloc(sizeof(char));
          printf("Taper le caractere a ajouter: \n");
          *c=getchar();      
        }
     
        printf("debut: %p\n",Liste_char->Ptr_val);
        printf("Affichage de la liste\n");
        Afficher_liste(Liste_char);
        system("pause");    
    }
    Les soucis: - ma liste est toujours vide!
    - afficher un type donné (ici caractere) alors que en generique j'ai <void * ptr_val> comme valeur de l'element de la liste?

    Si quelqu'un peut m'aider svp ? D'avance merci !
    a bientot

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 16
    Par défaut
    En fait c'est normal,

    Voila la signature de ta fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     int Ajouter_fin(t_Liste * L, void * Ptr_valeur);
    <L> est un pointeur et est recopié lors de l'appel de fonction, en conséquence quand dans ta fonction tu ecrit :
    <L> est modifié dans la fonction mais la valeur de <Liste_Char> (passée par copie) n'est pas modifié dans ton main,

    Deux solutions s'offrent à toi :
    --> Retourner un pointeur sur la tete de la liste dans ta fonction <Ajouter_Fin>
    --> Passer l'addresse du pointeur sur la tete de la liste à ta fonction <Ajouter_Fin>

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    merci beaucoup de ta réponse

    Il faut donc que je passe en parametre un pointeur de pointeur ?

    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
     
    /* ajoute un pointeur sur valeur en fin de liste*/
     int Ajouter_fin(t_Liste ** L, void * Ptr_valeur)
     {
       t_Liste * temp;
       // attribuer de l'espace
       temp=(t_Liste*)malloc(sizeof(struct t_Liste));
     
     if (*L == NULL) /* si liste vide*/
       {
         *L=temp;
         *L->Ptr_val = Ptr_valeur; //pointer valeur
         *L->Suiv = NULL; //fin de liste
       }
       else
       {
         temp=*L;
         while (temp->Suiv != NULL) {
             temp=temp->Suiv;
         }
         /*on est arrive a la fin de la liste*/
         temp->Ptr_val=Ptr_valeur;
         temp->Suiv=NULL;
       }
       return 0;
     }
    Quelque chose comme ca ?
    Merci

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dr_octopus74 Voir le message
    Il faut donc que je passe en parametre un pointeur de pointeur ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    /* ajoute un pointeur sur valeur en fin de liste*/
     int Ajouter_fin(t_Liste ** L, void * Ptr_valeur)
     {
    Quelque chose comme ca ?
    Oui, ou en retournant l'adresse...

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

  5. #5
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    j'ai essayé, mais ca compile pas, il ne comprend pas les accès au structures <*L->Ptr_val = Ptr_valeur> et <*L->Suiv = NULL>
    Pourtant j'accède bien au contenu d'un pointeur de pointeur, donc au pointeur...

  6. #6
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         (*L)->Ptr_val = Ptr_valeur; //pointer valeur
         (*L)->Suiv = NULL; //fin de liste
    sinon, c'est interprété comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         *(L->Ptr_val) = Ptr_valeur; //pointer valeur
         *(L->Suiv) = NULL; //fin de liste

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par diogene Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         (*L)->Ptr_val = Ptr_valeur; //pointer valeur
         (*L)->Suiv = NULL; //fin de liste
    C'est pour éviter ce genre de code gore que je recommande
    • soit de retourner la valeur :
      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
       
      #include <stdlib.h>
       
      typedef struct t_Liste
      {
         void *Ptr_val;               /* pointeur sur un type de valeur desire */
         struct t_Liste *Suiv;        /* pointeur sur element suivant */
      }
      t_Liste;
       
      /* ajoute un pointeur sur valeur en fin de liste*/
      t_Liste *Ajouter_fin (t_Liste * L, void *Ptr_valeur)
      {
         t_Liste *new = malloc (sizeof *new);
       
         if (new != NULL)
         {
            new->Ptr_val = Ptr_valeur;   /* pointer valeur */
            new->Suiv = NULL;            /* fin de liste */
            if (L == NULL)               /* si liste vide */
            {
               L = new;
            }
            else
            {
               t_Liste *temp = L;
               while (temp->Suiv != NULL)
               {
                  temp = temp->Suiv;
               }
               /*on est arrive a la fin de la liste */
               temp->Suiv = new;
            }
         }
         return L;
      }
    • soit d'utiliser une structure 'liste'
      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
       
      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>
       
      typedef struct node
      {
         void *Ptr_val;               /* pointeur sur un type de valeur desire */
         struct node *Suiv;           /* pointeur sur element suivant */
      }
      node_s;
       
      typedef struct
      {
         node_s *head;
         node_s *tail;
      }
      list_s;
       
      /* ajoute un pointeur sur valeur en fin de liste*/
      int Ajouter_fin (list_s * L, void *Ptr_valeur)
      {
         int err = 1;
         node_s *new = malloc (sizeof *new);
       
         if (new != NULL)
         {
            new->Ptr_val = Ptr_valeur; /* pointer valeur */
            new->Suiv = NULL;         /* fin de liste */
            if (L->head == NULL)      /* si liste vide */
            {
               L->head = new;
            }
            else
            {
               L->tail->Suiv = new;
            }
            L->tail = new;
            err = 0;
         }
       
         return err;
      }
       
      void aff (list_s * L)
      {
         node_s *p = L->head;
       
         if (p != NULL)
         {
            do
            {
               printf ("'%s'\n", (char *) p->Ptr_val);
               p = p->Suiv;
            }
            while (p != NULL);
         }
         else
         {
            puts ("VIDE");
         }
      }
       
      int main (void)
      {
         list_s list = { NULL, NULL };
       
         int err;
       
         err = Ajouter_fin (&list, strdup ("Hello"));
         if (!err)
         {
            err = Ajouter_fin (&list, strdup ("World"));
            if (!err)
            {
               aff (&list);
            }
         }
       
         return 0;
      }
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
       
      'Hello'
      'World'
       
      Press ENTER to continue.

    Nota : j'ai corrigé l'algorithme qui était gravement erroné... Je te laisse écrire le code de libération de la mémoire...

    http://emmanuel-delahaye.developpez....s_chainees.htm

  8. #8
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    ok merci beaucoup ca marche !
    par contre je n'arrive pas a afficher le contenu de chaque element de ma liste
    ca m'affiche des "element: 400128", "element: 400160", ce qui devrait etre l'adresse du pointeur sans doute ?

    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
     
    /* ajoute un pointeur sur valeur en fin de liste*/
    t_Liste * Ajouter_fin(t_Liste * io_L, void * Ptr_valeur)
    { 
      t_Liste * nouveau;
      t_Liste * ptcourant; 
      // attribuer de l'espace
      nouveau=(t_Liste*)malloc(sizeof(struct t_Liste));
     
      if (io_L == NULL)
      {
        io_L=nouveau;
        io_L->Ptr_val = Ptr_valeur; //pointer valeur
        io_L->Suiv = NULL; //fin de liste
      }
      else
      { 
        ptcourant=io_L;
        while (ptcourant->Suiv != NULL) {
          ptcourant=ptcourant->Suiv;
        }
        /*on est arrive a la fin de la liste*/
        ptcourant->Suiv=nouveau;
        nouveau->Ptr_val=Ptr_valeur;
        nouveau->Suiv=NULL;
      }
      printf("element: %d\n",nouveau->Ptr_val);
      return io_L;
    }
    Mon affichage est a l'avant derniere ligne de ma fonction d'ajout.En gros je ne sais pas comment faire pour afficher un void * (ici de type caractere).
    merci d'avance

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dr_octopus74 Voir le message
    Mon affichage est a l'avant derniere ligne de ma fonction d'ajout.En gros je ne sais pas comment faire pour afficher un void * (ici de type caractere).
    merci d'avance
    Tu affiches une chaine avec un type "%d" ?

    Relis mon code... Ton code est inutilement compliqué...

Discussions similaires

  1. [Axis][Java1.5] gestion de la généricité
    Par nezdeboeuf62 dans le forum Services Web
    Réponses: 1
    Dernier message: 01/08/2007, 09h22
  2. probleme genericité 1.5
    Par decksroy dans le forum Langage
    Réponses: 2
    Dernier message: 01/03/2007, 09h31
  3. Réponses: 2
    Dernier message: 20/09/2006, 13h20
  4. [Debutant]Généricité & Héritage
    Par Drannor dans le forum Débuter
    Réponses: 21
    Dernier message: 17/09/2006, 17h07
  5. [UML][?Poseidon] Genericité
    Par TabrisLeFol dans le forum Outils
    Réponses: 2
    Dernier message: 10/03/2006, 18h24

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