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 et pointeurs


Sujet :

C

  1. #1
    Membre confirmé Avatar de Tchetch
    Inscrit en
    Mars 2002
    Messages
    401
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 401
    Points : 477
    Points
    477
    Par défaut Structures et pointeurs
    Bonjour,

    Voilà j'ai une structure comme suite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct X {
      int a;
      int b;
      int c;
      int d;
      int e;
      int f;
      /* ... 11 entiers au total */
      struct Y *y;
      struct X *x;
    }
    Et au lieu de faire un tableau d'entier dans ma structure je me suis proposé de la laisser comme présentée et de faire ainsi pour la remplir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct X *x;
     
    for(i=0;i<11;++i)
    {
      *((int *)x+i)=value;
    }
    Donc ce code compile et fonctionne merveilleusement bien, mais quelque chose me dit que je ne devrais pas le faire.
    Qu'en pensez-vous ?

    T.
    Mon wiki (on y parle Debian principalement) : http://www.tchetch.net/

  2. #2
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Tchetch
    Qu'en pensez-vous ?
    Qu'effectivement tu ne devrais pas faire cela.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  3. #3
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(i=0;i<11;++i)
    {
      *((int *)x+i)=value;
    }
    En faisant ça, tu supposes que tu connais l'implémentation des structures, alors qu'il ne faudrait pas.

    Si un jour, l'implémentation change (par exemple, si les éléments se retrouvent à être écrits dans l'autres ordre dans la mémoire à cause du compilateur), alors ton programme va gravement planter. Tu supposes ici que les éléments, dans la mémoire sont dans l'ordre où tu les as écrits. Pourquoi ça ne commencerait pas par tes pointeurs ?

    Si un jour tu modifies l'ordre (toi même), ça sera plus difficile à changer.
    Je ne répondrai à aucune question technique en privé

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par millie
    par exemple, si les éléments se retrouvent à être écrits dans l'autres ordre dans la mémoire à cause du compilateur
    L'ordre des éléments d'une structure est imposé. Mais pas le décalage. Il se peut, même si c'est peut vraissemblable, que qu'il y ait un padding entre les membres (il n'y a jamais de padding entre les éléments d'un tableau; dans les cas où c'aurait été nécessaire, la norme exige que le padding soit incorporé à l'élément).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  5. #5
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 727
    Points
    1 727
    Par défaut
    On pourrait faire ceci, 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
    struct X {
      union
      {
       struct
       {
        int a;
        int b;
        int c;
        int d;
        int e;
        int f;
       } fields;
       int tab[6];
      } u;
     
      struct Y *y;
      struct X *x;
    }

  6. #6
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Gruik
    On pourrait faire ceci, 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
    struct X {
      union
      {
       struct
       {
        int a;
        int b;
        int c;
        int d;
        int e;
        int f;
       } fields;
       int tab[6];
      } u;
     
      struct Y *y;
      struct X *x;
    }
    Oui. Mais ça ne règle pas le problème: rien ne garanti que tab+1 == &fields.b. Seul le dernier dans lequel on a écrit entre tab et fields peut être lu.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  7. #7
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Si tu veux déclarer une structure avec 11 entiers et deux pointeurs vers deux autres structures, le plus simple serait d'incorporer un vecteur de 11 éléments à ta structure, ainsi que les deux pointeurs. Comme ça au moins, tu auras la garantie que ton code fonctionnera... mais il est tout de même très moche.

    Qui t'a dit de procéder ainsi ?
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Tchetch
    Voilà j'ai une structure comme suite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct X {
      int a;
      int b;
      int c;
      int d;
      int e;
      int f;
      /* ... 11 entiers au total */
      struct Y *y;
      struct X *x;
    }
    Et au lieu de faire un tableau d'entier dans ma structure je me suis proposé de la laisser comme présentée et de faire ainsi pour la remplir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct X *x;
     
    for(i=0;i<11;++i)
    {
      *((int *)x+i)=value;
    }
    Donc ce code compile et fonctionne merveilleusement bien, mais quelque chose me dit que je ne devrais pas le faire.
    Qu'en pensez-vous ?
    Que ce n'est pas portable. Il ne faut pas confondre tableau et structure, même si les éléments sont identiques. Il pourrait y avoir du padding pour des questions d'alignement (un simple changement de reglage de compilateur suffit), et ça fausserait tout. Si ce sont N données répétées, fait un tableau de taille N...
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Gruik
    On pourrait faire ceci, 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
    struct X {
      union
      {
       struct
       {
        int a;
        int b;
        int c;
        int d;
        int e;
        int f;
       } fields;
       int tab[6];
      } u;
     
      struct Y *y;
      struct X *x;
    }
    Non. Il n'y a aucune garantie que les données soient au même endroit.
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par millie
    Si un jour, l'implémentation change (par exemple, si les éléments se retrouvent à être écrits dans l'autres ordre dans la mémoire à cause du compilateur),
    L'ordre est garanti. Mais pas l'alignement.
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Si tu regroupes tous tes entiers dans un même vecteur au sein de la structure (et en début de structure), comme je l'ai souligné plus haut, la norme ANSI te garantit le résultat sans toucher une virgule à ton code... mais le plus simple serait d'utiliser la notation "tableau".

    Le plus simple quand on commence en C, c'est de ne pas faire des trucs "bas niveau". Trop souvent les gens disent : "On peut tout faire en C !"... Ouais, surtout des conneries !
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par InOCamlWeTrust
    Le plus simple quand on commence en C, c'est de ne pas faire des trucs "bas niveau". Trop souvent les gens disent : "On peut tout faire en C !"... Ouais, surtout des conneries !
    +1 !
    Pas de Wi-Fi à la maison : CPL

  13. #13
    Membre confirmé Avatar de Tchetch
    Inscrit en
    Mars 2002
    Messages
    401
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 401
    Points : 477
    Points
    477
    Par défaut
    C'est aussi l'avis de mon livre "Unleashed C". C'est pour ça que je doutais, il me semblait qu'on ne pouvait pas le faire, mais j'étais plus sûr. Donc ceci étant dit, le problème est résolu.

    Merci beaucoup.

    T.
    Mon wiki (on y parle Debian principalement) : http://www.tchetch.net/

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Tchetch
    C'est aussi l'avis de mon livre "Unleashed C".
    J'espère bien. Je vois qu'on a de bonnes lectures, c'est bien.
    Pas de Wi-Fi à la maison : CPL

  15. #15
    Membre confirmé Avatar de Tchetch
    Inscrit en
    Mars 2002
    Messages
    401
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 401
    Points : 477
    Points
    477
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    J'espère bien. Je vois qu'on a de bonnes lectures, c'est bien.
    J'ai trouvé la référence de ce livre sur un site que tu devrais connaître : http://emmanuel-delahaye.developpez.com/
    Mon wiki (on y parle Debian principalement) : http://www.tchetch.net/

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

Discussions similaires

  1. structures et pointeurs de fonctions
    Par aimad41 dans le forum C
    Réponses: 5
    Dernier message: 21/11/2006, 10h49
  2. Structure et pointeur
    Par Nalido dans le forum C
    Réponses: 5
    Dernier message: 08/08/2006, 15h08
  3. Copie de structure par pointeur - Problème LSB MSB
    Par the_ionic dans le forum Réseau
    Réponses: 4
    Dernier message: 17/07/2006, 15h08
  4. Structures et pointeurs
    Par mastochard dans le forum C
    Réponses: 17
    Dernier message: 25/05/2006, 11h55
  5. [structure et pointeur] problème d'affichage
    Par kitsune dans le forum C
    Réponses: 17
    Dernier message: 22/03/2006, 22h20

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