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 :

Pointeurs sur Structure [Débutant]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Avril 2009
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 140
    Par défaut Pointeurs sur Structure [Débutant]
    Bonjour a tous,

    Je m'exerce désesperemment sur l'utilisation des pointeurs mais j'éprouve toujours quelques difficultés a leurs utilisations. Je pense que le seul moyens d'y arriver est la pratique.

    J'ai donc un petit doute quand a l'accès des données pour le code suivant :

    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
    {
    int* DataPtr;
    int DataLength;
    }InfoType
     
    void Function(int Buffer, InfoType* InfoPtr)
    {
     
                int copy_buffer, copy_DataPtr, copy_DataLength;
     
    			copy_buffer = Buffer;
    			copy_DataPtr = *InfoPtr.DataPtr;
    			copy_DataLength = InfoPtr.DataLength;
     }
    A l'appel de ma fonction, InfoPtr est défini comme pointeur sur la structure InfoType, qui elle même contient un pointeur sur un entier.

    Je souhaite copier les données de la structure via ma fonction mais je ne suis pas sûr de mon code.

    Qu'en pensez-vous?


    Merci d'avance pour vos réponses et explications.

    Cordialement,

  2. #2
    Membre Expert
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 149
    Par défaut
    Tu passes un pointeur à ta fonction, pour accéder à la donnée il faut donc une étoile.
    Après pour avoir accès à la donnée pointée par DataPtr il faut une seconde étoile.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    copy_DataPtr = (*(*InfoPtr).DataPtr);
    copy_DataLength = (*InfoPtr).DataLength;
    Une étoile te permet de passer du pointeur à la zone mémoire pointée.
    Sachant que si tu as un pointeur de pointeur :
    - pas d'étoile = zone mémoire du pointeur
    - une étoile = zone mémoire du pointeur pointé
    - deux étoiles = zoné mémoire de la donnée

    En espérant que je ne te dises pas de bêtises, je n'utilise pas de pointeur dans mon métier et donc mes connaissances sur ce sujet datent de l'école.

  3. #3
    Membre expérimenté Avatar de moins1
    Homme Profil pro
    Autre
    Inscrit en
    Février 2013
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2013
    Messages : 85
    Par défaut
    Pour les pointeur sur une structure, on utilise habituellement le symbole ->

    Dans ton cas:
    InfoPtr->DataLength

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 497
    Billets dans le blog
    1
    Par défaut
    Salut,

    Il faut que tu sépares le problème en sous-problèmes :
    1. l'utilisation d'un pointeur sur structure
    2. l'accès aux champs
    3. l'utilisation des champs


    Un pointeur sur structure, c'est comme n'importe quel pointeur : ça contient l'adresse d'une structure. C'est utile pour passer des structures en paramètres à des fonctions, car ça évite de copier toute la structure sur la pile d'appel : on ne copie qu'un pointeur.

    L'accès aux champs d'une structure est indépendant du type des champs. Si tu utilises une structure directement, tu utilises le . ; si tu utilises un pointeur sur structure, tu peux déférencer le pointeur avec * et ensuite utiliser le . pour accéder aux champs mais la solution la plus souvent utilisées est la flèche ->. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    typedef struct
    {
        Type1 champ1;
        Type2 champ2;
    } ma_struct_t;
     
    ma_struct_t direct;
    Type1 c = direct.champ1;
     
    ma_struct_t *pointeur = &direct;
    c = (*pointeur).champ1;
    Type2 d = pointeur->champ2;
    L'accès aux champs est indépendant du type des champs. Dans l'exemple précédent, tu remplaces Type1 par int et Type2 par int* si tu veux. c sera un int, d sera un int*. Tu les utilises ensuite pour ce qu'ils sont.

    Pour en venir à ton code, il y a donc des erreurs que tu auras trouvée en lisant ce que je viens d'écrire :
    • tu n'accèdes pas toujours de la même manière aux champs (une fois avec étoile, une fois sans)
    • tu as un champ de type int* et tu lui affectes un int

    Ton compilateur doit d'ailleurs de mettre des messages d'erreur non ?

    Je pense que le seul moyens d'y arriver est la pratique.
    Je pense qu'il faut d'abord bien saisir les concepts et que ces concepts se digèrent mieux avec de la pratique. Ne fais pas l'effort de comprendre avec un stylo et une feuille comme cela marche !


    @transgohan :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    copy_DataPtr = (*(*InfoPtr).DataPtr);
    Vu les noms des champs, je pense qu'il s'agit plutôt ici d'un mauvais type de la variable locale copy_DataPtr qui devrait être un int*.

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Pour résumer :

    Si on a une structure X du type InfoType, on a accès à ses champs par l'opérateur . (point) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    InfoType X ;
    X.DataLength = ...;
    Si on a un pointeur pX sur une structure du type InfoType, il faut prendre l'objet à l'adresse contenue dans le pointeur (*pX). Cet objet est une structure InfoType et on a accès à ses champs comme ci-dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    InfoType X;
    InfoType * pX = &X ;
    (*px).DataLength = ...; // avec les parenthèses
    Cette dernière écriture peut se simplifier par la notation habituelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    px->DataLength = ...; // équivalent à (*px).DataLength.
    En appliquant à ton exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Function(int Buffer, InfoType* InfoPtr)
    {
       int copy_buffer, copy_DataLength;
       int * copy_DataPtr;
       copy_buffer = Buffer;
       copy_DataPtr = (*InfoPtr).DataPtr;     // ou InfoPtr->DataPtr;
       copy_DataLength = InfoPtr->DataLength; // ou (*InfoPtr).DataLength
     }

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 497
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (*px).DataLength = ...; // avec les parenthèses
    Je n'étais plus certain de la nécessité des parenthèses, merci pour la piqûre de rappel !

  7. #7
    Membre confirmé
    Inscrit en
    Avril 2009
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 140
    Par défaut
    Bonjour a tous,

    Tout d'abord, merci pour ces éclaircissements.

    Donc si j'ai bien tout saisi, pour accéder a un pointeur sur structure de pointeur, il faut définir un pointeur qui sera egal au pointeur en entrée corréler avec l'argument de la structure?

    Concernant ma fonction "Function", pour éffectuer un appel de cet dernière dans ma fonction main, il faudrait la définir de la manière suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void main (void)
    {
    int Buffer1;
    InfoType InfoPtr1;
     
    Function(Buffer1, &InfoPtr1);
    }
    Merci d'avance,

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Donc si j'ai bien tout saisi, pour accéder a un pointeur sur structure de pointeur, il faut définir un pointeur qui sera egal au pointeur en entrée corréler avec l'argument de la structure?
    je ne comprend rien à cette phrase


    Concernant ma fonction "Function", pour éffectuer un appel de cet dernière dans ma fonction main, il faudrait la définir de la manière suivante:...
    Oui, la trame est correcte.

  9. #9
    Membre confirmé
    Inscrit en
    Avril 2009
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 140
    Par défaut
    Effectivement, ma phrase n'étais pas très explicite.

    Autant résumer cela par un exemple plus claire. Je souhaite utiliser la function mecpy pour stocker les données en mémoire dans un buffer local.

    memcpy ( void * destination, const void * source, size_t num );

    Dans le cadre de mon exemple:

    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
     
     
    int buffer_data;
     
     
    typedef struct
    {
    int* DataPtr;
    int DataLength;
    }InfoType
     
    void Function(int Buffer, InfoType* InfoPtr)
    {
     
    (VOID)memcpy(&(buffer_data), ((*InfoPtr).DataPtr), InfoPtr->DataLength);
     
     }
    Le fait est que j'ai toujours quelques doutes quand a l'adressage et le pointage des données. J'éprouve quelques difficultés a jouer avec cela pour le moment.

    Merci d'avance pour vos réponses.

    Cordialement,

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 853
    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 853
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (*px).DataLength = ...; // avec les parenthèses
    Je n'étais plus certain de la nécessité des parenthèses, merci pour la piqûre de rappel !
    Salut
    C'est parce que les parenthèses sont obligatoires (cause priorité du point sur l'étoile) que l'opérateur "->" a été créé pour simplifier...
    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]

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 497
    Billets dans le blog
    1
    Par défaut
    Dis comme ça c'est très logique !

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

Discussions similaires

  1. pointeur sur structures
    Par Seimaya dans le forum Débuter
    Réponses: 33
    Dernier message: 26/08/2007, 18h13
  2. Réponses: 6
    Dernier message: 07/07/2007, 18h12
  3. pointeur sur structure
    Par julien.63 dans le forum C
    Réponses: 7
    Dernier message: 04/06/2007, 17h50
  4. problème pointeur sur structure
    Par lejohn dans le forum C
    Réponses: 9
    Dernier message: 01/05/2007, 13h17
  5. Réponses: 2
    Dernier message: 21/03/2007, 10h55

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