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 :

Cherche tuto ou article sur les pointeurs


Sujet :

C++

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut Cherche tuto ou article sur les pointeurs
    Bonjour

    Confronté récemment à quelques lignes ce C++ sans y connaître vraiment pas grand-chose, j'ai vu l'utilisation d' & et * que je n'ai pas vraiment comprise.

    Ces & étaient positionnés devant des paramètres, devant des noms de variables, limite un peu partout :-(

    Exemples:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    bool fileCanBeOpen(std::string const & filename)
     
     
    result.push_back(coef*(*el));  // Là je me doute que * après coef est la multiplication mais celui avant el ???????
    De plus, le & est parfois tout seul et parfois collé à une variable. Tout ça est un peu confus pour moi.

    Alors je cherche un site qui m'expliquerait ça façon "les & c++pour les nulls"

    A moins qu'une âme charitable prenne le temps de faire ça ici

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ah, en fait pour le & tu te heurtes là à deux syntaxes différentes, qui font références à des concepts très différents:
    • Dans une expression, le & est lié aux pointeurs, il s'agit de l'opérateur "adresse de". On la voit ici:
      Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      int a; //Déclaration d'un entier
      int *p; //Déclaration d'un pointeur sur entier
      p = &a; //Le pointeur contient maintenant l'adresse de l'entier.
      Cette syntaxe existe aussi bien en C qu'en C++.
    • Dans une déclaration, c'est une syntaxe propre au C++, qui déclare une variable comme étant une référence à une autre. Quand on l'utilise pour déclarer des paramètres de fonction (comme dans bool fileCanBeOpen(std::string const & filename)), il s'agit plus ou moins de pointeurs déguisés. Dans l'exemple de fileCanBeOpen(), cela signifie que la chaîne filename est passée par référence à la fonction, c'est-à-dire qu'elle n'est pas recopiée. Le const indique que cette référence ne permet pas de modifier l'objet.


    Pour ce qui est de l'astérisque, elle est propre au pointeurs, mais elle aussi a deux significations légèrement différentes selon où elle se trouve:
    • Dans une expression, il s'agit de l'opérateur de déréférencement, c'est-à-dire l'opérateur d'accès à la donnée pointée. Si je reprends le code au-dessus et que j'ajoute cette ligne:
      L'entier pointé par p (ici, il s'agit de a) va recevoir la valeur 42.
    • Dans une déclaration, il indique que la variable qu'on déclare est un pointeur. int *p; déclare la variable p de type "pointeur sur int". Si je déclares un pointeur int const * const p2 = &a;, Je déclares un pointeur qui ne peut pas être modifié, et ne permet pas non-plus de modifier la valeur pointée (mais il permet de la lire).


    Note juste pour être complet: Ici, le concept d'opérateur signifie simplement une partie d'une expression qui retourne une valeur; un opérateur prend une ou plusieurs entrées, et retourne une valeur en sortie (qu'on peut ensuite mettre dans une variable, passer en paramètre à une fonction, ou ignorer).
    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.

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    On a plusieurs cours qui inclue un bon chapitre sur les pointeurs (notamment Penser en C++), regarde dans notre section tutoriels.

    En résumé:

    La mémoire d'un ordinateur est un ensemble d'octets numérotés. Ainsi, sur un ordinateur 64 bits, ces numéros vont de 0 à 2 puissance 64 (c'est à dire "beaucoup")
    Le numéro d'un octet est appelé son adresse.

    Une adresse est une valeur comme une autre, elle peut se stocker dans une variable.
    Une telle variable est appelée pointeur.

    Une spécificité des pointeurs, c'est que les adresses d'int ne sont pas compatibles avec celles de char ni celles de double (etc).

    Si p est un pointeur d'entier et i est un entier, alors:
    • p est le nom d'un bloc mémoire pouvant contenir un pointeur d'entier
    • la valeur de p est une adresse d'entier
    • i est le nom d'un bloc mémoire pouvant contenir un entier
    • la valeur de i est un entier
    • &i est l'adresse du bloc mémoire nommé i
    • *p est la valeur de l'entier contenu dans le bloc mémoire désigné par l'adresse contenue dans p
    • &p est l'adresse du bloc mémoire nommé p (c'est à dire l'adresse d'un bloc mémoire qui contient l'adresse d'un bloc mémoire qui contient un entier), c'est une valeur pour un pointeur de pointeur d'entier.
    • p = &i signifie que le programme met l'adresse de i dans la variable p.
    • *p = 2 signifie que le programme met 2 dans le bloc mémoire désigné par l'adresse contenue dans p


    Pour t'aider, considère que l'étoile signifie toujours "ce que désigne"
    Ainsi *p = 2 se lirait "ce que désigne p reçoit la valeur 2".

    En C++, il y a une subtilité supplémentaire: les références
    il est possible de déclarer des variables comme étant "un autre nom pour" une autre, et c'est écrit avec un & dans la déclaration.

    ainsi:
    • int * p, q signifie soient de type int "ce que désigne p", et q (attention au piège, l'étoile porte sur p uniquement, pas sur int, donc pas sur q.)
    • int &r = q signifie soit de type int r un autre nom de q. à partir de maintenant, r et q sont le même bloc mémoire.


    en dehors d'une déclaration de variable, le & est l'opérateur qui permet d'obtenir l'adresse de ce à quoi il s'applique (ou dans de rare cas, l'opérateur de conjonction (and) bit à bit)

    Un pointeur sert (normalement) quand on veut faire des choses dynamiques, que le programme n'est pas vraiment capable de déterminer à la compilation:
    • réservation de blocs de mémoire de taille inconnue à la compilation
    • pointeur de fonction pour choisir à l'exécution quelle fonction exécuter
    • d'autres choses, comme les listes chainées ou les graphes


    En règle générale, les pointeurs posent beaucoup de problème technique, et leur usage en C++ est de plus en plus rare, les classes de la STL comme std::vector ou std::string gérant la très grande majorité des cas.

    edit: doublé par médinoc
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Tout a été dit.

    Citation Envoyé par Médinoc Voir le message
    Si je reprends le code au-dessus et que j'ajoute cette ligne:
    L'entier pointé par p (ici, il s'agit de a) va recevoir la valeur 42.
    Faute de frappe :

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Oups, corrigé.
    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.

  6. #6
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Merci pour vos réponses que j'étudierai mieux dès ce w-e.

    Je reviendrai surement pour des précisions :-)

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    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 : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par leternel Voir le message
    Ensemble d'octets numérotés. Ainsi, sur un ordinateur 64 bits, ces numéros vont de 0 à 2 puissance 64 (c'est à dire "beaucoup")
    Le numéro d'un octet est appelé son adresse.
    Je chipote : vont de 0 à 2 puissance 48 (de mémoire, la mienne ) (c'est à dire "moins beaucoup")

  8. #8
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Bon, si je reprends
    & peut être utilisé dans les paramètres d'une fonction et dans ce cas il n'est pas accolé au nom du paramètre mais placé entre le type et le paramètre
    Le paramètre ne peut pas être modifié dans la fonction
    Si const n'est pas ajouté, on pourrait modifier le contenu et la valeur serait modifiée en sortie de fonction
    Si on ne met pas de &, on peut modifier le contenu dans la fonction mais au retour de l'appelant, le contenu a gardé sa valeur initiale

    Dans du code, ça renvoie une adresse et c'est donc l'équivalent Pascal de @


    Pour * , ça désigne un pointeur.


    Mais dans mon "monde" Delphi, un pointeur est une adresse mémoire.
    Si j'utilise un type pointeur comme paramètre d'une fonction, ça veut dire que je peux modifier le contenu de l'adresse mémoire pointée.


    Est-ce qu'on peut utiliser un type pointeur comme type de paramètre dans une déclaration de fonction ??

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    & dans la déclaration d'une variable est pour une référence, qui est un allias sur une variable
    Est-ce qu'on peut utiliser un type pointeur comme type de paramètre dans une déclaration de fonction ??
    Bah... oui.
    Mais dans mon "monde" Delphi, un pointeur est une adresse mémoire.
    Si j'utilise un type pointeur comme paramètre d'une fonction, ça veut dire que je peux modifier le contenu de l'adresse mémoire pointée.
    Et c'est strictement identique.

    Si on ne met pas de &, on peut modifier le contenu dans la fonction mais au retour de l'appelant, le contenu a gardé sa valeur initiale
    Si tu mets pas de & (et pas de * non-plus), le paramètre est une variable créée par copie.
    En fait le pointeur est aussi une copie, mais comme c'est l'emplacement pointé qui nous intéresse en général, on s'en moque.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool fileCanBeOpen(std::string  *filename)
    Quelque chose dans le genre, c'est la bonne syntaxe pour avoir une chaîne de caractères modifiable ?

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Non

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool fileCanBeOpen(std::string& filename)

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool fileCanBeOpen(std::string  *filename)
    Quelque chose dans le genre, c'est la bonne syntaxe pour avoir une chaîne de caractères modifiable ?
    Disons que c'est quelque chose qui techniquement marcherait, mais ce n'est pas la façon recommandée.
    Voir le message de bacelar.

    PS: Je dois avouer que je suis assez hostile à la façon recommandée, parce que je n'aime pas les passages de paramètre modifiable sans une syntaxe qui le signale au moment de l'appel (comme c'est le cas en C#). Mais le gain en sécurité (plus de crainte de pointeur nul, etc.) compense la perte de lisibilité.
    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.

  13. #13
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Non

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool fileCanBeOpen(std::string& filename)
    Là, le & est collé à string.

    Dans la ligne copier-coller que j'avais au départ

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool fileCanBeOpen(std::string const & filename)
    Est-ce à cause du const ajouté que le & est seul dans la déclaration ?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Collé ou pas, ça ne change rien, ce n'est qu'une question de style. Les gens vont avec ce qui leur parait le plus explicite.
    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.

  15. #15
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    en fait, comme string& n'est pas un identifieur valide, il est décomposé en deux: string, puis & (et de même pour const&).
    Les espaces sont globalement superflux.

    De même, tu aurais pu écrire bool fileCanBeOpen(std::string const &filename).

    En C++, comme en C, le mot clé const porte sur le type situé à sa gauche, ou le mot à sa droite s'il n'y a rien à gauche. C'est pour cela que le fameux char const* est un pointeur modifiable de caractère constant. C'est aussi pour éviter la confusion avec un pointeur constant de caractère (un char * const) qu'on préfère placer le const à gauche dans le cas d'un pointeur (const char*).

    Cela dit, les formes possibles pour une référence sur constante sont:
    • std::string const & filename, qui regroupe la constance et la référence: le type "utile" est en premier, et le "bruit" technique placé après: l'utilisateur a surtout besoin de savoir que c'est une string, la référence sur constante est un détail qui pollue moins
    • std::string const& filename, la forme compacte de la précédente.
    • const std::string & filename, forme historique venue des vieilles habitudes du c (et des const char*)


    Les arguments en faveur de l'une ou l'autre sont de grands sujets de troll, que l'on tranche normalement par "comme tu veux, tant que c'est cohérent et réfléchi"
    Personnellement, je préfère la forme type const& nom parce que cela ressemble à un seul mot modificateur.
    J'ai ainsi cinq modificateurs possibles: rien, const& et & et const* et * (qui aurai pu être des mots clés: copy, reference, mutable, potential et pointer)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  16. #16
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    J'ai installé CodeBlocks et je ferai quelques essais de code dès que je pourrais.

    Ce serait pas mal pour moi d'avoir quelques notions plus poussées sur ce langage et je reviendrai surement vous "casser les pieds" avec des questions de débutant.

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

Discussions similaires

  1. Cherche Article sur les types de plus de 64 bits
    Par rvzip64 dans le forum Langage
    Réponses: 2
    Dernier message: 17/02/2009, 18h41
  2. cherche tuto ou exemple sur les sockets unix
    Par razam dans le forum Réseau
    Réponses: 14
    Dernier message: 24/10/2007, 17h18
  3. Réponses: 5
    Dernier message: 20/09/2007, 16h43
  4. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 17h50

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