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 régulier
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Par défaut Structures et pointeurs
    Bonjour,

    je dispose de deux structures définies comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    typedef struct {
          int a;
          int *b;
    }first;
     
    typedef struct {
          int c;
          first d;
    }seconde
    Je déclare deux variables.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    first x;
    seconde y;
    Comment accéder aux membres de chaque variable ?

    Supposons que je souhaite accéder aux membres de x:
    je devrais alors faire pour le membre a
    Mais comment faire pour l'autre membre ?

    Et comment accéder aux membres de y ? Et aux membres du membre d de y ?

    Au revoir

  2. #2
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Mais comment faire pour l'autre membre ?
    Pareil:

  3. #3
    Membre chevronné Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Par défaut
    Excuses moi, mais j'ai peur de ne pas comprendre ta question.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    typedef struct {
          int a;
          int *b;
    }first;
     
    typedef struct {
          int c;
          first d;
    }seconde
    Tu accedes au donnees comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    first     x;
    seconde   y;
    int       entier;
     
    entier = 2;
     
    x.a = 1;
    x.b = &entier;
     
    y.c = 10;
    y.d = x;
    Tu peux ensuite enfiler les structures comme bon te semble.


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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Jack_serious
    Tu peux ensuite enfiler les structures comme bon te semble.
    N'oublie pas ton petit chapeau...

  5. #5
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Par défaut
    Hello,

    Citation Envoyé par seriousme
    x.b
    Mais ne dois-je pas avant faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    x.b=malloc(sizeof(int))
    Citation Envoyé par Jack_serious
    Tu peux ensuite enfiler les structures comme bon te semble.

    Mais ne puis-je pas faire cette opération avant de faire

  6. #6
    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
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    N'oublie pas ton petit chapeau...
    On se dévergonde ?
    "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

  7. #7
    Membre chevronné Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Par défaut
    Citation Envoyé par mastochard
    Hello,


    Mais ne dois-je pas avant faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    x.b=malloc(sizeof(int))
    Oui.

    Si tu veux conserver la valeur de ton entier apres la sortie de la fonction.
    Mais tu n'est pas oblige.
    Ce n'est qu'un pointeur.
    Ici je l'ai fait pointer sur un entier existant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    x.b = malloc(sizeof(*(x.b)));
    Mieux.
    Citation Envoyé par mastochard
    Mais ne puis-je pas faire cette opération avant de faire
    Si.

    Vu que ta structure est definie comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typedef struct {
          int c;
          first d;
    }seconde

    La structure seconde contient une structure first. Donc oui tu peux affecter quelque chose directement a "y.d.a".
    Je me suis contente de recopier la variable x dans y.d.

  8. #8
    Membre chevronné Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    N'oublie pas ton petit chapeau...
    Toujours faire attention au fuites quand on code...

  9. #9
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Par défaut
    Si tu veux conserver la valeur de ton entier apres la sortie de la fonction.
    Mais tu n'est pas oblige.
    Ce n'est qu'un pointeur.
    Ici je l'ai fait pointer sur un entier existant.
    En fait, je ne veux pas conserver la valeur après la sortie de la fonction.
    Dans cette fonction, j'appelle une autre fonction dans laquelle je passe en paramètre un pointeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    typedef struct {
        int *b;
    }first;
     
    void maFonction(){
    first x;
     
    //Avant de passer en paramètre mon entier, je dois initialiser le pointeur.
    x.b=malloc(sizeof(int));
         monAutreFonction(x.b);
    }
    T d'accord avec ça ?

    Au revoir

  10. #10
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Par défaut
    Encore un truc aussi:

    avec le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    x.b = malloc(sizeof(int));
    x.b=0;
    le compilateur me signale un Warning dû à différents niveaux d'indirections et une erreur se produit.

    Merci d'avance.

  11. #11
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par mastochard
    En fait, je ne veux pas conserver la valeur après la sortie de la fonction.
    Dans ce cas pas la peine de faire une allocation dynamique. Ceci suffit largement pour ce que tu as à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    typedef struct {
         int *b;
    }first;
     
    void maFonction()
    {
        first x;
        int val;
     
        x.b = &val;
        monAutreFonction(x.b);
     }
    Le prototype de la fonction monAutreFonction() doit être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void monAutreFonction( int *ptr );

  12. #12
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par mastochard
    Encore un truc aussi:

    avec le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    x.b = malloc(sizeof(int));
    x.b=0;
    le compilateur me signale un Warning dû à différents niveaux d'indirections et une erreur se produit.

    Merci d'avance.
    Dans ton code, tu essayes d'initialiser à deux reprises ton pointeur. Tu es sûr que c'est bien ça que tu voulais faire ?
    Sur la 2eme ligne je pense que tu voulais initialiser le valeur pointée par x.b. Si c'est ça, alors il faut que tu fasses comme ceci :

  13. #13
    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
    Par défaut
    Manifestement, tu n'as pas compris ce qu'est un pointeur.
    Un pointeur est une variable contenant l'adresse d'une zone mémoire, cette adresse peut-être valide si elle a été initialisée par un malloc ou par l'affectation de l'adresse d'une donnée existante.
    Pour accéder à la valeur pointée il faut utiliser l'opérateur *.

    int *p; // déclare que p est un pointeur vers un integer, c'est à dire que la valeur de p est l'adresse où on trouvera un entier. Tel quelle cette valeur est n'importe quoi car C n'initailise pas les variables dans le corps des fonctions, il est donc prudent, à la déclaration de l'initialiser à NULL : int *p = NULL;

    p = malloc(sizeof *p); // ici tu initialises le pointeur, c'est-à-dire que malloc fournit une adresse mémoire valide qui te permettra d'utiliser cette zone pour tes actions futures. A noter que la "valeur pointée" (*p) elle est une fois de plus n'importe quoi, ce qu'il y a ait à cet endroit au moment du malloc. Autre remarque, malloc peut échouer, c'est pour celà qu'il faut TOUJOURS tester le retour de malloc. Ensuite, il est pratique de déclarer sizeof *p car si le type de p change, tu n'as pas à changer cette instruction car sizeof *p renvoie la bonne taille à allouer. Enfin, en C on peut ne pas caster le retour, contrairement au C++, c'est même recommandé, (on voit tout de suite si on a bien inclus le fichier en-tête adéquat).

    // une fois que tu as fini d'utiliser le pointeur, il est de très bon usage de libérer la zone mémoire par un
    free(p); // mais attention, la valeur de p reste inchangée, c'est toujours une adresse mémoire, mais cette adresse n'est plus valide car elle a été rendue au système, c'est pour celà que souvent, les programmeurs après le free font
    p = NULL;
    "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

  14. #14
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Par défaut
    Pour résumer,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    typedef struct {
       int *a;
    }structure;
    Donc en fait, si je veux accéder au pointeur a membre de structure, je dois faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    structure maPremiere;
    maPremiere.a;
    Evidemment, en faisant cela, vu que je n'ai pas initialisé mon pointeur j'aurais une valeur quelconque.
    Par contre, si je veux accéder à la valeur pointée, je dois faire:
    N'est-ce pas ?

    Si tu veux conserver la valeur de ton entier apres la sortie de la fonction.
    Mais pour ça, de toute manière, il faut que ce pointeur soit déclaré en argument ou en variable globale ou que la fonction retourne ce pointeur, n'est-ce pas ?

    Supposons maintenant que je déclare en variable globale un pointeur:
    Comment puis-je l'initialiser dès la déclaration ?
    Je ne peux pas faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int *pVar=malloc(sizeof(int));
    et non plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int pVar=malloc(sizeof(int));
    Parce que dans ce dernier cas, ce n'est plus un pointeur.

    Et si je l'initialise dans une fonction ,il aura cette valeur à chaque fois qu'elle sera appelée.
    Et pourtant, j'aimerais initialiser mon pointeur et la valeur vers laquelle pointe le pointeur.

    Autre question, supposons que:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int *pVar;
     
    void monAutreFonction(int *pValeur){
         *pValeur=*pValeur+1;
    }
     
    void maFonction() {
          monAutreFonction(ptr);
    }
    Je pourrais aussi très bien faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int var;
     
    void monAutreFonction(int *pValeur){
         *pValeur=*pValeur+1;
    }
     
    void maFonction() {
          monAutreFonction(&ptr);
    }
    Quel interêt de passer en variable globale un pointeur ? Je me doute un peu de la réponse, "tout dépend de l'appli", mais si vous aviez un exemple qui me montre l'interêt de déclarer un pointeur en globale, ce serait cool.

    Merci d'avance.

  15. #15
    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
    Par défaut
    Quel interêt de passer en variable globale un pointeur ? Je me doute un peu de la réponse, "tout dépend de l'appli", mais si vous aviez un exemple qui me montre l'interêt de déclarer un pointeur en globale, ce serait cool.
    On va avoir du mal car il n'y en pas (en tout cas pas à ma connaissance).
    "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

  16. #16
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Par défaut
    Et sinon quand utiliser un pointeur en globale et quand cela ne sert pas ?

  17. #17
    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
    Par défaut
    Il est presque toujours inutile d'utiliser des variables globales, elles peuvent servir pour manipuler des constantes dépendant du sytème (et encore). Le problème est que souvent au début dans les petits programmes de débutant, on les utilise, mais ça devient vite une très mauvaise habitude, si on veut devenir un "pro".
    "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

  18. #18
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Par défaut
    Ok merci pour cette réponse.
    Je comprends bien.

Discussions similaires

  1. structures et pointeurs de fonctions
    Par aimad41 dans le forum C
    Réponses: 5
    Dernier message: 21/11/2006, 10h49
  2. Structures et pointeurs
    Par Tchetch dans le forum C
    Réponses: 14
    Dernier message: 19/10/2006, 13h30
  3. Structure et pointeur
    Par Nalido dans le forum C
    Réponses: 5
    Dernier message: 08/08/2006, 15h08
  4. 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
  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