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 :

taille d'un pointeur


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    février 2013
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : février 2013
    Messages : 170
    Points : 17
    Points
    17
    Par défaut taille d'un pointeur
    bonjour,

    Quelque chose me chiffonne en C/C++:
    un prof expérimenté d'informatique nous explique que la taille d'un pointeur est unique et cela quelque soit son type(int*,float*,long*,char*,void*,...)
    Cette taille correspond à l'architecture du pc:si c'est un processeur 64 bits,on pourra adresser à tous les pointeurs une taille de 2^64 octets dans la RAM.
    si c'est un processeur 32 bits,on pourra adresser à tous les pointeurs une taille de 2^32 octets dans la RAM

    Pourtant,quand on effectue des opérations sur les pointeurs,les sauts ne sont pas les même selon le type de pointeur:
    Par exemple,un char prend 8 octets et s'il s'agit de char *p,le passage de p à p+1 fera un saut de 8 octets
    Un short prend 16 octets et s'il s'agit de short *p,le passage de p à p+1 fera un saut de 16 octets
    etc...

    Ma question:
    Comment concilier et expliquer cette unicité de taille de pointeur alors que leurs sauts varient selon le type de pointeur?

    merci de votre aide

  2. #2
    Membre éclairé Avatar de viper1094
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2019
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2019
    Messages : 570
    Points : 839
    Points
    839
    Par défaut
    Bonjour,

    Un pointeur est une adresse mémoire, un simple nombre. Supposons que nous ayons 20 cases mémoires. Nous avons donc le pointeur pointant sur 0, sur 1, sur 2.. jusque 20. Pour représenter les nombres de 1 à 20, on a donc toujours un type de la même taille (un int, qui va en général faire 8 octets sur une architecture 64 bits si je ne dis pas de bêtises). Le pointeur fait donc la même taille.

    Ajoutons à l'équation deux types, un type A, prenant 2 cases mémoires, et un type B, en prenant 4.
    Supposons que nous ayons un type A à l'adresse 1, stocké dans un pointeur qu'on appellera ptr_a. 1 et 2 sont donc occupés par A. Si on ajoute sizeof(A) (ici 2) à ptr_a, on se retrouve avec un pointeur pointant sur la case mémoire numéro 3.
    Si on fait très exactement la même chose avec B, on se retrouve à la case numéro 5.

    Est ce plus clair ?
    "C'est d'un ennui…"

    Shikamaru Nara

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 825
    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 : 7 825
    Points : 21 397
    Points
    21 397
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par tabkelm Voir le message
    Pourtant,quand on effectue des opérations sur les pointeurs,les sauts ne sont pas les même selon le type de pointeur:
    Par exemple,un char prend 8 octets et s'il s'agit de char *p,le passage de p à p+1 fera un saut de 8 octets
    Un short prend 16 octets et s'il s'agit de short *p,le passage de p à p+1 fera un saut de 16 octets
    etc...

    Ma question:
    Comment concilier et expliquer cette unicité de taille de pointeur alors que leurs sauts varient selon le type de pointeur?
    Tu confonds "taille du pointeur" et "taille de l'élément qui est pointé"

    Un pointeur c'est juste une variable qui contient une adresse. Et une adresse, dans un ordi, a toujours la même taille. Jusque là, tu as tout à fait raison.

    Maintenant, un pointeur n'a de sens que si à terme on utilise ce vers quoi il pointe et ça aussi il faut le connaitre. Donc (par exemple) que se passe-t-il avec un long. Un long est une variable qui s'étend sur 4 octets. Si le long se trouve à l'adresse 0x1000, alors il s'étendra sur 0x1000, 0x1001, 0x1002 et 0x1003. Mais le pointeur qui contient l'adresse de ce long ne contient que 0x1000. Toutefois c'est parce que tu as déclaré ce pointeur comme pointeur sur long (long *pt) que le compilateur sait que le contenu "*pt" fait 4 octets et saura alors comment traiter (par exemple) l'instruction printf("%ld", *pt). C'est pour ça qu'il faut toujours faire attention aux types donnés à nos pointeurs (sinon ça aurait été beaucoup plus simple de créer un type unique "ptr" mais voilà, le C a aussi besoin de connaitre la taille du pointé). Et c'est aussi pour ça qu'il est très mauvais de cacher un pointeur derrière un typedef comme je le vois souvent faire par beaucoup de débutants qui ont peur de cette étoile (ou comme je le vois souvent conseillé par certains profs de C qui, eux non plus, ne semblent pas vraiment maitriser cette notion et qui préfèrent s'en débarasser de cette façon). Un programmeur de C a besoin de connaitre ce sur quoi pointent ses pointeurs s'il veut pouvoir les manipuler correctement.

    Ainsi, en écrivant long *pt, tu déclares 2 choses
    1. pt est une variable de type "adresse"
    2. *pt est une valeur de type "long"


    Ensuite, puisque tout est connu, c'est uniquement pour simplifier la vie du codeur que les concepteurs du C ont défini que l'addition d'un pointeur correspondrait à un décalage de la taille de ce qu'il pointe. Parce que dans 99,8% des cas, quand on écrit "pt+1" c'est qu'on a l'intention de récupérer l'élément pointé qui vient après (en considérant que ce qu'il y a après est de même nature, ce qui est le cas de tableaux).
    Et dans les 0.2% restants, si on veut traiter les cases 0x1000, 0x1001, 0x1002 et 0x1003 de façon individuelle, on peut alors utiliser le cast => ((char*)pt) + 1.
    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

  4. #4
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 229
    Points : 7 262
    Points
    7 262
    Par défaut
    Cela c'est ce qu'on appelle "l'arithmétique des pointeurs" (<- lien developpez.com)

    Tu n'as pas à te prendre la tête, c'est le compilateur qui ajuste tout seul le décalage réel à faire
    Seul les pointeurs génériques void* génèrent des erreurs. Et donc tu n'as qu'à considérer que la mémoire en C est un immense tableau contiguë :
    • un pointeur + X -> on avance de X éléments de même type
    • un pointeur - X -> on recule de X éléments de même type
    • un pointeur1 - un pointeur2 (de même type) -> on prend le nombre d'éléments entre + 1.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 825
    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 : 7 825
    Points : 21 397
    Points
    21 397
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par foetus Voir le message
    Tu n'as pas à te prendre la tête, c'est le compilateur qui ajuste tout seul le décalage réel à faire
    Oui, on peut aussi l'expliquer comme ça
    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

  6. #6
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    février 2013
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : février 2013
    Messages : 170
    Points : 17
    Points
    17
    Par défaut
    l'adresse d'un pointeur est en hexadécimal.
    Selon que le processeur du pc soit en 64 bits ou en 32 bits,comment diffère la taille de cet hexadécimal?

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

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

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 113
    Points : 40 515
    Points
    40 515
    Par défaut
    Le pointeur n'est pas en hexadécimal, on l'exprime couramment en hexadécimal.
    Et pour l'exprimer en hexadécimal, le nombre de "digits" sera (sizeof(void*)*CHAR_BIT+3)/4 (nombre de bits /4, arrondi au supérieur).
    À cela, on peut rajouter un éventuel préfixe, un caractère nul de fin de chaîne, etc.
    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.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    février 2013
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : février 2013
    Messages : 170
    Points : 17
    Points
    17
    Par défaut
    ...et comment varie la taille de cette adresse en fonction de l'architecture du processeur(16,32 ou 64 bits)?

  9. #9
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 229
    Points : 7 262
    Points
    7 262
    Par défaut
    Citation Envoyé par tabkelm Voir le message
    l'adresse d'un pointeur est en hexadécimal.
    Il faut revoir tes cours de mathématiques mon cher

    Le système décimal est en base 10. Donc 10 chiffres : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Et donc 781 vaut à 1*10^0 + 8*10^1 + 7*10^2

    Le système hexadécimal est en base 16 et est préfixé par "0x". Donc 16 chiffres : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. Et donc 0x781 vaut en décimal 1*16^0 + 8*16^1 + 7*16^2

    Il y a d'autres systèmes : binaire (1 et 0), sexagésimal (base 60, pour les secondes/ minutes/ heures) et octal (8 chiffres: 0, 1, 2, 3, 4, 5, 6, 7 et est préfixé par "0")

    Et donc 174 = 0xAE = 0256 = 10101110

    Le système hexadécimal est pratique parce que 1 chiffre correspond à 4 bits (nibble en anglais, lien wiki en français) soit la moitié d'un octet 8 bits


    Citation Envoyé par tabkelm Voir le message
    ...et comment varie la taille de cette adresse en fonction de l'architecture du processeur(16,32 ou 64 bits)?
    La taille d'un pointeur ne varie pas un processeur de X bits ne peut adresser que 2^X bits de mémoire.

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

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

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 113
    Points : 40 515
    Points
    40 515
    Par défaut
    Sur une PC sous Windows 64 bits, on peut programmer pour Win32 (pointeurs de 32 bits, soit 4 octets, donc 8 chiffres hexadécimaux) ou Win64 (pointeurs de 64 bits, soit 8 octets, donc 16 chiffres hexadécimaux) selon les flags qu'on passe au compilateur et à l'éditeur de liens.

    Les processus des deux types cohabitent, mais un seul processus ne peut pas avoir des DLLs de deux bitness différentes.
    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.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    février 2013
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : février 2013
    Messages : 170
    Points : 17
    Points
    17
    Par défaut
    merci pour cette dernière réponse qui seule résout mon incompréhension

  12. #12
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 229
    Points : 7 262
    Points
    7 262
    Par défaut
    Et avant que tu ne poses la question suite à la réponse de @Médinoc, les processeurs x86 64 bits sont compatibles 32 bits.

    Mais en mode 32 bits au niveau de la mémoire, cela ne change rien ... sauf pour ton programme qui aura accès qu'à 2^32 bits de mémoire (taille des pointeurs 4 octets au lieu de 8).
    C'est juste que la taille des instructions processeur (ADD, MOV, ...) ne font que 32 bits de large (étonnant non )
    Et donc, ton processeur 64 bits, lui qui travaille avec des instructions processeur de 64 bits de large, va devoir couper en 2 les instructions en mode 32 bits. C'est pour cette raison que c'est un chouïa + lent

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 825
    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 : 7 825
    Points : 21 397
    Points
    21 397
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tabkelm Voir le message
    Citation Envoyé par tabkelm Voir le message
    Pourtant,quand on effectue des opérations sur les pointeurs,les sauts ne sont pas les même selon le type de pointeur:
    Par exemple,un char prend 8 octets et s'il s'agit de char *p,le passage de p à p+1 fera un saut de 8 octets
    Un short prend 16 octets et s'il s'agit de short *p,le passage de p à p+1 fera un saut de 16 octets
    etc...

    Citation Envoyé par Médinoc Voir le message
    Sur une PC sous Windows 64 bits, on peut programmer pour Win32 (pointeurs de 32 bits, soit 4 octets, donc 8 chiffres hexadécimaux) ou Win64 (pointeurs de 64 bits, soit 8 octets, donc 16 chiffres hexadécimaux) selon les flags qu'on passe au compilateur et à l'éditeur de liens.

    Les processus des deux types cohabitent, mais un seul processus ne peut pas avoir des DLLs de deux bitness différentes.
    merci pour cette dernière réponse qui seule résout mon incompréhension
    Super, merci pour les autres qui ont répondu . Personnellement je ne vois pas trop le rapport entre sa réponse et les opérations sur les pointeurs donc je ne vois pas le rapport entre ton incompréhension et ta question initiale
    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

  14. #14
    Expert éminent
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    mai 2010
    Messages
    2 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : mai 2010
    Messages : 2 754
    Points : 8 471
    Points
    8 471
    Par défaut
    Citation Envoyé par tabkelm Voir le message
    ...et comment varie la taille de cette adresse en fonction de l'architecture du processeur(16,32 ou 64 bits)?
    Cela ne dépend pas forcément des processeurs 8/16/32 bits.
    En gros on peut avoir un proc 8 bits et pouvoir adresser 16 bits de données (donc un pointeur fera 16 bits ici).
    Et rien n’empêche d'avoir un processeur 64 bits qui peut adresser plus.

    Pour les proc 16 bits c'est plus complexe, la plupart peuvent souvent adresser plus (le x86 pouvait adresser jusqu'a 1Mo, mais si on prend un 68k, il peut facilement adresser 32 bits ).

  15. #15
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    ...
    Inscrit en
    juin 2009
    Messages
    4 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : ...

    Informations forums :
    Inscription : juin 2009
    Messages : 4 306
    Points : 12 938
    Points
    12 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tabkelm Voir le message
    Par exemple,un char prend 8 octets [...]
    Un short prend 16 octets
    [Détail] C'est possible mais en général ce sera plutôt 8 bits pour les chars et 16 bits pour les shorts.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/03/2010, 22h40
  2. Taille d'un pointeur de fonction (delegate)
    Par yocks dans le forum C#
    Réponses: 2
    Dernier message: 13/05/2009, 11h07
  3. Taille d'un pointeur NULL
    Par Bakura dans le forum C++
    Réponses: 28
    Dernier message: 03/03/2008, 03h51
  4. Taille d'un pointeur
    Par emprex dans le forum Débuter
    Réponses: 15
    Dernier message: 03/02/2008, 11h59
  5. Taille d'un pointeur
    Par oranoutan dans le forum Débuter
    Réponses: 9
    Dernier message: 08/06/2007, 00h06

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