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 :

Un pointeur dans une union


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut Un pointeur dans une union
    Bonjour, comme pour habitude ces derniers jours, j'ai pleins de questions, je veux être sûr de comprendre.

    Si j'ai une union telle que celle ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    union
    {
    char * p;
    struct
    {
    int q;
    char o;
    } s;
    } u;
    On est d'accord que l'adresse de p est la même que s et q ?
    Mais si j'alloue de la mémoire à p, je n'accède pas à ses valeurs grâce à q et o, étant donné que ce dernier pointe vers un nouvel emplacement mémoire ?
    Mais si je lis q ou o, je lis quoi dans ce cas ?

    merci d'avance, et merci encore à tout ceux qui osé m'aider

  2. #2
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut
    sur mon compilateur les pointeurs et les int ont la même taille mémoire et je lis dans p et q la même chose ... dans o je lis n'importe quoi.

    A+

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 105
    Par défaut
    Bonjour dafpp,

    alors, je vais d’abord faire une petite représentation un peu différente, avec indentation, sa passe toujours mieux (en tout cas j'y vois déjà plus clair)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    union{
        char * p;
        struct{
            int q;
            char o;
        } s;
    } u;
    Citation Envoyé par dafpp Voir le message
    On est d'accord que l'adresse de p est la même que s et q ?
    et bien non, je ne suis pas d'accord, l'adresse de ton pointeur p est différente de celle de ta structure s qui est aussi différente que celle de ton entier q.

    Citation Envoyé par dafpp Voir le message
    Mais si j'alloue de la mémoire à p, je n'accède pas à ses valeurs grâce à q et o, étant donné que ce dernier pointe vers un nouvel emplacement mémoire ?
    alors, il ne faut pas confondre l'adresse de ton pointeur p et l'adresse vers laquelle il pointe, sachant qu'il ne contient rien, il pointe sur n'importe quoi, c'est pour sa qu'on initialise généralement les pointeurs (sur NULL quand tu n'as pas immédiatement d'adresse à lui faire pointer)

    edit: si tu veux accéder aux valeurs de p après une allocation mémoire, tu devras utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    u.p[/*ce que tu veux*/] //dans la mesure où tu utilise bien ton union u
    Citation Envoyé par dafpp Voir le message
    Mais si je lis q ou o, je lis quoi dans ce cas ?
    et bien, si tu lis q ou o, il te renvoie n'importe quoi, étant donné qu'ils n'ont pas de valeur, si tu veux lire leur emplacement mémoire, c'est &q et &o qu'il faut lire, mais je ne sais pas vraiment, si c'est ce que tu cherche, si leur emplacement mémoire est à suivre ou non, ou si ils ont le moindre rapport entre eux.

  4. #4
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut
    salut !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    union{
        char * p;
        struct{
            int q;
            char o;
        } s;
    } u;
    void main(void){
    	printf("&p=%p\n&q=%p\n&s=%p\n&u=%p\n",
    	&(u.p), &(u.s.q), &(u.s), &u);
    }
    produit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    &p=004020D0
    &q=004020D0
    &s=004020D0
    &u=004020D0
    avec mon compilateur...

    A+

  5. #5
    Modérateur

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

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    On recommence cette discussion a moit', non ?

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 105
    Par défaut
    bon bah visiblement sa dépend du compilateur car là il y a de sacrés écarts de réponses

  7. #7
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    Citation Envoyé par anacharsis Voir le message
    salut !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    union{
        char * p;
        struct{
            int q;
            char o;
        } s;
    } u;
    void main(void){
    	printf("&p=%p\n&q=%p\n&s=%p\n&u=%p\n",
    	&(u.p), &(u.s.q), &(u.s), &u);
    }
    produit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    &p=004020D0
    &q=004020D0
    &s=004020D0
    &u=004020D0
    avec mon compilateur...

    A+
    Moi j'avais lu ça, mais donc ça ne serait pas pareil selon les compilos...
    Aie aie, comment je fais dans ce cas pour éviter ça et pour être sûr de ne pas avoir le problème d'avoir des adresses diffèrentes.
    Car dans la définition de l'union, le résultat de anarchis est normal - de même pour la structure:
    Il faut simplement respecter les tailles, que la taille de p soit la même que s, étant donné que c'est une union, si je respecte ça, je n'aurai pas de soucis d'espaces mémoire non contigus ?

    Donc pour revenir à ma dernière question, ici, si je lis o ou q, ça me lit un espace mémoire, mais qui ne représente pas vraiment grand chose ?

  8. #8
    Modérateur

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

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    What ???? J'avais rédigé un message et il a sauté ! Bon, je le recommence

    Je disais que j'avais plusieurs machines sous la main et que j'ai testé.

    Windows XP / CodeBlocks :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    &p=00404040
    &q=00404040
    &s=00404040
    &u=00404040
    RedHat / GCC :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    > a.out
    &p=0x6008a0
    &q=0x6008a0
    &s=0x6008a0
    &u=0x6008a0
    > gcc --v
    Using built-in specs.
    Target: x86_64-redhat-linux
    Configured with: [...]
    Thread model: posix
    gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)
    Solaris (SunOS 5.10) / GCC
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a.out
    &p=20918
    &q=20918
    &s=20918
    &u=20918
     
    Reading specs from /usr/local/lib/gcc/sparc-sun-solaris2.10/3.4.6/specs
    Configured with: [...]
    Thread model: posix
    gcc version 3.4.6

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    On a déjà répondu dans l'autre discussion...

    Citation Envoyé par dafpp Voir le message
    Si j'ai une union telle que celle ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    union
    {
    char * p;
    struct
    {
    int q;
    char o;
    } s;
    } u;
    On est d'accord que l'adresse de p est la même que s et q ?
    Oui, c'est la définition de l'uniion.


    Citation Envoyé par dafpp Voir le message
    Mais si j'alloue de la mémoire à p, je n'accède pas à ses valeurs grâce à q et o, étant donné que ce dernier pointe vers un nouvel emplacement mémoire ?
    l'adresse de p n'est pas le contenu de p.. Quand tu alloues de la mémoire, tu ne modifies pas l'adresse du pointeur, mais son contenu (vers où il pointe)


    Citation Envoyé par dafpp Voir le message
    Mais si je lis q ou o, je lis quoi dans ce cas ?
    n'importe quoi... suivant la définition respective d'un pointeur, d'un int, et d'une struct.

    Normalement une struct et un pointeur devraient avoir le même type (pointeur)

    Par contre, il n'est pas du tout évident que le type pointeur soit du type int.

    Si tu te trouves sur un système où c'est équivalent, tu pourrais lire (en hexa) la même valeur. Sauf que ça n'a pas d'ntérêt..

  10. #10
    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
    Il y a des spécifications particulières garanties pour les structures/union. Pour résumer et en simplifiant la formulation :

    L'adresse d'une structure est l'adresse de son premier membre (en faisant les cast qui conviennent) (le cas où ce membre est un champ de bits est particulier). Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct
    {
       int a;
       int b;
    } x;
     
    int * p = (int*)&x //pointe sur a
    L'adresse d'une union est l'adresse de ses membres (en faisant les cast qui conviennent)

    @souviron34
    Normalement une struct et un pointeur devraient avoir le même type (pointeur)
    ????

    Par contre, il n'est pas du tout évident que le type pointeur soit du type int.
    Un type pointeur n'est pas un type entier

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par diogene Voir le message
    @souviron34????
    Je ne sais pas comment se passe, à la compilation, le stockage de la définition d'une structure, mais, vu que elle peut contenir n'importe quoi, je suppose que cela doit être du type pointeur.. (c'est ce que je voulais dire. Je me suis mal exprimé sans doute)

    Me trompe-je ?

    (même si nous on l'utilise avec le mot-clé struct)


    Citation Envoyé par diogene Voir le message
    Un type pointeur n'est pas un type entier
    C'est bien ce que j'ai dit...

    J'ai juste dit qu'il peut y avoir des architectures/compilateurs/versions pour lesquelles un pointeur est de type entier... (après tout c'est une adresse. Et en gros c'était souvent le cas jusqu'au 64 bits. C'est comme le truc du time_t, qui en fait était entier jusqu'au Y2K bug)

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dafpp Voir le message
    Mais si j'alloue de la mémoire à p, je n'accède pas à ses valeurs grâce à q et o, étant donné que ce dernier pointe vers un nouvel emplacement mémoire ?
    Salut

    Tu ne peux pas allouer de mémoire à "p" car "p" est une variable donc il a déjà une zone qui lui est réservée.
    Ce que tu peux faire, c'est
    1) demander au système de t'allouer à toi de la mémoire, ce qui se fait via malloc()
    2) récupérer et stocker l'adresse de début de la zone allouée dans p => u.p=malloc(...)

    A partir de là, il n'y a aucune différence fondamentale entre u.p=malloc(...) et u.s.o=getchar()
    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]

  13. #13
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    D'accord, merci, mes doutes se sont dissipés.

    -- je pensais avoir mal fait avec l'histoire de l'autre topic de char p[] et char * p -- les deux étaient liés.

  14. #14
    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
    @souviron34
    Je ne sais pas comment se passe, à la compilation, le stockage de la définition d'une structure, mais, vu que elle peut contenir n'importe quoi, je suppose que cela doit être du type pointeur.. (c'est ce que je voulais dire. Je me suis mal exprimé sans doute)
    Je ne comprend pas ce que tu veux dire. Pourquoi une structure demanderait-elle un comportement différent de celui d'un autre type de données ?

    Envoyé par diogene
    Un type pointeur n'est pas un type entier
    C'est bien ce que j'ai dit...
    Pas tout à fait, tu dis qu' "il n'est pas évident que ce soit ...", alors que je dis "il est évident que ce n'est pas..." autrement dit que ce n'est pas. C'est plus catégorique.

    J'ai juste dit qu'il peut y avoir des architectures/compilateurs/versions pour lesquelles un pointeur est de type entier... (après tout c'est une adresse...
    Une adresse en C n'est jamais un type entier : les opérations définies sur les adresses ne sont pas celles définies sur les entiers. Quant à interpréter la représentation binaire du codage de l'adresse comme un entier, on peut le faire avec n'importe quel type de données sans que ça présente un quelconque intérêt. De plus, un tel point de vue (qui veut prendre en compte la représentation binaire du codage de l'adresse) abaisse le niveau d'abstraction du C et introduit une regrettable confusion dans les esprits.

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    c'est à moi que tu t'adresses et non à Sve@r ...

    Ce que je voulais dire (mais j'ai l'esprit un peu tordu) était que si on écrit :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    union
    {
    char * p;
    struct
    {
    int q;
    char o;
    } s;
    } u;

    s, que l'on n'utilise jamais seul, est pourtant "défini".. L'adresse de départ de l'union (u) étant la même pour tous les membres de l'union, c'est donc bien cela : une adresse..

    On décrit cela dans le langage comme une structure, mais elle a bien une adresse de départ..

    M'enfin, ce que j'en dis...


    Quant au type, vu qu'il n'existe pas à proprement parlé de type primitif "pointeur" comme il existe "int", ou "double", mais que c'est un "type" déduit, défini par le caractère "*" devant le type primitif pour lequel on veut un pointeur, il pourrait prendre n'importe quelle forme, et il a été longtemps assimilé à un entier, puisque c'est en fait une adresse.

    Je suis d'accord avec toi que cela peut induire une confusion, mais là n'était pas mon propos dans le post en question...

  16. #16
    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
    c'est à moi que tu t'adresses et non à Sve@r ...
    J'ai corrigé pour ne pas me faire incendier par Sve@r (à qui je présente mes plus humbles excuses)

    On décrit cela dans le langage comme une structure, mais elle a bien une adresse de départ..
    Mais tout objet en C a une adresse de départ, et c'est pourquoi je ne comprend pas trop ce que tu veux dire. Mais passons...

    Quant au type, vu qu'il n'existe pas à proprement parlé de type primitif "pointeur" comme il existe "int", ou "double", mais que c'est un "type" déduit, défini par le caractère "*" devant le type primitif pour lequel on veut un pointeur,
    Je vois plutôt la question comme "il n'existe pas à proprement parler un type "pointeur" mais des types "pointeur sur ..." avec autant de types différents que de possibilités pour les '...' ". Leur dépendance d'un autre type (le type pointé) les a fait qualifiés de "types dérivés" mais il n'empêche qu'ils sont également, de mon point de vue, très "primitifs", c'est à dire complètement définis au départ dans le langage (par opposition avec struct/union dont la composition intime dépend du programmeur). Mais ce n'est guère qu'une question de vocabulaire.

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

Discussions similaires

  1. Pointeur dans une fonction ?
    Par sliiim6184 dans le forum C
    Réponses: 4
    Dernier message: 28/12/2006, 11h32
  2. Réponses: 2
    Dernier message: 26/11/2006, 10h51
  3. Libérer des pointeurs dans une std::map
    Par GaldorSP dans le forum SL & STL
    Réponses: 2
    Dernier message: 09/07/2005, 14h42
  4. Réponses: 2
    Dernier message: 15/11/2004, 15h12
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14

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