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 tableaux, la galère


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 17
    Points : 11
    Points
    11
    Par défaut Structures et tableaux, la galère
    Salut !!

    je voudrais savoir si il y a des spécificitées lorsque l'on travaille avec une structure, composée d'autres structures, elles-mêmes contenant des tableaux (je m'explique...):

    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
    typdef struct 
    {
       short sLen;
       char *pszValeur;
    } Struct1;
     
    typedef struct 
    {
       Struct1 stVal1;
       Struct1 stVal2;
       Struct1 stVal3[10];
    } Struct2;
     
    typedef struct 
    {
       Strcut2 *pstVal1; // Tableau dont on ne connait pas la taille
       Strcut2 stVal2;
    } Struct3;
    dans mon code, j'ai ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main(...)
    {
       Struct3 stVal;
     
       memset( &stVal, '\0', sizeof(Struct3) );
       maFonction( &stVal );
    }
    aussi, mes sous structures sont-elles initialisées ??
    les tableaux des sous-structures le sont-ils ?

    d'avance merci !

  2. #2
    Expert éminent sénior

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

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    aussi, mes sous structures sont-elles initialisées ??
    Oui si les sous structures ne sont pas définies par un pointeur... Je m'explique, ta structure Struct3 posséde un pointeur vers une structure et une structure.

    Le pointeur est mis à NULL et la structure vstVal2 est initialisée à 0. Si nous regardons la struct Struct2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct {
    Struct1 stVal1;
    Struct1 stVal2;
    Struct1 stVal3[10];
    } Struct2;
    Ici les deux premiers champs seront mis à 0 et le tableau aussi. Donc si on regarde ta structure Struct1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typdef struct {
    short sLen;
    char *pszValeur;
    } Struct1;
    Ici, sLen sera mis à 0 et le pointeur pszValeur sera mis à NULL...

    Bref, tout est mis à 0, y compris les pointeurs...

    Jc

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Attention rien n'oblige il me semble à ce que NULL soit identique à 0.
    Il vaut mieux mettre les pointeurs à NULL tu es assuré de la portabilité.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  4. #4
    Expert éminent sénior

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

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Attention rien n'oblige il me semble à ce que NULL soit identique à 0.
    Il vaut mieux mettre les pointeurs à NULL tu es assuré de la portabilité.
    Exact, autant pour moi... Donc il mettra 0 partout mais ce n'est pas forcément NULL donc DANGEREUX!!!

  5. #5
    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 Re: Structures et tableaux, la galère
    Citation Envoyé par kameha
    je voudrais savoir si il y a des spécificitées lorsque l'on travaille avec une structure, composée d'autres structures, elles-mêmes contenant des tableaux (je m'explique...):

    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
    typdef struct 
    {
       short sLen;
       char *pszValeur;
    } Struct1;
     
    typedef struct 
    {
       Struct1 stVal1;
       Struct1 stVal2;
       Struct1 stVal3[10];
    } Struct2;
     
    typedef struct 
    {
       Strcut2 *pstVal1; // Tableau dont on ne connait pas la taille
       Strcut2 stVal2;
    } Struct3;
    dans mon code, j'ai ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main(...)
    {
       Struct3 stVal;
     
       memset( &stVal, '\0', sizeof(Struct3) );
       maFonction( &stVal );
    }
    aussi, mes sous structures sont-elles initialisées ??
    les tableaux des sous-structures le sont-ils ?

    d'avance merci !
    Ce n'est pas la bonne façon d'initialiser une structure à 0 (pas portable). Il faut plutôt faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main(...)
    {
       Struct3 stVal = {0};
     
       maFonction( &stVal );
    }
    Ceci a pour effet de mettre tout les champs à 0 (logique), y compris les pointeurs qui seront à NULL et les champs des structures et tableaux imbriquées.
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Euh... Une petite question quand même au sujet du NULL non-zéro...

    Le test if(ptr) { quelquechose(); } se met à foirer, alors? Ou est-ce supposé être préservé par le compilateur?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 17
    Points : 11
    Points
    11
    Par défaut Re: Structures et tableaux, la galère
    Ok, merci pour ces éclaircissements...
    continuons donc avec les questions ;-)...

    je reprend ma Struct3:

    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
     
    typedef struct 
    {
       Strcut2 *pstVal1; // Tableau dont on ne connait pas la taille
       Strcut2 stVal2;
    } Struct3;
     
    .
    .
    .
    .
    .
     
      Struct3 stVal = {0};
     
      maFonction( &stVal );
    Si j'ai bien tout compris, pour ajouter de nouvelles occurences de Struct2 dans pstVal1, je peux dans la fonction maFonction faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void maFonction ( Struct3 *pstStruct )
    {
      Struct2 stVal[10] = {0};
     
      // Je rempli mon tableau de structure
      memcpy( pstStruct, stVal, sizeof(stVal) );
    }
    est-ce correct ??

    merci

  8. #8
    Expert éminent sénior

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

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Si j'ai bien tout compris
    Non, tu n'as pas compris....

    Il y a une différence majeur entre l'occupation mémoire d'un pointeur et d'un tableau statique.

    Un pointeur occupe la taille d'un pointeur seulement et la valeur est l'adresse mémoire où se trouve le tableau (même à un seul élément)...

    Un tableau statique occupe la taille de l'élément de base du tableau * nombre d'éléments...

    Donc logiquement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    memcpy( pstStruct, stVal, sizeof(stVal) );
    Ne pourra jamais marché!!!

    Si tu veux le faire comme ceci, tu pourrais faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    pstStruct->pstVal1 = malloc(sizeof(stVal));
     
    if(pstStruct->pstVal1==NULL)
      {
      printf("Erreur d'allocation!!!\n");
      //En principe faudrait retourner une valeur d'erreur mais ta fonction est void
      }
     
    memcpy( pstStruct->pstVal1, stVal, sizeof(stVal) );

    De plus, il est mauvais usage de faire comme tu as fait puisque tu suppose beaucoup de choses, si ta structure était définie comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct
    {
       Strcut2 pstVal1[10]; // Tableau dont on ne connait pas la taille
       Strcut2 stVal2;
    } Struct3;
    Tu pourrais faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy( pstStruct->pstVal1, stVal, sizeof(stVal) );
    Et si on suppose que le compilateur respecte l'ordre de la structure (et c'est là que je me tourne vers les spécialistes de la norme: Est-ce dans la norme que la disposition en mémoire suit la déclaration de la structure?) alors tu pourrais faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy( pstStruct, stVal, sizeof(stVal) );
    Mais je te le déconseille puisque le jour où tu ajoutes quelque chose dans ta structure, si tu le fais en premier élément, ce code ne sera plus correct...

    Jc

  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 Médinoc
    Euh... Une petite question quand même au sujet du NULL non-zéro...

    Le test if(ptr) { quelquechose(); } se met à foirer, alors? Ou est-ce supposé être préservé par le compilateur?
    Non, ça marche toujours, parce qu'on est dans un contexte pointeur.

    Par contre, si on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *p;
    memset (&p, 0, sizeof p);
    et ensuite
    il y a un risque d'erreur, car en effet rien ne dit que 'all bits to 0' soit la représentation de la constante pointeur nul sur l'implémentation.

    Lorsqu'on écrit
    le compilateur met ce qu'il faut dans les bits pour que ce soit la bonne combinaison (il sait quoi faire, car p est un pointeur)

    lors du test
    la même précaution est prise (silencieusement)
    Si on faisait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       printf ("bits de p = %08lX\n", (unsigned long) p);
    on verrait la valeur exacte des bits en mémoire, alors que si on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       printf ("p = %p\n", (void *) p);
    on verra 0 quelque soit la représentation physique de NULL.
    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 Re: Structures et tableaux, la galère
    Citation Envoyé par kameha
    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
     
    typedef struct 
    {
       Strcut2 *pstVal1; // Tableau dont on ne connait pas la taille
       Strcut2 stVal2;
    } Struct3;
     
      Struct3 stVal = {0};
    /* -ed- maintenant, stVal.pstVal1 vaut NULL */
     
      maFonction( &stVal );
     
    void maFonction ( Struct3 *pstStruct ){
      Struct2 stVal[10] = {0};
     
      // Je rempli mon tableau de structure
     
      memcpy( pstStruct, stVal, sizeof(stVal) );
    }
    est-ce correct ??
    Ben non. memcpy() permet de faire n'importe quoi, notamment d'écraser des données existantes. Là, tu ne t'es pas loupé. Le comportement est indéfini...

    Il faut allouer un bloc avec malloc(), et stocker son adresse dans le pointeur prévu à cet effet. (Il est pratique aussi de stocker la taille ou le nombre d'élements alloués, afin de pouvoir se prémunir des débordements de tableau toujours possibles...)
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Ok... ca commence à rentrer (passer de java à c est bien difficile...)... merci à tous pour vos réponses !!

Discussions similaires

  1. structures et tableaux
    Par LostInGeekLand dans le forum Débuter
    Réponses: 14
    Dernier message: 24/07/2009, 13h15
  2. probleme pour structure et tableaux
    Par yassin123441 dans le forum C++
    Réponses: 1
    Dernier message: 18/06/2008, 02h11
  3. Type Structuré et Tableaux
    Par Aurazed dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 30/05/2007, 23h45
  4. [C++/CLI]Structures et tableaux en C++ .NET
    Par kinouseb dans le forum C++/CLI
    Réponses: 2
    Dernier message: 08/12/2006, 15h01
  5. [XSD]Créer structure de tableaux
    Par blastobi dans le forum Valider
    Réponses: 4
    Dernier message: 07/04/2006, 12h29

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