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 :

Arithmétique des pointeurs


Sujet :

C

  1. #1
    Membre actif
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Septembre 2009
    Messages
    458
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ressources humaines

    Informations forums :
    Inscription : Septembre 2009
    Messages : 458
    Points : 237
    Points
    237
    Par défaut Arithmétique des pointeurs
    Salut à tous,

    Voilà, je débute avec les pointeurs et je galère un peu…

    Dans cet exercice, par exemple, la réponse est 5210 mais je ne sais vraiment pas comment il faut procéder ??

    Si PI, qui est un pointeur d'entiers codés sur 72 bits, est stocké à l'adresse 7793 et contient l’adresse 7811, et que N, qui est une variable de type char, a été initialisée avec le caractère Espace, quelle est l’adresse désignée par l’expression :
    --PI – N-- * sizeof(*(++PI))
    Est-ce que quelqu'un pourrait m'expliquer comment vous faites pour avoir cette réponse s'il vous plaît ??? D'avance merci beaucoup.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Bonjour,

    C'est assez simple : il te suffit de retenir que l'adresse renvoyée par un pointeur correspond bien à l'endroit exact en mémoire de ce qu'il pointe, mais que son arithmétique utilise comme unité la taille de l'objet pointé et pas l'octet (ou le mot mémoire de base utilisé par le micro-processeur). Ainsi, si « p » pointe un entier 32 bits (de quatre octets, donc) à l'adresse 0x8000, alors « p + 1 » pointera en 0x8004.

    Ensuite, il est vivement déconseillé d'utiliser les opérateurs de pré ou post incrémentation ou décrémentation « ++ » et « -- » au sein d'une expression algébrique plus complexe parce qu'il n'est pas garanti que l'opération en question se produira au moment où on le croit. Mais pour le moment, on va considérer qu'il n'y a pas de piège à ce niveau-là.

    Enfin, il faut tenir compte de la priorité des opérateurs. L'opérateur de multiplication « * » est bien sûr prioritaire sur « + » et « - », comme à l'école, mais c'est vrai aussi pour les autres opérateurs C : http://www.difranco.net/compsci/C_Op...ence_Table.htm

    De là :
    • PI pointe des entiers de 72 bits. Divisé par 8, cela représente des éléments de neuf octets. On considère que tu travailles sur une architecture habituelle qui mesure sa mémoire en octets et qu'il n'y a pas de bourrage entre tes éléments ;
    • On se moque de savoir où le pointeur lui-même est enregistré. Ce qui nous intéresse ici, c'est sa valeur, donc l'adresse qu'il pointe ;
    • « --PI » va décrémenter PI, qui va donc passer de 7811 à 7802 (un élément en moins, donc -9 octets) ;
    • « N-- » va décrémenter N, mais seulement après l'avoir évaluée, donc on ne s'occupera que de sa valeur initiale ;
    • N est une variable de type char, qui est un fait un entier signé. Cette variable contient un espace, donc le code ASCII est notoirement 32 ;
    • sizeof te donne la taille en octets (plus précisement en char, mais passons) de ce que tu lui indiques. Comme il y a une étoile, c'est la taille de ce qui est pointé par (PI++) qui nous intéresse. Donc, ici, quelque soit la valeur de PI, le résultat sera toujours 9 (la taille des entiers de 72 bits) ;
    • 32 × 9 = 288 ;
    • Tu vas donc retrancher 288 unités à PI, qui avait déjà été décrémenté pour arriver à 7802 ;
    • Plus précisément, tu vas retrancher 288 unités de neuf octets de long, ce qui va donner 32 × 9 × 9 = 2592 ;
    • 7802 - 2592 = 5210.


    On notera d'une part que le sizeof est donc superflu et, en faisant le travail deux fois, nous fait décrémenter des unités de 81 octets au lieu de 9 (erreur assez fréquente en C). On remarquera d'autre part que l'exercice est vraiment tordu en soi, pour le principe, et qu'on évitera autant que possible de recourir à ce genre d'expression quand on développera en conditions réelles.

  3. #3
    Membre actif
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Septembre 2009
    Messages
    458
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ressources humaines

    Informations forums :
    Inscription : Septembre 2009
    Messages : 458
    Points : 237
    Points
    237
    Par défaut
    Bonjour Obsidian

    Waaaaawww ! Merci beaucoup pour tes explications.

    Je voulais juste savoir pourquoi tu divises par 8 ?? Parce que c'est un 72 bits ???

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Citation Envoyé par Tamzoro Voir le message
    Je voulais juste savoir pourquoi tu divises par 8 ?? Parce que c'est un 72 bits ???
    Simplement parce que 8 bits = 1 octet (d'où le nom).

    En C, l'unité de mémoire minimum utilisé pour la représentation des pointeurs est le char, c'est-à-dire l'entier signé de taille minimum et suffisante pour représenter tous les caractères du jeu. Comme il y en a 91, il faut au moins sept bits pour les représenter. En pratique, l'unité de mémoire la plus courante et la plus pratique depuis au moins 50 ans étant l'octet, un char est en général long de 1 octet et devient de fait l'unité de référence du C comme du reste, et c'est parfait comme cela.

  5. #5
    Membre actif
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Septembre 2009
    Messages
    458
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ressources humaines

    Informations forums :
    Inscription : Septembre 2009
    Messages : 458
    Points : 237
    Points
    237
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Simplement parce que 8 bits = 1 octet (d'où le nom).

    En C, l'unité de mémoire minimum utilisé pour la représentation des pointeurs est le char, c'est-à-dire l'entier signé de taille minimum et suffisante pour représenter tous les caractères du jeu. Comme il y en a 91, il faut au moins sept bits pour les représenter. En pratique, l'unité de mémoire la plus courante et la plus pratique depuis au moins 50 ans étant l'octet, un char est en général long de 1 octet et devient de fait l'unité de référence du C comme du reste, et c'est parfait comme cela.
    Merci pour toutes tes explications, j'ai pas mal d'exercice en arithmétique des pointeurs je vais essayé de le faire maintenant.

    En tout cas je t'en suis vraiment reconnaissant d'avoir pris le temps de m'expliquer.

    Bien à toi

  6. #6
    Membre actif
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Septembre 2009
    Messages
    458
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ressources humaines

    Informations forums :
    Inscription : Septembre 2009
    Messages : 458
    Points : 237
    Points
    237
    Par défaut
    Bonjour,

    Il y a un exercice, où je bloque il est presque similaire à celui du haut:

    Citation Envoyé par Tamzoro Voir le message
    Si PI, qui est un pointeur d'entiers codés sur 64 bits, est stocké à l'adresse 2238 et contient l’adresse 2257, et que N, qui est une variable de type char, a été initialisée avec le caractère Escape, quelle est l’adresse désignée par l’expression :
    --PI – N++ * sizeof(*(--PI))

    Dans l'exercice précédant, on a vu que N faisait 32 je voulais savoir si N a toujours une valeur initiale qui est 32 ??? Comment on fait pour connaitre ça valeur initiale???

    Merci beaucoup

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Citation Envoyé par Tamzoro Voir le message
    Dans l'exercice précédant, on a vu que N faisait 32 je voulais savoir si N a toujours une valeur initiale qui est 32 ??? Comment on fait pour connaitre ça valeur initiale???
    C'est écrit dans l'énoncé : « N, qui est une variable de type char, a été initialisée avec le caractère Escape ». Reste à trouver la valeur de Escape… :-)

    Quand tu l'auras trouvée, tu pourras l'apprendre par cœur. Elle est extrêmement fréquente en informatique.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Obsidian Voir le message
    C'est écrit dans l'énoncé : « N, qui est une variable de type char, a été initialisée avec le caractère Escape ». Reste à trouver la valeur de Escape… :-)
    C'est espace, pas escape. Mais sinon superbe explication dans ton premier post (sisi, je l'ai lue intégralement en comparant chaque fois avec l'expression et en calculant de mon coté)
    Tout ça pour un exercice peut-être formateur niveau arithmétique des pointeurs mais auquel on pourra quand-même reprocher son coté totalement en dehors de tout pragmatisme voire même néfaste question "bonnes pratiques de codage". Surtout que si PI est stocké à l'adresse 7793 et contient l’adresse 7811 mais que cette valeur 7811 n'est pas une valeur accessible au programme, alors regarder ne serait-ce que PI (sans parler de --PI ni ++PI ni même *PI ni (encore pire) *(++PI)) produira un comportement indéterminé (mais comme tu l'as dit "on considèrera qu'il n'y a pas de piège à ce niveau là").

    Perso, un bon tableau de structures qu'on parcours au travers d'un pointeur dans lequel on demande sa valeur numérique dans différents cas aurait eu le même effet mais aurait donné une meilleure idée du but des pointeurs et de leurs utilisations correcte...
    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]

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    C'est espace, pas escape.
    Après ton message, je me suis relu une seconde fois par peur d'avoir posté trop tard mais il semblerait que ce soit bien escape. C'est bien vu parce qu'en presque 30 ans de programmation, je ne m'étais jamais aperçu qu'escape était l'anagramme d'espace ! C'est encore un piège vicieux. :-)

    Mais sinon superbe explication dans ton premier post (sisi, je l'ai lue intégralement en comparant chaque fois avec l'expression et en calculant de mon coté)
    Je suis obligé de reconnaître que je l'ai fait aussi pour être sûr de ne pas poster d'âneries (puisque ça m'est arrivé ici comme tout le monde)…

    Perso, un bon tableau de structures qu'on parcours au travers d'un pointeur dans lequel on demande sa valeur numérique dans différents cas aurait eu le même effet mais aurait donné une meilleure idée du but des pointeurs et de leurs utilisations correcte...

  10. #10
    Membre actif
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Septembre 2009
    Messages
    458
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ressources humaines

    Informations forums :
    Inscription : Septembre 2009
    Messages : 458
    Points : 237
    Points
    237
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    C'est écrit dans l'énoncé : « N, qui est une variable de type char, a été initialisée avec le caractère Escape ». Reste à trouver la valeur de Escape… :-)

    Quand tu l'auras trouvée, tu pourras l'apprendre par cœur. Elle est extrêmement fréquente en informatique.
    Bonjour Obsidian,

    J'ai trouvé ! C'était 27.

    Merci à toi !

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

Discussions similaires

  1. Exercice tordu sur l'arithmétique des pointeurs
    Par Tamzoro dans le forum Débuter
    Réponses: 5
    Dernier message: 20/04/2015, 16h26
  2. [LG] Comprendre mieux le principe des pointeurs
    Par maind5or dans le forum Langage
    Réponses: 4
    Dernier message: 04/10/2005, 01h06
  3. Probleme avec des pointeurs...
    Par barucca dans le forum C++
    Réponses: 5
    Dernier message: 23/08/2005, 21h05
  4. Libérer des pointeurs dans une std::map
    Par GaldorSP dans le forum SL & STL
    Réponses: 2
    Dernier message: 09/07/2005, 14h42
  5. à propos des pointeurs
    Par salseropom dans le forum C++
    Réponses: 20
    Dernier message: 24/03/2005, 09h37

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