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 :

structures imbriqués fonctions


Sujet :

C

  1. #1
    Membre très actif
    Homme Profil pro
    touristepationné
    Inscrit en
    Janvier 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Janvier 2012
    Messages : 132
    Par défaut structures imbriqués fonctions
    Bonjour,

    Je voudrais accéder à une cellule d'une structure imbriqué dans une autre, grâce a une fonction. Comment faire?

    Voici mes structures:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    struct eleve
      {
        char nom[100];
        char prenom [100];
        int age;
      };
     
    struct nClass
    	{
    		char nom[5];
    		char maitresse [26];
    		struct eleve tableEleves [32];
    	};
    et voici ma fonction à modifer (initialement ecrite pour utiliser seulement la structure eleve):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Afficher_Eleve ( struct nClass param)
      {
      printf ("Nom = %-10.10s | ",param.nom);
      printf ("Prenom = %-10.10s | ",param.prenom);
      printf ("Age = %d\n",param.age);
      }
    Comment appeler dans mon main?

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 871
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par B65AcR Voir le message
    et voici ma fonction à modifer (initialement ecrite pour utiliser seulement la structure eleve):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Afficher_Eleve ( struct nClass param)
      {
      printf ("Nom = %-10.10s | ",param.nom);
      printf ("Prenom = %-10.10s | ",param.prenom);
      printf ("Age = %d\n",param.age);
      }
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void Afficher_Eleve ( struct nClass *param)
    {
      struct eleve *elv;
      size_t i;
      for (i=0, elv=param->tableEleves; i < 32; i++, elv++)
      {
          printf("Eleve %d\n", i+1);
          printf ("Nom = %-10.10s | ", elv->nom);
          printf ("Prenom = %-10.10s | ", elv->prenom);
          printf ("Age = %d\n", elv->age);
      }
    }
    Citation Envoyé par B65AcR Voir le message
    Comment appeler dans mon main?
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        struct nClass classe;
        Afficher_Eleve(&classe);
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre très actif
    Homme Profil pro
    touristepationné
    Inscrit en
    Janvier 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Janvier 2012
    Messages : 132
    Par défaut
    Super! Merci!

    Par contre je ne suis pas super a l'aise avec les pointeurs. Il n'y aura pas une autre solution avec un truc dans ce genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Afficher_Eleve ( struct nClass param[i])
      {
      printf ("Nom = %-10.10s | ",param[i].nom);
      printf ("Prenom = %-10.10s | ",param[i].prenom);
      printf ("Age = %d\n",param[i].age);
      }

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 871
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par B65AcR Voir le message
    Super! Merci!

    Par contre je ne suis pas super a l'aise avec les pointeurs.
    Hé ben il faut t'y mettre sérieusement. Ou alors abandonner le C...

    Citation Envoyé par B65AcR Voir le message
    Il n'y aura pas une autre solution avec un truc dans ce genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Afficher_Eleve ( struct nClass param[i])
      {
      printf ("Nom = %-10.10s | ",param[i].nom);
      printf ("Prenom = %-10.10s | ",param[i].prenom);
      printf ("Age = %d\n",param[i].age);
      }
    Ouais bon faut vraiment t'y mettre!!!

    Que reçoit la fonction ? L'adresse d'une structure (&classe). Elle stockera cette adresse dans un pointeur (*param). Ce pointeur pointe vers une structure classe => struct classe *param.

    Comment on accède aux membres d'une structure pointée ? Par le biais de la flèche -> (parce que la priorité des opérateurs impose, sinon, de taper (*param).membre ce qui devient vite chiant). Toi tu veux accéder à chaque élément "i" de ton tableau d'élèves => param->tabEleves[i].
    Une fois que tu as chaque élément "i", tu veux taper dans le nom et autres membres => param->tabEleves[i].nom.

    A partir de là, c'est fini, t'as tout ce qu'il faut. Tout ce que j'ai fait, moi, c'est de remplacer tabEleves[i] par un autre pointeur "elv" pour optimiser les accès. Et comme tabEleves[i].nom <=> *(elv + i).nom et que (*elv).nom <=> elv->nom alors tabEleves[i].nom <=> elv->nom. Mais si c'est trop ardu alors tu remplaces dans mon code elv->truc par param->tabEleves[i].truc. C'est méga plus long à s'exécuter (un déréférencement plus un index plus un autre déréférencement et ça à chaque printf) mais c'est pareil au niveau du résultat...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre très actif
    Homme Profil pro
    touristepationné
    Inscrit en
    Janvier 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Janvier 2012
    Messages : 132
    Par défaut
    Wow! Plus ardu, mais j'ai compris! Et c'est super interessant a lire quand tu es debutant.

    C'est quoi un déréférencement?

    A tout niveau il vaut mieux declarer un pointeur que d'écrire "param->tabEleves[i].truc" ?

    Il y a une ligne que je ne comprends absolument pas:
    ça veut dire quoi? size sort d'ou?

  6. #6
    Membre très actif
    Homme Profil pro
    touristepationné
    Inscrit en
    Janvier 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Janvier 2012
    Messages : 132
    Par défaut
    Sinon j'ai fait ç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
     
    # include<stdio.h>
    # include<string.h>
     
    struct eleve
      {
        char nom[100];
        char prenom [100];
        int age;
      };
     
    struct nClass
    	{
    		char nom[5];
    		char maitresse [26];
    		struct eleve tableEleves [32];
    	};
     
    void Afficher_Eleve ( struct nClass param,int i);
     
    main ()
    {
     
      struct eleve Moi = {"yop","la",1};
      struct nClass test;
     
     Afficher_Eleve (test,0);
     
    }
     
    void Afficher_Eleve ( struct nClass param, int i)
      {
      printf ("Nom = %-10.10s | ",param.tableEleves[i].nom);
      printf ("Prenom = %-10.10s | ",param.tableEleves[i].prenom);
      printf ("Age = %d\n",param.tableEleves[i].age);
      }
    Qu'en penses tu?

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 871
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par B65AcR Voir le message
    C'est quoi un déréférencement?
    C'est l'opération que fait le compilo pour atteindre l'élément tab[x] ou elem.elem.elem.data ou autres opérations similaires.
    Dans chaque cas il part du début de la zone puis se déplace du nombre d'octets voulus pour atteindre la cible demandée.
    Et ce genre d'opération est toujours super longue donc si t'as besoin de la faire plusieurs fois vaut mieux créer un pointeur intermédiaire...

    Citation Envoyé par B65AcR Voir le message
    A tout niveau il vaut mieux declarer un pointeur que d'écrire "param->tabEleves[i].truc" ?
    Uniquement si t'as besoin d'accéder plusieurs fois à tabEleves[i]...

    Citation Envoyé par B65AcR Voir le message
    Il y a une ligne que je ne comprends absolument pas:
    ça veut dire quoi? size sort d'ou?
    C'est un type rajouté dans la libC pour manipuler les index de tableaux. On peut le remplacer par short ou long ou, mieux unsigned short/long mais l'avantage du size_t c'est qu'il évolue avec le C...

    Citation Envoyé par B65AcR Voir le message
    Code c : 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
    # include<stdio.h>
    # include<string.h>
     
    struct eleve
      {
        char nom[100];
        char prenom [100];
        int age;
      };
     
    struct nClass
    	{
    		char nom[5];
    		char maitresse [26];
    		struct eleve tableEleves [32];
    	};
     
    void Afficher_Eleve ( struct nClass param,int i);
     
    main ()
    {
     
      struct eleve Moi = {"yop","la",1};
      struct nClass test;
     
     Afficher_Eleve (test,0);
     
    }
     
    void Afficher_Eleve ( struct nClass param, int i)
      {
      printf ("Nom = %-10.10s | ",param.tableEleves[i].nom);
      printf ("Prenom = %-10.10s | ",param.tableEleves[i].prenom);
      printf ("Age = %d\n",param.tableEleves[i].age);
      }
    Qu'en penses tu?
    Ta fonction d'affichage est correcte. Mon code affiche tout le tableau, la tienne n'affiche que l'élève x. Le fait de préférer l'une ou l'autre dépend de ton besoin.
    Toutefois faut quand-même recopier le contenu de "Moi" dans "test.tabEleves[0]" pour que l'exécution produise un résultat visible correct (pour un test rapide on peut utiliser memcpy mais pour une portabilité complète faut le faire membre par membre).

    Voici cependant un petit correctif indispensable

    Code c : 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
    void Afficher_Eleve ( struct nClass *param, size_t i)
    {
      printf ("Nom = %-10.10s | ",param->tableEleves[i].nom);
      printf ("Prenom = %-10.10s | ",param->tableEleves[i].prenom);
      printf ("Age = %d\n",param->tableEleves[i].age);
    }
    
    main ()
    {
      
      struct eleve Moi = {"yop","la",1};
      struct nClass test;
     
      // Recopie de Moi dans test.tabEleves[0]
      memcpy(&test.tabEleves[0], &Moi, sizeof (struct eleve));
       
      Afficher_Eleve (&test,0);
    }

    En effet, comme je l'ai dit, c'est plus rapide de passer l'adresse d'une structure que de passer la structure elle-même.
    Autre remarque: la fonction "afficher" n'utilisant que des éléments de tabEleves aurait pu se contenter de recevoir un pointeur sur ce membre (au lieu de recevoir un pointeur vers struct nClass). Mais telle qu'elle est cela ne pose pas de pb et permet ensuite de la faire évoluer plus facilement...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2013
    Messages : 2
    Par défaut
    Bonjour,
    Citation Envoyé par B65AcR Voir le message
    Super! Merci!

    Par contre je ne suis pas super a l'aise avec les pointeurs. Il n'y aura pas une autre solution avec un truc dans ce genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Afficher_Eleve ( struct nClass param[i])
      {
      printf ("Nom = %-10.10s | ",param[i].nom);
      printf ("Prenom = %-10.10s | ",param[i].prenom);
      printf ("Age = %d\n",param[i].age);
      }
    Généralement, lorsque le type de l'argument d'une fonction a une taille supérieure à celle des entiers, on le passe par pointeur.
    Ici les deux structures ont une taille plus grande que celle des entiers, c'est pour cette raison il a utilisé les pointeurs.

Discussions similaires

  1. Passage d'une structure en fonction
    Par god_enel dans le forum C
    Réponses: 11
    Dernier message: 15/04/2007, 21h55
  2. Problème de templates et de structures imbriqués
    Par digital_versatil dans le forum C++
    Réponses: 1
    Dernier message: 01/03/2007, 00h10
  3. structures et fonctions
    Par olivier1209 dans le forum C
    Réponses: 11
    Dernier message: 10/12/2006, 15h53
  4. Structure et fonction
    Par progfou dans le forum C
    Réponses: 7
    Dernier message: 04/07/2006, 15h23
  5. structures et fonctions
    Par kendras dans le forum C
    Réponses: 15
    Dernier message: 14/06/2006, 16h57

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