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

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 29
    Points : 9
    Points
    9

    Par défaut Structure principale ?

    Bonjour à toutes et à tous.
    Dans ce code , j'ai l'impression que « struct humain » est la structure principale , et que « struct id » et « struct date » sont des sous-structures dans la mesure ou id et date sont déclarées dans celles-ci . Ai-je tort ou raison ? Si c'est le cas , les sous-structures doivent toujours être déclarées dans la structure principale ?

    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
    #include <stdio.h>
    #include <string.h>
     
     int main()
     {
        struct id
        {
          char hprenom[20]
          char hnomfam[20]
        };
        struct date
        {
          int sjour;
          int smois;
          int sannee;
        };
        struct humain
        {
          struct id hnom;
          struct date hdatenaiss;
        };
        struct humain president;
     
        strcpy(president.hnom.hprenom, "georges");
        strcpy(president.hnom.hnomfam, "whashington");
        president.hdatenaiss.sjour=22;
        president.hdatenaiss.smois=2;
        president.hdatenaiss.sannee=1732;
     
        printf("Naissance de %s le %d %d %d\n",
               president.hnom.hprenom,
               president.hnom.hnomfam,
               president.hdatenaiss.sjour,
               president.hdatenaiss.smois,
               president.hdatenaiss.sannee);
        return 0;
      }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    septembre 2007
    Messages
    7 168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2007
    Messages : 7 168
    Points : 22 855
    Points
    22 855

    Par défaut

    Bonjour et bienvenue,

    Il n'y a pas, à proprement parler, de « structure principale » et de « sous-structures » en C. Elles sont toutes a priori définies au même niveau, même s'il est tout-à-fait autorisé d'y intégrer des membres dont le type soit lui-même une structure, auquel cas ladite structure doit être définie avant, naturellement. Donc, il est normal de voir définies d'abord struct date et struct id si on souhaite les utiliser dans struct humain.

    Une subtilité toutefois : la définition d'une structure vaut déclaration de type et à ce titre, elle peut avoir lieu au sein d'une autre définition de structure même si, au final, elles occuperont toutes deux le même niveau au sein du namespace. Par exemple :

    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
    #include <stdio.h>
     
    struct A
    {
        int                               x;
        int                               y;
        int                               z;
        struct B { int i; int j; int k; } b;
    };
     
    int main (void)
    {
        struct A alpha;
        struct B beta;
     
        alpha.x = beta.i = 1;
        printf ("%d %d\n",alpha.x,beta.i);
     
        return 0;
    }

    Dans cet exemple, parfaitement valide au demeurant (sauf erreur), l'intégralité de la chaîne struct B { int i; int j; int k; } est considéré comme un identifiant de type, au même titre que int et a donc parfaitement sa place là où on en attend un, même si c'est pendant la définition d'une structure, et on en profite au passage pour déclarer le membre « b ». En revanche, une fois que c'est fait, le nom de cette structure est bien « B » (appelé grâce à struct B) et pas A.B. Ceci se voit au niveau de la déclaration de alpha et beta dans la fonction principale.

    C'est notoirement différent des classes C++ qui font automatiquement office de namespace en plus du reste, et surtout de Java, avec lequel tout doit être défini au sein d'une classe.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 29
    Points : 9
    Points
    9

    Par défaut

    Merci de ta reponse . Bien compris , du moins pour le 1 er paragraphe ! Pour le reste je finirai par comprendre au fur et mesure de mon apprentissage et il y a encore du boulot ...

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 29
    Points : 9
    Points
    9

    Par défaut

    J'ai essayé ce code mais il ne fonctionne pas , pourquoi ? J'ai quand meme une petite idée , je me disais qu'il n'etait pas possible d' utiliser 2 structures avec des tableaux char dans chacune d'elle . Pourtant le nom des menbres est différent .... mais peut etre que l'erreur est ailleurs .

    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 <stdio.h>
      #include <string.h>
     
      int main()
      {
        struct nom
        {
           char prenom[20]
           char nomFamille[20]
        };
        struct date
        {
           int jour;
           int mois;
           int an;
        };
        struct lieu
        {
           char art[20]
           char nouvelle[20]
        };
        struct human
        {
          struct nom hnom;
          struct date hdate;
          struct lieu hlieu;
        };
        struct human perl;
     
        strcpy(perl.hnom.prenom, "perlanti");
        strcpy(perl.hnom.nomFamille, "hatayan");
     
     
        printf("%s %s", perl.hnom.prenom,
                        perl.hnom.nomFamille);
     
      return 0; 
      }

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 278
    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 : 7 278
    Points : 20 734
    Points
    20 734
    Billets dans le blog
    1

    Par défaut

    Bonjour
    Citation Envoyé par chris7522 Voir le message
    J'ai essayé ce code mais il ne fonctionne pas , pourquoi ?
    Pourquoi tu ne lis pas les messages du compilateur ? Chaque message te donne la ligne en erreur et la cause possible de l'erreur.
    Bon parfois il y a énormément de messages mais en réalité, bien souvent la première erreur décale le compilateur et il t'en ressort 500000 alors qu'il n'y en a en réalité qu'une seule.
    Donc tout ce que tu as à faire, c'est te concentrer sur le premier message d'erreur qui te donne la ligne incriminée, la corriger et recompiler. Ca marche pas forcément tout le temps immédiatement (ici il y a par exemple 4 erreurs donc si tu appliques cette méthode tu compileras 4 fois avant d'avoir tout réglé) mais ça évite quand-même beaucoup de recherche inutile.

    Citation Envoyé par chris7522 Voir le message
    mais peut etre que l'erreur est ailleurs .
    Exact. Les point-virgules manquants dans tes déclarations.

    Et il est maintenant temps que tu apprennes les bonnes pratiques. Une structure doit se nommer "struct s_xxx". C'est une question de convention mais ça te permet de garder le vocable "xxx" libre pour le donner à une variable.
    Ensuite il est préférable de définir les structures de façon globale afin qu'elles soient connues de tout le programme (attention, je ne dis pas de créer de variables globales !!!).
    Donc tu définis ta structure au début du code, puis dans les fonctions tu déclares tes variables du type de la structure en question.

    Autre chose: ne néglige pas l'indentation. Ici ton code c'est l'anarchie (2 espaces vides pour rien à chaque ligne, un return décalé par rapport au reste). Non. Un code proprement écrit c'est un code qu'on lit bien, qu'on relit encore mieux et qu'on fait évoluer encore plus mieux. Tu commences en début de ligne. Et chaque nouveau bloc sera augmenté d'un seul niveau à l'ouverture et diminué d'un niveau à la fermeture. Ainsi, si à la fin de ta fonction, l'accolade fnale n'est pas en début de ligne c'est que tu te seras vautré.

    Tout ça donne par exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct s_nom {
    	char prenom[20];
    	char nomFamille[20];
    };
     
    int main() {
    	struct s_nom nom;
    	...
    }

    Et si devoir mettre "struct" à chaque fois te fais un peu chier (ce que je trouve tout à fait normal car il n'y a aucune honte à vouloir éviter les trucs inutiles), alors rien ne t'interdit de transformer ta structure en type
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct {
    	char prenom[20];
    	char nomFamille[20];
    } t_nom;
     
    int main() {
    	t_nom nom;
    	...
    }
    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

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 29
    Points : 9
    Points
    9

    Par défaut

    Milles merci ! C'est vraiment généreux de ta part d'avoir prit le temps de m'expliquer tout ca !

  7. #7
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    2 927
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 2 927
    Points : 6 488
    Points
    6 488

    Par défaut

    Pour les termes techniques cela s'appelle de la composition ou de l’agrégation (cela va dépendre si la structure human prend en charge ou pas la création et la destruction des structures qui l'a compose)
    En UML c'est le losange (plein ou vide).
    Et c'est une relation moins forte d'appartenance que l'héritage (qui n'existe pas en C, mais qu'on peut simuler assez simplement)


    Citation Envoyé par Sve@r Voir le message
    Ensuite il est préférable de définir les structures de façon globale afin qu'elles soient connues de tout le programme (attention, je ne dis pas de créer de variables globales !!!).
    Bof

    Le premier truc , c'est d'isoler les structures dans des fichiers, pour avoir au moins 1 constructeur et 1 destructeur et éventuellement une remise à zéro, méthodes qui accompagnent toujours une structure/ classe.
    Et par la suite d'étoffer.

    Si tu as des structures, style des DTOs, (Data Transfer Object, <- lien wiki), comme les 2 structures de @chris7522, moi je les regroupe par thématique.

    Tout cela fait parti de l'organisation fichiers/ dossiers de son projet.

    Et ensuite si tu ne maîtrises pas tes inclusions, cela va devenir vite la chienlit . Dans le cas de @chris7522, l'utilisateur a juste besoin de la structure human. Et c'est cette dernière qui va inclure tout ce qu'elle a besoin (dont 2 autres structures)

    Après je sais très bien que pour un exemple à l'arrache et/ ou qui est posté sur un fil de discussion, c'est plus simple/ rapide d'avoir qu'1 seul source.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 278
    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 : 7 278
    Points : 20 734
    Points
    20 734
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par foetus Voir le message
    Bof
    Ah bon ? Toi tes structures tu les déclares dans les fonctions ? Oui effectivement si la fonction a besoin pour son travail local s'une structure précise et limitée je veux bien mais là je parlais de structures plus générales qui servent alors dans tout le code. Ici il semble assez probable que les structures montrées vont servir à un truc style jeu de rôle qui s'étalera dans plein de fonctions. Il sera alors peut-être utile que ces fonctions connaissent le type en question (tout comme elles connaissent l'int, le double et autres types natifs)...

    Citation Envoyé par foetus Voir le message
    au moins 1 constructeur et 1 destructeur... méthodes qui accompagnent toujours une structure/ classe.
    "constucteur", "destructeur", "méthodes", "classes"... Des notions associées à l'objet et qui n'existent pas en C. Je ne dis pas qu'on ne peut pas les émuler (après-tout, certains langages "objet" sont écrit en C) mais c'est peut-être un peu tôt pour un débutant non ?

    Citation Envoyé par foetus Voir le message
    Dans le cas de @chris7522, l'utilisateur a juste besoin de la structure human. Et c'est cette dernière qui va inclure tout ce qu'elle a besoin (dont 2 autres structures)
    Oui dans cet exemple certes, si on est sûr que les stuctures interne resteront à tout jamais défiitivement interne, elles peuvent alors être déclarées en live dans la structure principale. Quitte à les ressortir si demain ça change (comme ce qui arrive si souvent dans beaucoup de programmes sensés être pourtant bien définis )
    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

  9. #9
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    2 927
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 2 927
    Points : 6 488
    Points
    6 488

    Par défaut

    Citation Envoyé par Sve@r Voir le message
    Ah bon ? Toi tes structures tu les déclares dans les fonctions ???
    Tu n'as pas compris mes propos C'est le global qui me gène : du genre on met tout en extern - c'est "open bar"

    Moi je dis qu'il faut découper son code et répartir ses structures (et les méthodes qui les accompagnent) avec méthode - par exemple, chaque structure (sauf DTOs) a son fichier .h/ .c
    Et ainsi, pouvoir gérer l'arbre d'inclusion parce que certains #include ce n'est pas à toi de les faire.

    Alors oui, quelque part, tout est global, mais en apparence c'est propre et rangé


    Pour, les énumérations/ structures imbriquées j'évite ... même si j'adore cela (toujours dans cette optique de rangement).
    J'évite parce que (bon c'était en C++) certains compilateurs sont assez teubés et ils exigent de tout surspécifier de partout, et notamment à l'intérieur de la classe qui contient les énumérations/ structures (<- Je ne parle pas de gcc)


    Citation Envoyé par Sve@r Voir le message
    "constucteur", "destructeur", "méthodes", "classes"... Des notions associées à l'objet et qui n'existent pas en C. Je ne dis pas qu'on ne peut pas les émuler (après-tout, certains langages "objet" sont écrit en C) mais c'est peut-être un peu tôt pour un débutant non ?
    C'est de la sémantique ... de la sémantique précise

    Une méthode c'est une fonction liée à une classe/ structure
    Un constucteur c'est une fonction qui initialise l'objet (en C je pense qu'on dit l'init)
    Un destructeur c'est une fonction qui détruit l'objet

    Après, j'organise mon code (source, fichiers, dossiers) pour que cela ressemble à de l'objet, mais c'est du bon vieux C. Rien qui ressemble au code qui simule la POO en C

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 278
    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 : 7 278
    Points : 20 734
    Points
    20 734
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par foetus Voir le message
    Tu n'as pas compris mes propos C'est le global qui me gène
    C'est pour ça que j'ai bien précisé que je ne parlais pas de variable globale (je sais que c'est le mal).
    D'où mon exemple où je déclares un type qui, tel l'int ou le double, sera disponible de partout... puis où je définis une variable de ce type mais qui reste bien proprement locale à la fonction main().
    Citation Envoyé par foetus Voir le message
    du genre on met tout en extern - c'est "open bar"
    Ben surtout qu'une variable qui est extern de partout n'existe donc en réalité nulle part. Et à l'édition des liens ben l'open bar il se ferme de suite...
    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

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 29
    Points : 9
    Points
    9

    Par défaut

    J'ai éssayé de mettre un peu d'ordre dans mon bordel en suivant tes conseils , on doit pourtant pouvoir faire mieux que ca , non ?

    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
    #include <stdio.h>
    #include <string.h>
     
    int main()
    {
     struct s_nom
     {
      char prenom[20];
      char nom[20];
     };
     struct s_date
     {
      int jour;
      int mois;
      int an;
     };
     struct s_lieu
     {
      char lieu1[20];
      char lieu2[20];
     };
     struct s_human
     {
      struct s_nom hnom;
      struct s_date hdate;
      struct s_lieu hlieu;
     };
     struct s_human lauralee;
     
      strcpy(lauralee.hnom.prenom, "lauralee");
      strcpy(lauralee.hnom.nom, "berthelot");
      lauralee.hdate.jour=9;
      lauralee.hdate.mois=2;
      lauralee.hdate.an=1998;
      strcpy(lauralee.hlieu.lieu1, "paris");
      strcpy(lauralee.hlieu.lieu2, "vincennes");
     
      printf("%s %s est né le %d %d %d,a vécu a %s puis a %s\n",
             lauralee.hnom.prenom,
             lauralee.hnom.nom,
             lauralee.hdate.jour,
             lauralee.hdate.mois,
             lauralee.hdate.an,
             lauralee.hlieu.lieu1,
             lauralee.hlieu.lieu2);
    return 0;
    }

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 278
    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 : 7 278
    Points : 20 734
    Points
    20 734
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par chris7522 Voir le message
    on doit pourtant pouvoir faire mieux que ca , non ?
    Pas beaucoup.
    Bon déjà comme l'a dit foetus, si les structures internes ne sont utiles que pour la structure "s_human", alors tu as le droit de les écrire en live
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct s_human {
    	struct {
    		char nom[20];
    		char prenom[20];
    	} h_nom;
    	...
    };

    Ensuite le nom d'une variable ne doit pas être associé à son contenu. Si je veux stocker un nombre, j'écrirai int nb, pas int nb_20 parce que ça limite mon nombre et s'il contient autre chose que "20" j'aurai franchement l'air un peu con avec mon "nb_20". Pareil pour toi. Tu veux gérer des humains en général, pas forcément gérer tout le temps "Lauralee"...

    Et enfin il reste un décalage d'alignement vertical entre la ligne 28 et la ligne 30.
    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

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 29
    Points : 9
    Points
    9

    Par défaut

    Ok ca marche . Merci

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

Discussions similaires

  1. recuperation de la structure d'une base
    Par pascalT dans le forum 4D
    Réponses: 7
    Dernier message: 07/06/2006, 15h32
  2. Structure de données de type "RECORD"
    Par chaours dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/09/2002, 17h10
  3. Fenêtre principale et secondaire
    Par FranT dans le forum Composants VCL
    Réponses: 9
    Dernier message: 31/07/2002, 19h25
  4. Form principale non visible au demarrage!!!!
    Par toufou dans le forum Composants VCL
    Réponses: 2
    Dernier message: 20/07/2002, 21h49
  5. longueur d'une structure
    Par bohemianvirtual dans le forum C
    Réponses: 6
    Dernier message: 28/05/2002, 18h31

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