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 :

problème de pointeurs vers structure


Sujet :

C

  1. #1
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut problème de pointeurs vers structure
    bonsoir

    j'ai un petit problème, est ce que ceci est juste??


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct toto
    {
           int a;
           int b; 
           int c;
    }toto;
     
    toto**tab;

    après ça, est ce que je peux travailler avec un tableau dynamique de 2 dimension (chaque case contient une variable de type toto)?

    comment dois-je allouer de l'espace mémoire ?

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641

  3. #3
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    l'exemple qu'ils ont donné contient le type int,
    mais est ce que c'est la même chose pour toto??

  4. #4
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    tenez pourriez vous corriger ce code ?

    mon problème vient de ça!!!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <stdio.h>
     
    void affiche(int**A)
    {
        int i, j;
        for(i=0 ; i<=4 ; i++)
        {
            for(j=0 ; j<=1 ; j++)
            printf("%d   ", A[i][j]);
            printf("\n\n");
        }
    }
     
    int main (void)
    {
       int C[5][2], i, j;
     
       for(i=0 ; i<=4 ; i++)
       for(j=0 ; j<=1 ; j++)
       C[i][j]=i+j;
     
     
     
       affiche(C);
     
       saut;saut;
       system("pause");
       return 0;
    }

  5. #5
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void affiche(int A[][2])
    { 
       /* ... */

  6. #6
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    j'ai jamais vu ça, pourriez vous expliquer un petit peu ??

  7. #7
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Ca signifie simplement que la fonction affiche prends comme paramètre un tableau à deux dimensions dont la seconde dimension est 2 (il est possible d'omettre la dimension la plus à gauche qui n'est pas nécessaire au compilateur pour gérer l'index du tableau).

    En effet, contrairement à ce que tu avais écrit dans ton message initiale, un tableau statique à deux dimensions n'est pas équivalent à un pointeur de pointeur et n'est pas promu en pointeur de pointeur lors d'un passage de paramètre.

    En outre pour gérer l'index d'un tel tableau, il est nécessaire que le compilateur connaisse toutes les dimensions, à l'exception de la première, en effet tous les éléments d'un tableau, quel qu'en soit le nombre de dimensions, sont contigus en mémoire, il faut donc pouvoir faire la conversion de n index (un par dimension) vers un index unique.

  8. #8
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    On peut aussi l'écrire comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void affiche(int(*A)[2])
    {
      /* ... */
    Pour passer un tableau à deux dimensions en paramètre
    le compilateur à besoin de connaitre la taille de la deuxieme dimension.


    Maintenant si tu tiens vraiement le traiter en passant juste un pointeur,
    il faut le traiter comme un tableau à une dimension :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void affiche(int *A)
    {
        size_t i, j;
        for(i=0 ; i<5 ; i++)
        {
            for(j=0 ; j<2 ; j++)
            printf("%d   ", A[i*2+j]);
            printf("\n\n");
        }
    }

  9. #9
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    excusez moi, mais c'est quoi size_t ?

  10. #10
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par fred_sell Voir le message
    excusez moi, mais c'est quoi size_t ?
    Un type entier non signé (généralement c'est un typedef de unsigned int ou de unsigned long) standard du C défini dans stddef.h.

    C'est le type naturel pour gérer les tailles et les indices de tableaux. C'est notamment le type retourné par l'opérateur sizeof et utilisé par de nombreuses fonctions de la bibliothèque standard travaillant avec une taille.

  11. #11
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    d'après ce que vous m'aviez dit, ce code devrait être correct !!

    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
    #include <stdio.h>
     
    void affiche(int**A)
    {
        int i, j;
        for(i=0 ; i<=4 ; i++)
        {
            for(j=0 ; j<=1 ; j++)
            printf("%d   ", A[i][j]);
            printf("\n\n");
        }
    }
     
    int main (void)
    {
       int **C, i, j;
     
       C=(int**)malloc(5*sizeof(int*));
       for(i=0 ; i<=4 ; i++)
       C[i]=(int*)malloc(2*sizeof(int));
     
       for(i=0 ; i<=4 ; i++)
       for(j=0 ; j<=1 ; j++)
       C[i][j]=i+j;
     
     
     
       affiche(C);
     
       saut;saut;
       system("pause");
       return 0;
    }
    n'est ce pas ?!!

  12. #12
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    desolé pour le "saut;saut;"

    j'aurais dû faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define saut printf("\n\n")

  13. #13
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33

  14. #14
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    d'après ce que vous m'aviez dit, ce code devrait être correct !!
    Il fait correctement ce que tu souhaites faire.

    La mémoire alloué par malloc doit être libérée par free quand tu n'en as plus besoin.

  15. #15
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    oui merci!!
    et pourquoi un tableau à 2 dimension n'est-t-il pas un pointeur de pointeur ??

  16. #16
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    pourquoi un tableau à 2 dimension n'est-t-il pas un pointeur de pointeur ??
    Pour la même raison qu'un tableau à une dimension n'est pas un pointeur.

    Un pointeur c'est une variable qui contient une adresse.

    Un tableau c'est une suite contigue de donnée d'un type définie. Il a une adresse comme toute variable (pour un tableau celle de son premier élément), mais il contient des données du type avec lequel il a été définie donc pas focement des adresses.

  17. #17
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par fred_sell Voir le message
    d'après ce que vous m'aviez dit, ce code devrait être correct !!

    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
    #include <stdio.h>
     
    void affiche(int**A)
    {
        int i, j;
        for(i=0 ; i<=4 ; i++)
        {
            for(j=0 ; j<=1 ; j++)
            printf("%d   ", A[i][j]);
            printf("\n\n");
        }
    }
     
    int main (void)
    {
       int **C, i, j;
     
       C=(int**)malloc(5*sizeof(int*));
       for(i=0 ; i<=4 ; i++)
       C[i]=(int*)malloc(2*sizeof(int));
     
       for(i=0 ; i<=4 ; i++)
       for(j=0 ; j<=1 ; j++)
       C[i][j]=i+j;
     
     
     
       affiche(C);
     
       saut;saut;
       system("pause");
       return 0;
    }
    n'est ce pas ?!!
    Plus ou moins :
    • La mémoire allouée n'est pas libérée.
    • Il manque les contrôles sur le retour des malloc().


    Sinon d'un point de vu du style :
    • Le cast de l'adresse retournée par malloc() n'est pas indispensable.
    • Tu gagnerais à passer les tailles du tableau à la fonction affiche() afin de la rendre plus générique.
    • Tu devrais éviter les valeurs "magiques" dans le code. Le jour où tu vas avoir besoin de modifier une des dimensions, ça t'épargnera du travail et évitera les oublis malencontreux.
    • Tu devrais préférer la forme for(i=0 ; i<5 ; i++) à la forme for(i=0 ; i<=4 ; i++). La première forme est idiomatique et donc de ce fait plus "naturelle" pour la plupart des développeurs C, donc plus facile à lire, à comprendre et à maintenir.


    Citation Envoyé par fred_sell Voir le message
    oui merci!!
    et pourquoi un tableau à 2 dimension n'est-t-il pas un pointeur de pointeur ??
    Parce que la norme ne le défini pas de cette manière.
    Un tableau à 2 dimensions est un objet dont tous les éléments sont contigus en mémoire alors qu'un pointeur de pointeur est une variable contenant l'adresse (pointeur) d'une autre variable contenant elle même l'adresse (de pointeur) d'une troisième variable. Il n'y a pas de lien entre les deux éléments.
    Ce que tu as créé dans le code précédent n'est pas un tableau à deux dimensions alloué dynamiquement mais un tableau (alloué dynamiquement) contenant l'adresse d'autres tableaux eux-même alloués dynamiquement, ce que l'on pourrait grossièrement résumé par tableau de tableau.

    Au passage, un tableau à une dimension n'est pas un pointeur, bien que dans certains cas il y est une conversion implicite d'un tableau en un pointeur.

  18. #18
    Nouveau membre du Club Avatar de fred_sell
    Inscrit en
    Juin 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 106
    Points : 33
    Points
    33
    Par défaut
    bah merci beaucoup

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

Discussions similaires

  1. Pointeur vers structure dans classe
    Par mulfycrowh dans le forum Débuter
    Réponses: 7
    Dernier message: 14/10/2012, 21h42
  2. Réponses: 11
    Dernier message: 17/05/2010, 10h40
  3. Petit problème sur pointeurs de structures
    Par benjaminb dans le forum C
    Réponses: 5
    Dernier message: 05/01/2008, 20h08
  4. [C#]Pointeur vers structure
    Par torNAdE dans le forum Windows Forms
    Réponses: 3
    Dernier message: 08/05/2006, 19h43
  5. pointeur vers une structure
    Par Xyrroa dans le forum C
    Réponses: 14
    Dernier message: 12/04/2006, 13h13

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