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 :

Pointeurs et structures... [Débutant(e)]


Sujet :

C

  1. #1
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut Pointeurs et structures...
    Hello,
    Voila mon problème:
    Je souhaite modéliser un groupe de personne auquel on peu ajouter/enlever etc... dynamiquement des individus.
    Pouir cela, j'ai crée deux structure:
    - une pour les individus qui contiendra des attributs standarts...
    - une pour le groupe, elle contient un pointeur de type individu qui servira de tableau dynamique pour les individus.

    Je souhaite ensuite ajouter les methodes standards... tout ca est résumé dans mon code ci-dessous:

    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
     
     
    #include <windows.h>
    #include <stdio.h>
     
    typedef struct individu {
                   char* nom;
            } individu ;
     
    typedef struct groupe{
                   int nbPers ;
                   individu *indivs ; // Pointeur = tableau d'individus
            } groupe ;
     
    individu* creerIndividu () {
         individu *indiv ;
         indiv = calloc(1, sizeof(individu)) ;
         return indiv ;             
    }
     
    groupe* creerGroupe(int nbPers) {
         groupe* gp ; // Pointeur sur le nouveau groupe
         gp = malloc(sizeof(groupe)); // Allocation de mémoire pour le groupe
         (*gp ).indivs = malloc(nbPers* sizeof(individu)) ; // Allocation de mémoire pour les individus
     
         int i ;
         for(i = 0 ; i < nbPers; i++) {
               gp->(indivs+i) = creerIndividu() ; //pb a la compilation
         }
     
         return gp ; 
    }
     
    int main(void) {
        int nbIndiv= 5 ;
        groupe *gp ;
        gp = creerGroupe(nbIndiv) ;
    }
    A la compilation, j'ai le droit a une syntax error au niveau de l'instruction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gp->(indivs+i) = creerIndividu()
    Quelqu'un voit il l'erreur? C'est surement au niveau des pointeurs, je ne maitrise pas encore bien... mais j'ai beau chercher je ne trouve pas de solutiosn.

    Merci d'avance.

  2. #2
    Membre habitué
    Inscrit en
    Novembre 2002
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 120
    Points : 125
    Points
    125
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gp->(indivs+i) = creerIndividu() ; //pb a la compilation
    C'est un peu normal du reste. Tu voulais peut-être dire *(gp->indivs + i) = creerIndividu()? Mais comme c'est un peu lourd on préfère utiliser gp->indivs[i] = creerIndividu().

  3. #3
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    ben non si je fais ca il me dit: "incompatible types assignment"...
    Ma méthode creeIndividu() renvoi un pointeur, dc une adresse, donc je suppose que c'est pr ca... gp->indivs[i] c'est pas un pointeur

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Il me semble que dans ce cas là, CreerIndividu ne doit pas renvoyer un pointeur mais bien un Individu.

    Puisque gp->indiv[i] désigne un individu et non un pointeur sur un individu.

    EDIT : Pas lu ce que tu as écrit avant. En effet tu possédes déja un tableau d'individu. Tu peux à la rigeur dans CreerIndividu allouer la mémoire pour le champs nom de ta structure Individu
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  5. #5
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    En effet ca marche si on renvoi un individu.
    Seulement dans le tableau je voudrai avoir des pointeurs sur des individus et non des individus (pour pouvoir les modifier ensuite)... C'est pourquoi ma fonction creerIndividu renvoi un pointeur.
    En fait j'ai trouvé la solution, il faut que ma structure groupe soit comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct groupe{
                   int nbPers ;
                   individu **indivs ; // Pointeur = tableau de pointeurs sur les individis
            } groupe ;
    Seulement maintenant je n'arrive pas à accéder aux individus a partir d'un groupe...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    void afficherIndividu(individu indiv) {...}
     
    void afficherGroupe(groupe gp) {
         int i ;
         for (i=0 ; i < gp.nbPers ; i++){
             afficherIndividu(gp.(*(indivs[i])) ;   // Syntax error
         }     
    }
    J'ai la même erreur que tout a l'heure: syntax error...

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Il sort d'ou pop ? Bob ?
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  7. #7
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    lol dsl erreur de frappe c'est modifié

  8. #8
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Il te manque une parenthése fermante ')'
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  9. #9
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    oui, mais ca ne marche pas quand même de cette manière... La syntaxe du C ne le permet pas apparament ou alors c'est moi.
    En tout cas je vien juste de trouver la solution: il fait déclarer un pointeur pour récupérer les éléments du tableau (les pointeurs)...
    Ca donne ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (i=0 ; i  < gp.nbPers ; i++){
             individu *indiv = gp.indivs[i] ; // On récup le pointeur sur l'individu i
             afficherIndividu(*indiv) ;   // On affiche l'individu 
    }

  10. #10
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    EDIT : j'ai dis une connerie
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  11. #11
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    Ma fonction afficherIndividu attend un individu, non un pointeur sur un individu, comme c'est décrit plus haut (juste au dessu de la fonction afficherGroupe).
    Et selon ma structure groupe: (voir plus haut également, indivs est un tableau de pointeurs)
    renvoi un pointeur sur l'individu i, et non l'individu i, ce qui veu dire que cette instruction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    afficherIndividu(gp.indivs[i]); // Ici on envoi un pointeur a la fonction
    n'est pas équivalente à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    individu *indiv = gp.indivs[i] ;  
    afficherIndividu(*indiv) ; // Ici on envoi bien un individu
    Désolé si tout cela n'a peut etre pas été trés clair, mais je ne maitrise pas encore trés bien les pointeurs, et c'est pourquoi tu as du avoir l'impression que je voulai passer un pointeur, puis un individu a la fonction, alors que j'ai toujours voulu passe un individu

  12. #12
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Il faut faire attention à ce que tu fais:

    - Lorsque tu passes une structure à une fonction, il y a une copie superficielle de la structure (toutes les valeurs statiquement déclarées donc les valeurs des pointeurs mais pas les valeurs pointées)

    Cela a deux conséquences:

    - Lors de la modification de la structure, cela revient à modifier un paramétre de la fonction, la structure qui a été passée en argument n'a pas été modifiée.

    - Il y a un coût pour passer des grosses structures dû au nombre de copie nécéssaire.


    En passant un pointeur, il n"y a plus ce genre de problème mais alors toute modification de la structure passée en argument modifie la structure qui a été passé en argument.

    Je pense que tu as compris la différence entre passé une structure et un pointeur de structure mais voilà un exemple de base.

    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    //Définition d'une structure avec un pointeur
    struct ptr
    { 
     int *p;
    };
     
    struct tab
    { 
     int t[10];
    };
     
    //Fonctions f prennent les structures en argument
    void fptr(struct ptr a)
    {
       a.p[0] = 1;   //On met 1 à la 1ere case
    }
     
    void ftab(struct tab a)
    {
       a.t[0] = 1;   //On met 1 à la 1ere case
    }
     
    //Fonctions g prennent les pointeurs de structure en argument
    void gptr(struct ptr *a)
    {
       a->p[0] = 2;   //On met 2 à la 1ere case
    }
     
    void gtab(struct tab *a)
    {
       a->t[0] = 2;   //On met 2 à la 1ere case
    }
     
    int main()
    {
      struct ptr a;
      struct tab b;
     
      b.t[0] = 0; //On met à 0
      a.p = malloc(sizeof(int));
     
      if(a.p==NULL)
        {
        printf("Allocation error in main\n");
        return EXIT_FAILURE;
        }
     
      a.p[0] = 0;  //On met à 0
     
      fptr(a);
      ftab(b);
     
      printf("Après f: %d %d\n",a.p[0],b.t[0]);  
     
      gptr(&a);
      gtab(&b);
      printf("Après g: %d %d\n",a.p[0],b.t[0]);  
     
      return EXIT_SUCCESS;
    }
    Qui affiche ceci:
    Après f: 1 0
    Après g: 2 2
    En résumé, si tu sais que tu ne vas pas modifier ta structure, passe le pointeur, cela sera plus rapide lors de multiples appels avec des grosses structures.

    Jc

  13. #13
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    oui merci de tesd explications supplémentaires j'ai bien compris la différence

  14. #14
    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 fearyourself
    - Lorsque tu passes une structure à une fonction, il y a une copie superficielle <...>
    Jolie expression.
    Pas de Wi-Fi à la maison : CPL

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/03/2007, 10h55
  2. Réponses: 60
    Dernier message: 13/02/2007, 19h53
  3. [C#]Pointeur vers structure
    Par torNAdE dans le forum Windows Forms
    Réponses: 3
    Dernier message: 08/05/2006, 19h43
  4. Réponses: 7
    Dernier message: 08/04/2006, 12h18
  5. probleme avec pointeurs de structures
    Par remi77 dans le forum C
    Réponses: 2
    Dernier message: 20/10/2003, 13h19

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