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 :

Utilité des structures anonymes


Sujet :

C

  1. #1
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut Utilité des structures anonymes
    Bonjour à tous

    Je viens de découvrir (hé oui, on en apprend tous les jours) les structures anonymes.

    Alors sur le principe j'ai bien compris comment on les crée et comment on les utilise. Ce que je ne comprends pas, en revanche, c'est leur utilité.

    Exemple: quel avantage à écrire ceci...
    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
    #include <stdio.h>
     
    struct person {
    	char   name[30];
    	char   gender;
    	int	age;
    	int	weight;
    	struct {
    		int  areacode;
    		long number;
    	};
    } Jim;
     
    int main() {
    	Jim.number=1234567;
    	printf("%ld\n", Jim.number);		//Output: 1234567
    }

    plutôt que cela...

    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
    #include <stdio.h>
     
    struct person {
    	char   name[30];
    	char   gender;
    	int	age;
    	int	weight;
    	int  areacode;
    	long number;
    } Jim;
     
    int main() {
    	Jim.number=1234567;
    	printf("%ld\n", Jim.number);		//Output: 1234567
    }

    Pour l'instant, le seul avantage que je vois c'est que la structure anonyme permet d'isoler visuellement les éléments un peu "à part" (ici le fait que areacode et number vont ensembles) mais ça me parait un peu léger comme utilité...

    Si vous avez des avis...

    Merci à tous de votre sympathique attention
    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]

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Salut,

    Les structures anonymes, ça ne sert pas à grand chose. C'est surement pour cela que ça n'existe pas. La norme ne définit que les unions anonymes mais la plupart des compilateurs tolèrent les structures anonymes.

    Elles peuvent avoir un intérêt dans les unions, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    union Point {
       struct {
          int  x;
          int  y;
          int  z;
       };
       int  coord[3];
    };
    On peut alors accéder aux coordonnées du Point par leur nom ou par leur index. J'utilise cela en C, mais en C++ c'est un undefined behavior d'écrire pt.x pour y lire pt.coord[0].

  3. #3
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Citation Envoyé par dalfab Voir le message
    C'est surement pour cela que ça n'existe pas. La norme ne définit que les unions anonymes mais la plupart des compilateurs tolèrent les structures anonymes.
    Ce n'est pas ce que dit la norme C11 6.7.2.1 alinea 13 et 19 ou les structures anonymes sont décrites.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Les structures anonymes, ça ne sert pas à grand chose. C'est surement pour cela que ça n'existe pas. La norme ne définit que les unions anonymes mais la plupart des compilateurs tolèrent les structures anonymes.
    Hum.... pour moi la structure anonyme c'est la structure interne. Et donc ce que tu as mis dans ton union c'est bel et bien une structure anonyme (enfin c'est comme ça que je le voyais).
    Ceci dit merci pour ton exemple très illustratif. Là je vois mieux l'utilité .
    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
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Dans ton code initial, j'irais à fond et écrirais carrément
    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
    #include <stdio.h>
     
    struct {
    	char   name[30];
    	char   gender;
    	int	age;
    	int	weight;
    	struct {
    		int  areacode;
    		long number;
    	};
    } Jim;
     
    int main() {
    	Jim.number=1234567;
    	printf("%ld\n", Jim.number);		//Output: 1234567
    }
    Pour moi, pour avoir utilisé ça quelques fois dans du code C++, l'utilité est moindre mais ça permet juste de définir une variable de type structure, sans définir la structure au préalable. Un genre de shortcut syntaxique dans le cas où tu utiliserais cette structure à un endroit unique.
    Ici je déclare Jim, sans me soucier que ce soit une Person.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    J'ai dû louper un épisode. N'existant pas en C++, je suis resté sur fait que les structures anonymes n'existait pas plus en C.
    Il me reste à relire le C17...

    Mon exemple n'est pas si mal finalement

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Dans ton code initial, j'irais à fond et écrirais carrément...
    ...mais ça permet juste de définir une variable de type structure, sans définir la structure au préalable. Un genre de shortcut syntaxique dans le cas où tu utiliserais cette structure à un endroit unique.
    Ici je déclare Jim, sans me soucier que ce soit une Person.
    Tout à fait. On peut aussi partir sur un typedef struct {...} t_truc ce que je fais assez souvent. Mais l'essence de la question portait plus sur l'utilité de la structure interne que sur l'utilité du nom de la structure externe.

    Citation Envoyé par dalfab Voir le message
    Mon exemple n'est pas si mal finalement
    Oui oui, j'ai beaucoup aimé
    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
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonjour,

    Citation Envoyé par Sve@r Voir le message
    Bonjour à tous

    Je viens de découvrir (hé oui, on en apprend tous les jours) les structures anonymes.
    Alors sur le principe j'ai bien compris comment on les crée et comment on les utilise. Ce que je ne comprends pas, en revanche, c'est leur utilité.
    Si vous avez des avis...
    L'utilisation de la structure anonyme en langage de programmation C présente certains avantages. Elle permet de regrouper des variables ensemble pour une utilisation locale sans avoir besoin de définir une variable structure globale supplémentaire. Cela facilite grandement l'organisation des données de manière claire et cohérente, évitant ainsi la création de structures nommées distinctes pour des utilisations locales. En limitant la portée des données au contexte où elles sont déclarées, les structures anonymes évitent les conflits de noms de variables et simplifient la manipulation de données complexes, tout en optimisant la gestion de la mémoire.

    Un exemple concret de l'utilisation d'une structure anonyme (exemple ci-dessous "attention le code source ci-dessous peut comporter des erreurs" ) pourrait être une structure contenant deux pointeurs, "back" et "next". Dans ce cas, l'utilisation d'une structure anonyme permet de ne pas augmenter la taille de la structure globale tout en améliorant considérablement la lisibilité du code et la facilité d'organisation des membres liés ensemble.

    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
    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
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
     
    #include <stdio.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stddef.h>
     
    struct pseudo_liste {
        unsigned int data;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        };
    };
     
    /* Pour le comparatif */
    struct pseudo_liste_2{
        unsigned int data;
        struct {
            struct pseudo_liste_2 *back;
            struct pseudo_liste_2 *next;
        };
    };
     
     
     
     
    void printStructSizeAndOffsets(){
     
        (void)fprintf(stdout,"Infos debug comparatif structure 1 anonyme\n");
        (void)fprintf(stdout,"Size struct avec anonyme\t: %zu bytes\n", sizeof(struct pseudo_liste));
        (void)fprintf(stdout,"data offset\t: %zu bytes\n", offsetof(struct pseudo_liste,data));
        (void)fprintf(stdout,"back offset\t: %zu bytes\n", offsetof(struct pseudo_liste, back));
        (void)fprintf(stdout,"next offset\t: %zu bytes\n", offsetof(struct pseudo_liste, next));
     
        (void)fprintf(stdout,"===========================================\n");
        (void)fprintf(stdout,"Infos debug comparatif structure 2 no anonyme\n");
        (void)fprintf(stdout,"Size struct sans anonyme\t: %zu bytes\n", sizeof(struct pseudo_liste_2));
        (void)fprintf(stdout,"data offset\t: %zu bytes\n",offsetof(struct pseudo_liste_2,data));
        (void)fprintf(stdout,"back offset\t: %zu bytes\n",offsetof(struct pseudo_liste_2, back));
        (void)fprintf(stdout,"next offset\t: %zu bytes\n",offsetof(struct pseudo_liste_2, next));
    }
     
     
    /*    Fonction pour afficher la liste    */
    void fnc_printList(struct pseudo_liste *head) {
        unsigned int offset = 0x0;
        struct pseudo_liste *this_ptr = head;
     
        if (NULL == head) {
            puts("Liste vide");
            return;
        }
     
        while (NULL != this_ptr) {
            printf("offset[0x%x] Value\t:%d\n",
                   offset, this_ptr->data);
            this_ptr = this_ptr->next;
            offset++;
        }
     
        (void)puts("----------");
    }
     
     
    /*    Fonction pour libérer la mémoire 
     *  allouée pour la liste
     */
    void fnc_free(struct pseudo_liste **head) {
        struct pseudo_liste *this_ptr = *head;
        while (NULL != this_ptr) {
            struct pseudo_liste *ptr_del = this_ptr;
            this_ptr = this_ptr->next;
            free(ptr_del);
        }
        *head = NULL;
    }
     
     
    /*    Fonction pour supprimer 
     *    un nœud de la liste 
     */
    void fnc_delete(struct pseudo_liste **head, int data) {
        struct pseudo_liste *this_ptr = *head;
     
        if (NULL == this_ptr)
            return;
     
        while (NULL != this_ptr) {
            if (data == this_ptr->data) {
                if (NULL != this_ptr->back) {
                    this_ptr->back->next = this_ptr->next;
                } else {
                    *head = this_ptr->next;
                }
     
                if (NULL != this_ptr->next)
                    this_ptr->next->back = this_ptr->back;
     
                free(this_ptr);
                this_ptr = NULL;
                (void)printf("data: %d\n free\n", data);
                return;
            }
            this_ptr = this_ptr->next;
        }
        (void)printf("data %d\t absent\n", data);
    }
     
     
    /*
     * Fonction pour ajouter 
     * un nœud à la fin de la liste
     */
    void fnc_add(struct pseudo_liste **head, int data) {
        struct pseudo_liste *new_ptr = malloc(sizeof(struct pseudo_liste));
     
        if (NULL == new_ptr) {
            (void)fprintf(stderr, "Erreur(%d)\t:%s\n",
                          errno, strerror(errno));
            exit(EXIT_FAILURE);
        }
     
        new_ptr->data = data;
        new_ptr->next = NULL;
     
        if (NULL == *head) {
            new_ptr->back = NULL;
            *head = new_ptr;
        } else {
            struct pseudo_liste *this_ptr = *head;
            while (NULL != this_ptr->next) {
                this_ptr = this_ptr->next;
            }
            this_ptr->next = new_ptr;
            new_ptr->back = this_ptr;
        }
    }
     
     
    int main(void) {
     
        unsigned int offset = 0x0;
        struct pseudo_liste *head = NULL;
     
        /*    Afficher la taille de la structure 
         *  et les offsets de ses membres
         */
        printStructSizeAndOffsets();
     
        /* Sortie attendue : Liste vide */
        fnc_printList(head);
     
        /* Sortie attendue data 11 absent    */
        fnc_delete(&head, 11);
     
        /* Ajout des data    */
        for (; offset < 10; offset++)
            fnc_add(&head, (offset + 0x1));
     
        /*    Sortie attendue : 
         *  offset[0x0] Value : 1 ... 
         */
        fnc_printList(head);
        fnc_free(&head);
     
        return EXIT_SUCCESS;
    }

    Il est important de noter que l'utilisation d'une structure anonyme n'affectera pas la taille de la structure externe si les membres de la structure anonyme sont de types primitifs ou de petites tailles par rapport à la taille totale de la structure externe.

    Cependant, malgré les avantages évoqués précédemment, l'utilisation de structures anonymes peut aussi a des inconvénients. En effet, cela peut rendre le code moins lisible et plus difficile à maintenir, plus particulièrement pour les développeurs ou débutants qui ne sont pas familiers avec cette approche. Il est donc essentiel de peser les avantages et les inconvénients avant d'opter pour cette méthode. Dans certains cas, il peut être plus simple et efficace d'opter pour une approche plus conventionnelle dites classique avec des structures nommées pour éviter de compliquer le code pour rien.

    En conclusion, l'utilisation de structures anonymes trouve sont utilité et peut être avantageuse dans certains cas, en améliorant la clarté et l'organisation du code. Mais il est important de de ne pas omettre et prendre en compte les connaissances et la familiarité des développeurs avec cette approche avant de l'adopter a mon sens et en fonction des besoins spécifiques; il peut être préférable de choisir l'option la plus appropriée pour faciliter les choses.
    à bientôt

  9. #9
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    @sambia39
    La discussion était plus la comparaison d'une structure anonyme avec pas de structure du tout. Si je prend ton code comme exemple :
    Si je remplace ta structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct pseudo_liste {    unsigned int data;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        };
    };
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct pseudo_liste{    unsigned int data;
        struct pseudo_liste *back;
        struct pseudo_liste *next;
    };
    Et bien ton code compile pareil. On ne peut pas dire que ça apporte grand chose de plus.

    En passant, ta seconde structure est identique à la première (la structure interne est aussi anonyme).
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  10. #10
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Citation Envoyé par CGi Voir le message
    @sambia39
    La discussion était plus la comparaison d'une structure anonyme avec pas de structure du tout.
    Il ne s'agit pas de comparer des structures anonymes avec pas du tout de structure, mais de l'utilité des structures anonymes et de l'avantage d'écrire de cette manière. Si le but est une comparaison entre une structure anonyme avec pas du tout une structure ou éventuellement avec une structure non-anonyme, cela équivaudrait à utiliser des variables locales. (Cas contraire, user d'une structure anonyme localement dans la fonction, à titre d'exemple, revient à regrouper des variables...)

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void function_foo( void ) {
        struct {
            unsigned data_1;
            unsigned data_2;
             unsigned data_3;
        } foo;
     
        /* etc   reste du code */
        ETC ........ 
         .........;= 100;
    }


    En revanche, selon ce que j'ai compris. La question, est porter sur l'utilité d'une structure anonyme et les avantages d'écrire de cette manière d'écrite par @Sve@r. J'ai donc répondu en précisant que cela apporte certains avantages et inconvénients.

    Et dans mon post précédent, j'ai écrit qu'il est important de noter que l'utilisation d'une structure anonyme n'affectera pas la taille de la structure externe si les membres de la structure anonyme sont de type primitif ou de petite taille par rapport à la taille totale de la structure externe. Et votre exemple confirme que les deux approches produiront le même résultat au moment de l'exécution. Les structures anonymes et les structures conventionnelles ne diffèrent pas dans leur fonctionnalité, puisqu'elles sont toutes deux utilisées pour organiser et regrouper des données d'une manière similaire. Le choix entre une structure anonyme et une structure conventionnelle dépendra principalement de la clarté du code et de l'intention du programmeur - points que je n'ai peut-être pas plus détaillés et énoncés dans mon précédent message.

    Ainsi, les structures anonymes peuvent être utiles lorsqu'il s'agit de définir des structures de données locales dans un contexte spécifique, sans qu'il soit nécessaire de les réutiliser ailleurs. Cela peut rendre le code plus lisible et plus compact, en particulier lorsque vous voulez éviter de déclarer une nouvelle structure nommée pour une utilisation qui peut être ponctuelle.

    Citation Envoyé par CGi Voir le message
    @sambia39 Si je prend ton code comme exemple :
    Si je remplace ta structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct pseudo_liste {    unsigned int data;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        };
    };
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct pseudo_liste{    unsigned int data;
        struct pseudo_liste *back;
        struct pseudo_liste *next;
    };
    Et bien ton code compile pareil. On ne peut pas dire que ça apporte grand chose de plus.
    En passant, ta seconde structure est identique à la première (la structure interne est aussi anonyme).
    En effet, le code compile de la même manière. La structure supplémentaire que j'avais utilisée précédemment était destinée aux tests qui ont conduit à la formulation de l'idée initiale mentionnée dans mon premier message. Je m'excuse que cela ait pu traîner dans le code source.

    L'essentiel est de comprendre les avantages et les désavantages d'une structure anonyme. Par exemple, elle rend les membres inaccessibles depuis l'extérieur de la structure externe, ce qui peut compliquer la réutilisation de la structure si elle doit être utilisée dans plusieurs parties du code. Cependant, il est important de noter que les deux approches, structures anonymes et structures conventionnelles, peuvent être facilement interchangeables dans de nombreux cas. Le choix entre les deux dépendra principalement de la préférence du programmeur et de la lisibilité du code. En termes de taille mémoire, elle sera la même pour les deux approches si les types et les tailles des membres sont identiques.

    J'arrive donc à la conclusion dont j'ai évoqué dans mon premier poste cela peut rendre le code moins lisible et plus difficile à maintenir, plus particulièrement pour les développeurs ou débutants qui ne sont pas familiers avec cette approche. Il est donc essentiel de tenir compte des avantages et des inconvénients avant de choisir cette méthode. Dans certains cas, il peut être plus simple et plus efficace d'opter pour une approche plus classique avec des structures nommées afin d'éviter de compliquer le code pour rien.

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 850
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 850
    Par défaut
    Personnellement, je ne vois pas l’intérêt de ne pas nommer ses structures... ça ne peut qu'augmenter la clarté du code de définir des noms pour les structures.

    Donc entre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct {
       char info;
       struct {   
          char val1;
          char val2;
       };
    } struct_name1;
    et :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct {
       char info;
       struct {
          char val1;
          char val2;
       } data;
    } struct_name1;
    La deuxième solution est pour moi plus claire.

    Et d’ailleurs, la meilleure méthode à utiliser pour un maximum de clareté de maintenabilité, je trouve que c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct {
       char val1;
       char val2;
    } struct_data;
     
    typedef struct {
       char info;
       struct_data data;
    } struct_name1;


    Ensuite entre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct {
       char info;
       char val1;
       char val2;
    } struct_name1;
    et :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct {
       char info;
       struct {
          char val1;
          char val2;
       } data;
    } struct_name1;
    La taille des structures n'est pas identique : la structure interne dans la seconde structure aligne l'adressage, ce qui est utile si on veut pouvoir caster une stucture en une autre:
    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
     
    typedef struct {
       char type;
       char unknow;
       struct {
          char unknow[2];
       } data;
    } struct_general;
     
    typedef struct {
       uint16_t color;
    } struct_car_infos;
    typedef struct {
       char type;
       char id;
       struct_car_infos infos;
    } struct_car;
     
    typedef struct {
       char x;
       char y;
    } struct_location;
    typedef struct {
       char type;
       // char unknow; // en commentaire car ce paramètre n'existe pas pour cette stucture
       struct_location location;
    } struct_house;
     
    void printStruct(struct_general * ptr){
       switch(ptr->type){
       case 0:
          printCar(ptr);
       case 1:
          printHouse(ptr);
          break;
       }
    }
     
    void printCar(struct_car * ptr){
       printf("id: %i\r\n", ptr->id);
       printf("color: %u\r\n", ptr->infos.color);
    }
     
    void printHouse(struct_house * ptr){
       printf("x: %i\r\n", ptr->location.x);
       printf("y: %i\r\n", ptr->location.y);
    }


    Après si on vire les noms des sous-structures, ça permet d'écrire :
    au lieu de :
    Mais je trouve que l'on perd en maintenabilité et clarté.
    En gros pour moi, l'utilité des structures anonymes, c'est pour réduire la taille du code au détriment de la clarté et de la maintenabilité : utile pour les feignasses

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Un exemple concret de l'utilisation d'une structure anonyme (exemple ci-dessous "attention le code source ci-dessous peut comporter des erreurs"
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct pseudo_liste {
        unsigned int data;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        };
    };
    Merci de ton retour. Toutefois comme l'ont fait remarquer certains, cela ne changera rien si on écrit à la place
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct pseudo_liste {
        unsigned int data;
        struct pseudo_liste *back;
        struct pseudo_liste *next;
    };

    Citation Envoyé par sambia39 Voir le message
    les structures anonymes évitent les conflits de noms de variables
    Ah? Je vois pas trop comment.
    Parce que, si j'ai bien compris ton idée, cela se traduirait ainsi
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct pseudo_liste {
        unsigned int data;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        };
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        };
    };
    Mais puisque la structure anonyme n'a pas de nom, on ne peut pas la distinguer d'une autre. Et donc cet exemple ne peut pas fonctionner. Mais sinon je ne vois pas trop alors de quel conflit de noms tu veux parler.

    Citation Envoyé par sambia39 Voir le message
    tout en optimisant la gestion de la mémoire.
    Là il faudrait développer

    Citation Envoyé par sambia39 Voir le message
    tout en améliorant considérablement la lisibilité du code et la facilité d'organisation des membres liés ensemble.
    Là je suis d'accord. En fait ton exemple par rapport au mien est juste plus descriptif/lisible (on voit bien que "next" et "back" vont ensembles). Mais je ne pense pas que les structures anonymes aient été créées juste pour ça. En fait, le seul exemple vraiment valable de structure anonyme a été celui de dalfab car sans structure anonyme, son exemple ne peut pas s'écrire (ou alors on passe par une structure non anonyme mais il faut quand-même une structure interne à son union)
    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]

  13. #13
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ah? Je vois pas trop comment.
    Parce que, si j'ai bien compris ton idée, cela se traduirait ainsi
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct pseudo_liste {
    unsigned int data;
    struct {
    struct pseudo_liste *back;
    struct pseudo_liste *next;
    };
    struct {
    struct pseudo_liste *back;
    struct pseudo_liste *next;
    };
    };
    Mais puisque la structure anonyme n'a pas de nom, on ne peut pas la distinguer d'une autre. Et donc cet exemple ne peut pas fonctionner. Mais sinon je ne vois pas trop alors de quel conflit de noms tu veux parler.
    En bref l'utilisation de structures anonymes permet un accès direct aux membres dans le contexte externe. Cependant, lorsque deux structures anonymes sont imbriquées avec des membres portant les mêmes noms, cela engendre des erreurs de résolution de noms et crée de l'ambiguïté, et rend la compilation impossible. Ce conflit survient donc, au niveau des membres des structures anonymes, précisément lorsque des noms identiques comme "back" et "next" existent entre les structures. Cette situation entraîne une ambiguïté nuisible à la compilation du code. Bien que la structure anonyme en elle-même ne soit pas en conflit. Ainsi l'utilisation de noms similaires dans les membres des deux structures provoque le problème. Pour résoudre le problème, il va falloir attribuer des noms distincts soit aux membres des structures anonymes imbriquées au alors opté pour une approche avec une structure non-anonyme. Cette façon de faire élimine l'ambiguïté et clarifie les références des structures 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
    21
    22
     
    struct pseudo_liste {    unsigned int data;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        };
        struct {
            struct pseudo_liste *backs;
            struct pseudo_liste *nexts;
        };
    };
    // option alternative
    struct pseudo_liste {    unsigned int data;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        }foo;
        struct {
            struct pseudo_liste *back;
            struct pseudo_liste *next;
        }bar;
    };

    Citation Envoyé par Sve@r Voir le message
    Là il faudrait développe
    Pour faire simple les structures anonymes permettent d'économiser de la mémoire en partageant le même espace mémoire pour des données similaires et en évitant la duplication etc..
    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
    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
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <stddef.h>
     
     
    #define PADDING  0x1    /* 1 */
    #define MAX_SIZE 0x32   /* 50 */
     
     
    /*
     * Structure avec
     * structures anonymes
     * volentairement definis ainsi
     */
    struct ts_AnonymAnimal {
        struct {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        } info;
    };
     
     
    /*
     * Structures pour les
     * différents animaux
     * sans anonymat
     */
    struct ts_Serpent {
        char nom[MAX_SIZE];
        char race[MAX_SIZE];
        unsigned short age;
    };
     
     
    struct ts_Araigne {
        char nom[MAX_SIZE];
        char race[MAX_SIZE];
        unsigned short age;
    };
     
     
     
     
    /*
     * Structure globale pour
     * les animaux sans anonymat
     */
    struct ts_NoAnonymAnimal {
        struct ts_Serpent serpent;
        struct ts_Araigne araigne;
    };
     
     
    void fnc_indent(int level) {
        for (int i = 0x0; i < level; ++i) {
            (void)fprintf(stdout, "  ");
        }
    }
     
     
    void fnc_printSizeInfo(const char *name, size_t size) {
        (void)fprintf(stdout, "%s : %zu octets\n", 
                      name, size);
    }
     
     
    void fnc_printAnimalInfo(int level, const char *animalName, 
                             const char *nom, const char *race, 
                             unsigned short age, size_t size) {
     
        fnc_indent(level);
        (void)fprintf(stdout, "%s :\n", animalName);
        fnc_indent(level + PADDING);
        (void)fprintf(stdout, "Nom : %s\n", nom);
        fnc_indent(level + PADDING);
        (void)fprintf(stdout, "Race : %s\n", race);
        fnc_indent(level + PADDING);
        (void)fprintf(stdout, "Age : %hu\n", age);
        fnc_printSizeInfo("Taille de la structure", size);
     
        // Taille de chaque élément de la structure
        fnc_printSizeInfo("Taille de char nom", 
            sizeof(((struct ts_AnonymAnimal *)0)->info.nom));
        fnc_printSizeInfo("Taille de char race",
            sizeof(((struct ts_AnonymAnimal *)0)->info.race));
        fnc_printSizeInfo("Taille de unsigned short age", 
            sizeof(((struct ts_AnonymAnimal *)0)->info.age));
     
    }
     
    int main(void) {
        // Exemple avec structures anonymes
        struct ts_AnonymAnimal chien = {
            .info = {"Milou", "Border", 5}};
        struct ts_AnonymAnimal panda = {
            .info = {"Picha", "Pango", 15}};
     
        printf("Info Structure Anonyme :\n");
        fnc_printAnimalInfo(PADDING, "Chien", 
            chien.info.nom, chien.info.race, 
            chien.info.age, sizeof(struct ts_AnonymAnimal));
     
        fnc_printAnimalInfo(PADDING, "Panda", 
            panda.info.nom, panda.info.race, 
            panda.info.age, sizeof(struct ts_AnonymAnimal));
     
     
        /*    Exemple sans structures anonymes    */
        struct ts_NoAnonymAnimal serpent = {
            .serpent = {"Kaa", "Python", 5}};
        struct ts_NoAnonymAnimal araigne = {
            .araigne = {"Bagheera", "Araignee", 15}};
     
        (void)fprintf(stdout, "\nInfo Structure No Anonyme :\n");
        fnc_printAnimalInfo(PADDING, "Serpent", 
            serpent.serpent.nom, serpent.serpent.race, 
            serpent.serpent.age, sizeof(struct ts_NoAnonymAnimal));
     
        fnc_printAnimalInfo(PADDING, "Araignee", 
            araigne.araigne.nom, araigne.araigne.race, 
            araigne.araigne.age, sizeof(struct ts_NoAnonymAnimal));
     
        size_t sizeAnonym = sizeof(struct ts_AnonymAnimal);
        size_t sizeNoAnonym = sizeof(struct ts_NoAnonymAnimal);
     
        // Comparaison des tailles
        if (sizeAnonym < sizeNoAnonym) {
            (void)fprintf(stdout,
                "\x1b[31mLa structure avec structure anonyme est plus petite.\x1b[0m\n");
        } else if (sizeAnonym > sizeNoAnonym) {
            (void)fprintf(stdout,
                "\x1b[31mLa structure sans struture anonyme est plus petite.\x1b[0m\n");
        } else {
            (void)fprintf(stdout,
                "\x1b[31mLes deux structures ont la même taille.\x1b[0m\n");
        }
     
        return EXIT_SUCCESS;
    }


    Citation Envoyé par Sve@r Voir le message
    Là je suis d'accord. En fait ton exemple par rapport au mien est juste plus descriptif/lisible (on voit bien que "next" et "back" vont ensembles). Mais je ne pense pas que les structures anonymes aient été créées juste pour ça. En fait, le seul exemple vraiment valable de structure anonyme a été celui de dalfab car sans structure anonyme, son exemple ne peut pas s'écrire (ou alors on passe par une structure non anonyme mais il faut quand-même une structure interne à son union)
    En réalité il est toujours possible et son exemple démontre que l'on peut écrire autrement; Je m'explique. L'exemple illustre par @dalfab qui démontre la possibilité d'employée une structure anonyme pour stocker des coordonnées (x, y et z), tout comme le ferait le tableau de coordonnées "coord" illustré de manière explicite. plus précisément son exemple peut stocker les donnée de deux manières différentes : soit en utilisant une structure anonyme, soit en utilisant un tableau d'entiers. Ainsi en retirant le tableau d'entier ou inversement dans les deux cas, coordonne conserve la même structure mémoire, ce qui signifie que vous pouvez choisir d'utiliser des noms explicites avec la structure anonyme pour une meilleure lisibilité, ou simplement utiliser le tableau coord pour un accès plus direct. C'est une question de préférence et de lisibilité du code qui reviens a la conclusion d'un choix qui dépendra principalement de la préférence ( soit l'un/l'autre ou alors les deux ) et de la lisibilitédu code et en termes d'occupation mémoire, les deux approches sont équivalentes si les types et tailles des membres demeurent identiques. Exemple possible d’écriture:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    // exemple 1
    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
    union Point {
        int coord[3];
    };
     
    // exemple 2
    union Point {
        int x, y, z;
    };
     
    // exemple 3
    union Point {
        struct {
            int x;
            int y;
            int z;
        };
        int coord[3];
    };
    Les trois exemples sont équivalentes en termes de fonctionnalité et de comportement. Elles définissent toutes une union nommée "points" qui peut être utilisée pour stocker des coordonnées x, y et z de manière interchangeable. La structure anonyme n'ajoute pas de surcharge de mémoire. Elle permet simplement un accès plus lisible et cohérente aux membres de l'union en utilisant des noms explicites. Cela signifie que si les membres ont des types et des tailles identiques, la taille totale de l'union restera inchangée, quelle que soit l'approche que vous choisissez en soit oui pour moi le gros avantage est l'amélioration de la clarté et l'organisation du code.

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Pour faire simple les structures anonymes permettent d'économiser de la mémoire en partageant le même espace mémoire pour des données similaires et en évitant la duplication etc..
    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
    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
     
    #define MAX_SIZE 0x32   /* 50 */
     
     
    /*
     * Structure avec
     * structures anonymes
     * volentairement definis ainsi
     */
    struct ts_AnonymAnimal {
        struct {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        } info;
    };
     
     
    /*
     * Structures pour les
     * différents animaux
     * sans anonymat
     */
    struct ts_Serpent {
        char nom[MAX_SIZE];
        char race[MAX_SIZE];
        unsigned short age;
    };
     
     
    struct ts_Araigne {
        char nom[MAX_SIZE];
        char race[MAX_SIZE];
        unsigned short age;
    };
     
    /*
     * Structure globale pour
     * les animaux sans anonymat
     */
    struct ts_NoAnonymAnimal {
        struct ts_Serpent serpent;
        struct ts_Araigne araigne;
    };
     
        size_t sizeAnonym = sizeof(struct ts_AnonymAnimal);
        size_t sizeNoAnonym = sizeof(struct ts_NoAnonymAnimal);
     
        // Comparaison des tailles
        if (sizeAnonym < sizeNoAnonym) {
            (void)fprintf(stdout,
                "\x1b[31mLa structure avec structure anonyme est plus petite.\x1b[0m\n");
        } else if (sizeAnonym > sizeNoAnonym) {
            (void)fprintf(stdout,
                "\x1b[31mLa structure sans struture anonyme est plus petite.\x1b[0m\n");
        } else {
            (void)fprintf(stdout,
                "\x1b[31mLes deux structures ont la même taille.\x1b[0m\n");
        }
    Oui enfin la structure anonyme décrit un animal et la structure "pas anonyme" en décrit deux !!! Evidemment que l'anonyme est plus petite, mais ce n'est pas grâce à son anonymat.
    En écrivant...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct ts_Animal {
        char nom[MAX_SIZE];
        char race[MAX_SIZE];
        unsigned short age;
    };
    ... on obtient un niveau d'abstraction équivalent tout en restant plus simple

    Accessoirement écrire des valeurs comme la taille d'un nom en hexa ça donne peut-être un style mais c'est franchement pas lisible (toute notre éducation numérique s'étant faite sur la base 10). L'hexa c'est sympa pour des masques de bits (là il y a de la lisibilité) mais pour des nombres de la vie courante...


    Citation Envoyé par sambia39 Voir le message
    Exemple possible d’écriture:

    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
    // exemple 1
    union Point {
        int coord[3];
    };
     
    // exemple 2
    union Point {
        int x, y, z;
    };
     
    // exemple 3
    union Point {
        struct {
            int x;
            int y;
            int z;
        };
        int coord[3];
    };
    L'exemple 2 n'est pas équivalent aux autres, les 3 int x, y et z occupant le même espace.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    union Point {
    	int x, y, z;
    };
     
    int main() {
    	union Point p;
    	p.x=123;
    	p.y=456;
    	p.z=789;
    	printf("p.x=%d, p.y=%d, p.z=%d\n", p.x, p.y, p.z);			// Résultat p.x=789, p.y=789, p.z=789
    }
    Dans l'exemple de dalfab (ainsi que dans ton 3°), on a x, y et z distincts ; ces 3 int occupant le même espace que le tableau.

    Citation Envoyé par sambia39 Voir le message
    La structure anonyme n'ajoute pas de surcharge de mémoire. Elle permet simplement un accès plus lisible et cohérente aux membres de l'union en utilisant des noms explicites.
    C'est pour ça que j'ai dit que son (dalfab) exemple avait été le seul exemple vraiment réaliste pour expliquer l'utilité d'une structure anonyme.
    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]

  15. #15
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Oui enfin la structure anonyme décrit un animal et la structure "pas anonyme" en décrit deux !!! Evidemment que l'anonyme est plus petite, mais ce n'est pas grâce à son anonymat.
    En écrivant...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct ts_Animal {
        char nom[MAX_SIZE];
        char race[MAX_SIZE];
        unsigned short age;
    };
    ... on obtient un niveau d'abstraction équivalent tout en restant plus simple
    ............
    Oui, mais sous le capot c'est pas tout a fait ça. L'utilisation de structures anonymes a un impact sur l'utilisation de la mémoire. En réduisant la duplication de noms de membres communs entre différentes structures, économisons ainsi de l'espace mémoire en évitant d'allouer de la mémoire supplémentaire pour les mêmes noms de membres dans chaque structure. L'optimisation de la taille dans l'exemple avec les structures anonymes n'est pas directement due à l'anonymat en soi on est d'accord, mais plutôt à la manière dont les membres sont regroupés dans la mémoire. Les membres de la structure anonyme partagent le même espace mémoire, ce qui réduit l'espace occupé par les membres et évite l'ajout de bytes de padding. En fin de compte, les structures anonymes permettent d'économiser de la mémoire en partageant le même espace mémoire pour des données similaires et en évitant la duplication. De mon point de vue, cela constitue un moyen efficace d'optimiser l'utilisation de la mémoire, surtout lorsque plusieurs structures partagent des membres similaires.


    Citation Envoyé par Sve@r Voir le message
    L'exemple 2 n'est pas équivalent aux autres, les 3 int x, y et z occupant le même espace.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    union Point {
        int x, y, z;
    };
     
    int main() {
        union Point p;
        p.x=123;
        p.y=456;
        p.z=789;
        printf("p.x=%d, p.y=%d, p.z=%d\n", p.x, p.y, p.z);            // Résultat p.x=789, p.y=789, p.z=789
    }
    Dans l'exemple de dalfab (ainsi que dans ton 3°), on a x, y et z distincts ; ces 3 int occupant le même espace que le tableau.
    L'exemple 2 a potentiellement des chances d'occuper moins d'espace mémoire. Cependant, cette optimisation de mémoire relève de la responsabilité du compilateur. Le mode d'alignement des membres dans une union ou une structure est déterminé par les règles d'alignement du compilateur, les caractéristiques spécifiques de la machine et les options utilisées.


    Dans l'exemple 3, l'utilisation d'une structure anonyme garantit un alignement spécifique des membres x, y et z. Cependant, cela peut entraîner une légère augmentation de la consommation d'espace mémoire par rapport à l'exemple 2 . Et bien que la norme C ne définisse pas explicitement la notion de structure anonyme ou d'union dite "anonyme", elle établit clairement touts en matière d'alignement des structures, d'alignement des membres et de padding entre les membres ce qui se traduit au finale par un impact sur l'occupation mémoire des structures et des unions.

    De toute façon, les structures anonymes et les unions anonymes sont en réalité des extensions du langage de programmation C fournies par certains compilateurs pour faciliter la programmation et l'optimisation de la mémoire. La taille des structure anonyme peut donc varier d'un compilateur à l'autre, car le compilateur a le contrôle et choisit de traiter les structures anonymes de différentes manières. Par ailleurs votre remarque me fait penser "option __attribute__((packed))" de GCC qui permet d'indiquer au compilateur de ne pas insérer de padding entre les membres de la structure, cela peut avoir des conséquences sur les performances d'accès aux données en raison d'un alignement non optimal mais pourrais nous éclairée afin de savoir si oui sans option compilateur le compilateur applique alignement par défauts ou pas et ainsi supposer qu'importe par défaut c'est pareils pour une structure anonyme et non-anonyme ? "par exemple..."

    En attendant, pour moi, l'utilisation de structures anonymes permet d'optimiser l'utilisation de la mémoire en partageant l'espace entre les membres similaires, mais il faut tenir compte des règles d'alignement et du bon vouloir du compilateur. Et oui, la base 10 serait plus appropriée que du 0x32.

  16. #16
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Je pense qu'il y a une confusion,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct ts_AnonymAnimal{
        struct
        {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        } info;
    };
    N'est pas une structure anonyme car elle a un nom "info"
    Par contre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct ts_AnonymAnimal
    {
        struct
        {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        };
    };
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct ts_AnonymAnimal
    {
        struct info
        {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        };
    };
    Sont des structures anonymes.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  17. #17
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Citation Envoyé par CGi Voir le message
    Je pense qu'il y a une confusion,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct ts_AnonymAnimal{
        struct
        {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        } info;
    };
    N'est pas une structure anonyme car elle a un nom "info"
    Par contre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct ts_AnonymAnimal
    {
        struct
        {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        };
    };
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct ts_AnonymAnimal
    {
        struct info
        {
            char nom[MAX_SIZE];
            char race[MAX_SIZE];
            unsigned short age;
        };
    };
    Sont des structures anonymes.
    Exact

  18. #18
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    On n'en a pas parlé, voici un exemple ou une structure externe et mise dans une autre structure en anonyme :
    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
    #include <stdio.h>
     
    struct Personne
    {
        char nom[32];
        char prenom[32];
    };
     
     
    struct Info
    {
        struct Personne; // annonyme, car il n'y a que le type mais pas le nom.
        int age;
    };
     
     
    int main(void)
    {
        struct Info individu = {{"Gates", "Bill"}, 67};
     
     
        printf("%s %s %d ans.", individu.nom, individu.prenom, individu.age);
     
     
        return 0;
    }
    On voit que l'on peut accéder aux champs de la structure Personne comme s'ils étaient des champs de la structure Info.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  19. #19
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par CGi Voir le message
    On n'en a pas parlé, voici un exemple ou une structure externe et mise dans une autre structure en anonyme...
    On voit que l'on peut accéder aux champs de la structure Personne comme s'ils étaient des champs de la structure Info.
    Désolé, ton exemple est plaisant mais il ne compile pas chez-moi (gcc 11.4.0).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a.c:12:20: warning: declaration does not declare anything
       12 |     struct Personne; // annonyme, car il n'y a que le type mais pas le nom.
          |                    ^
    Peut-être qu'il faut une option particulière toutefois je n'en ai pas eu besoin pour ceux de sambia ou dalfab.
    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]

  20. #20
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Oui, c'est valable seulement à partir de C11.

    PS : J'ai testé avec gcc 12.2.0 et Visual Studio 2022 sur les deux ça fonctionne.
    C'est décrit dans la norme C11 (Comme tout ce qu'on a parlé depuis le début, avant c'était implémenté par certain compilateur sans faire partie de la norme).
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

Discussions similaires

  1. Utilité des fonctions anonymes
    Par tribaleur dans le forum Général Dotnet
    Réponses: 5
    Dernier message: 16/08/2018, 11h28
  2. Utilité des types OpenGL GLint, GLfloat, GLvoid, etc.
    Par Djakisback dans le forum OpenGL
    Réponses: 17
    Dernier message: 14/12/2005, 12h35
  3. Utilité des schemas sous Postgresql?
    Par sessime dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 18/03/2005, 15h45
  4. Utilité des logos Xiti ?
    Par KibitO dans le forum Evolutions du club
    Réponses: 5
    Dernier message: 20/02/2005, 17h42
  5. utilité des DbControl
    Par portu dans le forum Bases de données
    Réponses: 6
    Dernier message: 02/07/2004, 05h41

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