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

Langage C++ Discussion :

passage par référence en C++


Sujet :

Langage C++

  1. #1
    Membre régulier
    Homme Profil pro
    Programmeur PHP
    Inscrit en
    Août 2009
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Israël

    Informations professionnelles :
    Activité : Programmeur PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2009
    Messages : 244
    Points : 114
    Points
    114
    Par défaut passage par référence en C++
    Salut,
    Dapres ce que je sais d'un cours se nommant les principes des languages de programmation.
    Un passage d'un objet par reference est le passage de l'adresse de cette objet (a une fonction).
    Et dapres ce que je connais du C++, le passage par reference est une copie de l'adresse sur laquelle un pointeur pointe en mémoire.
    Résultat:
    Du point de vue du programmeur cela revient au meme.
    Mais du point de vue du code, il y a eu une copie et donc ce n'est pas vraiment un passage par reference?
    J'ai faux?

  2. #2
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Hum pour simplifier les choses, j'ai vu les références de cette manière:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void toto(std::string &str)
    {
      str="bobby";
    }
    reviens au meme que:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void toto(std::string *tmp)
    {
      std::string str;
     
      str="bibby";
      *tmp=str;
    }
    Je sais pas si sa répond a ta question
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par IsraGab Voir le message
    Salut,
    Dapres ce que je sais d'un cours se nommant les principes des languages de programmation.
    Un passage d'un objet par reference est le passage de l'adresse de cette objet (a une fonction).
    Et dapres ce que je connais du C++, le passage par reference est une copie de l'adresse sur laquelle un pointeur pointe en mémoire.
    Résultat:
    Du point de vue du programmeur cela revient au meme.
    Mais du point de vue du code, il y a eu une copie et donc ce n'est pas vraiment un passage par reference?
    J'ai faux?
    NON!!!

    il ne faut pas confondre l'adresse d'une variable et la variable en elle-même!

    L'adresse de la variable est, peu ou prou, le seul moyen dont au dispose, au niveau de l'exécutable, pour accéder à la variable.

    C'est un peu comme de dire que le seul moyen de te contacter est ton adresse postale ou ton adresse E-mail : cela ne signifie absolument pas que celles-ci sont... toi

    De plus, il faut savoir qu'une adresse (et donc un pointeur, vu que ce n'est qu'une variable contenant une adresse ) n'est, en définitive, qu'une valeur numérique, sur laquelle il est même possible d'appliquer une certaine arithmétique de manière à accéder, pourquoi pas, à d'autres données

    Il est donc vrai qu'il n'y a pas forcément d'intérêt (en terme de temps passé à copier les valeurs) à passer une valeur numérique par référence, à moins bien sur que l'on ait besoin du comportement particulier des références

    Copier une telle donnée est très vite fait, étant donné qu'il suffit de... mettre les bits qui la composent à une valeur particulière.

    En outre, il n'est pas du tout exclu que cette valeur soit, purement et simplement, placée dans un registre quelconque d'où elle sera disponible depuis (à peu près) n'import où (ou du moins n'importe quelle fonction).

    Enfin, il y a une différence flagrante entre copier une adresse ("seulement" quelques bits à mettre à des valeurs correctes) et copier tout un objet, qui nécessitera au minimum de copier tous ses membres (voire les membres des membres de l'objet, et ainsi de suite), et même, parfois, d'allouer des ressources pour certains d'eux.

    Le temps que peut demander la copie d'objet est donc sans aucune mesure avec celui que peut demander la copie d'une adresse, et, surtout, le résultat sera totalement différent:

    Avec la copie réelle de l'objet, tu te retrouve avec deux objets qui peuvent varier de manière tout à fait indépendante: ce que tu fais d'un coté n'est absolument pas répercuté de l'autre.

    Par contre, lorsque tu dispose de l'adresse à laquelle se trouve cet objet, que tu passe par cette adresse ou par la variable (qui n'est, soit dit en passant, aussi connue que comme une adresse) originale, tu travaillera toujours sur les même données "physiques" : que tu passe par un coté ou par l'autre, les modifications que tu pourras apporter à ton objet se verront immédiatement aussi bien du coté de la référence que du coté de la variable originale
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre régulier
    Homme Profil pro
    Programmeur PHP
    Inscrit en
    Août 2009
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Israël

    Informations professionnelles :
    Activité : Programmeur PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2009
    Messages : 244
    Points : 114
    Points
    114
    Par défaut
    Merci pour les réponses, mais je pense que l'on ne sait pas compris
    il ne faut pas confondre l'adresse d'une variable et la variable en elle-même!
    Je ne pense pas avoir confondu le passage d'une addresse avec celui d'un objet.

    Je dis juste que lorsqu'on passe une variable par reference normalement il ne se produit aucune copie (dans ce cas la une addresse).
    En Java par exemple lorsque j'envoie un objet a une fonction, je lui passe son adresse.
    En C++ également. Seulement, cette addresse, je pense (et la est ma question), est copiée.

    Ce qui, semble contredire la definition d'un passage par reference.

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 59
    Points : 120
    Points
    120
    Par défaut
    Salut

    je ne vois pas de contradiction ici : oui l'adresse est bien copiée (il faut bien quelque chose pour retrouver la variable) , mais la variable elle même ne l'est pas.

    ta phrase devra être :
    lorsqu'on passe une variable par reference normalement il ne se produit aucune copie de la variable.
    Cdt

  6. #6
    Membre régulier
    Homme Profil pro
    Programmeur PHP
    Inscrit en
    Août 2009
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Israël

    Informations professionnelles :
    Activité : Programmeur PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2009
    Messages : 244
    Points : 114
    Points
    114
    Par défaut
    Ok,

    oui l'adresse est bien copiée (il faut bien quelque chose pour retrouver la variable)
    Dapres ce que tu dis, meme en Java les adresses doivent etre copiés?

    Je reformule donc ma question:

    Lors d'un passage par reference une copie de l’adresse est effectué.
    Lors d'un passage par valeur, une copie de la variable est effectué.

    Dans tout les cas une copie est nécessaire?!

  7. #7
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Beh pose toi la question, comment ramener un cours chez toi si tu ne le copie pas?

    Meme fonctionnement avec les variable
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  8. #8
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonjour,

    Je pense que la question n'est pas réelement pertinante. Le passage par référence est une notion sémantique, elle attache un sens présis à un mode de passage des paramètres : on travail sur l'objet en lui même et pas sur une copie (*). Alors que le fait qu'en interne ca effectue une copie d'une addresse n'est qu'un détail d'implémentation, un détail technique qui ne change absolument rien à ce que signifie un tel passage.

    Et donc, tout ce que tu as pu voir sur le passage par référence garde strictement le même interet, qu'il y et ou non des copie de pointeur en interne.

    D'ailleurs, de mémoire (si quelqu'un peut confirmer/infirmer ^^), il n'est dit nul part dans la norme du C++ qu'un passage par référence doit induire la copie d'une addresse, c'est juste une supposition (surment réaliste) que l'on fait quand l'on discute de l'interet de passer certaines données par copie plutôt que par référence (constante).

    (*) En anglais : http://www.parashift.com/c++-faq-lit...semantics.html (première entrée) En particulier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    void foo(T* t) { t-> do_it(); }
    void foo(T& t) { t.do_it(); }
    Ont exactement le même sens : c'est une sémantique de référence, on va travailler sur l'objet et non sur une copie (la seconde forme est quand même à préférer)

  9. #9
    Membre régulier
    Homme Profil pro
    Programmeur PHP
    Inscrit en
    Août 2009
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Israël

    Informations professionnelles :
    Activité : Programmeur PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2009
    Messages : 244
    Points : 114
    Points
    114
    Par défaut
    Beh pose toi la question, comment ramener un cours chez toi si tu ne le copie pas?
    En ce qui me concerne je prend le cours d'une fille (elles écrivent toujours tout et leur écritures est bien plus claire que celles des garcons)

    Apparemment, il semblerai que j'ai un probleme de comprehension en ce qui concerne l'alocations des variables dans un programme.

    Pour répondre plus serieusement a ta question...
    Admetons que je dispose d'une valeur stockée dans ma RAM. Avec un pointeur ptr sur cette variable.
    Le pointeur se trouve (je pense) dans un des registres.
    Maintenant je veux modifier cette variable dans une fonction.... il suffit que je lui passe le pointeur! (il n'y a pas eu de copie)
    J'ai faux?

  10. #10
    Membre régulier
    Homme Profil pro
    Programmeur PHP
    Inscrit en
    Août 2009
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Israël

    Informations professionnelles :
    Activité : Programmeur PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2009
    Messages : 244
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    Bonjour,
    on travail sur l'objet en lui même et pas sur une copie (*). Alors que le fait qu'en interne ca effectue une copie d'une addresse n'est qu'un détail d'implémentation, un détail technique qui ne change absolument rien à ce que signifie un tel passage.
    Salut,
    En effet, si tu lis bien mon 1er post tu verras bien que j'ai spécifié que cela ne pose aucune différence du point de vue du programmeur, car finalement il est vrai que l'on travail sur l'objet lui même.
    La question que je me pose est justement technique.
    J’étudie en ce moment l'architecture du language C++, et je me pose juste la question comment ce language traite-t-il les passages par reference.

    Ma question est purement basée sur de la théorie et non de la pratique.

  11. #11
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par IsraGab Voir le message
    Maintenant je veux modifier cette variable dans une fonction.... il suffit que je lui passe le pointeur! (il n'y a pas eu de copie)
    J'ai faux?
    Tu lui passe le pointeur -> pointeur=variable qui contient une addresse, tu passe donc une variable donc une copie

    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void toto(void *ptr)
    {
      //ptr vaut 11111111
      ptr=NULL;
      //ptr vaut NULL
    }
     
    int main()
    {
      void *ptr=11111111;
     
      //ptr vaut 11111111
      toto(ptr);
      //ptr vaut 11111111
    }
    L'addresse '11111111' est juste un exemple mais quand tu passe un pointeur, c'est une copie de ton pointeur mais pas de la variable sur laquelle pointe ton pointeur.

    Comme le disait mon prof:

    En informatique, tout est variable
    Comprendre qu'en informatique, peut importe ce que tu utilise (variable simple, pointeur, texte ou nombre) est une variable donc quand tu le passe a une autre fonction, tu as obligatoirement une copie
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par IsraGab Voir le message
    J'ai faux?
    Oui.
    Probablement, que l'adresse sera recopiée sur la pile ou dans un registre pour être passée à la fonction.

    Comme dit Flob90, cette question n'a aucun sens. Parles-tu de copie de l'adresse à chaque fois que dans le code, dans la même fonction, l'adresse d'un objet est rechargée depuis la pile vers un registre par exemple ?

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    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 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par IsraGab Voir le message
    La question que je me pose est justement technique.
    J’étudie en ce moment l'architecture du language C++, et je me pose juste la question comment ce language traite-t-il les passages par reference.
    Effectivement, comme dit plus haut, les « références » sont une notion qui concerne essentiellement le compilateur. À la limite, la manière dont il va s'en sortir ensuite ne regarde que lui. Mais il est important de noter que le « passage par références » (passage de paramètres, donc) n'est qu'un des cas de figures possibles.

    Lorsque tu « déclares une référence », c'est en fait toi qui « fais référence » ou « te réfères » à une instance quelconque. Lorsque tu écris :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream>
     
    using namespace std;
     
    void fonction ()
    {
        int     x;
        int &   y = x;
     
        cout << "Adresse de x : " << &x << endl;
        cout << "Adresse de y : " << &y << endl;
    }

    Tu crées en fait un alias de la variable x. Plus précisément, tu déclares une variable en mémoire quand tu écris « int x » et dont le compilateur va tenir l'inventaire, et « x » est le symbole que tu as choisi pour y faire référence. Lorsque tu écris « int & y », tu crées un second symbole se référant à la même chose. Ainsi dans le bloc de la fonction concerné, tu peux utiliser indifféremment l'un ou l'autre. Ils signifient syntaxiquement la même chose.

    C'est donc tout naturellement que le résultat à l'écran donnera une même adresse en mémoire pour les deux variables x et y, parce qu'en fait, il s'agit d'une seule variable, désignée par deux symboles :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ ./ref
    Adresse de x : 0x7fff4661b044
    Adresse de y : 0x7fff4661b044

    Quand tu déclares une référence C++, donc, tu te réfères à une entité déjà existante. Une référence n'est donc pas en elle-même un objet, ou en elle-même une instance de quelque chose. Elle est résolue à la compilation.

    Dans le cas du « passage par référence », maintenant, ta fonction se réfère à un objet existant, mais pas encore connu à la compilation. C'est un problème technique, donc, mais pas du tout algorithmique. Comme, au final, le compilateur n'a besoin que de connaître l'adresse effective en mémoire d'un objet, quel qu'il soit, pour travailler dessus, notre passage par référence va effectivement consister à transmettre l'adresse de cet objet à la fonction, ce qui — techniquement, toujours — se réalise de la même façon qu'un passage de pointeur.

    Ces opérations sont donc équivalentes une fois le programme compilé mais, sémantiquement, elles restent quand même bien distinctes.

    Admetons que je dispose d'une valeur stockée dans ma RAM. Avec un pointeur ptr sur cette variable.
    Le pointeur se trouve (je pense) dans un des registres.
    Maintenant je veux modifier cette variable dans une fonction.... il suffit que je lui passe le pointeur! (il n'y a pas eu de copie)
    Non. Un pointeur est en soi une variable comme les autres. Il est donc alloué en mémoire à une adresse propre, que tu peux retrouver avec « &ptr » et qui a priori n'a rien à voir avec celle qu'il contient.

    Ensuite, si par « registre », tu parles des registres du processeur tels que désignés par register (on rappelle que « registre » est un terme général en informatique… et même ailleurs), il peut s'y trouver à un moment, mais au même titre que n'importe quel autre type (au moins les types natifs).

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

Discussions similaires

  1. Passage par référence
    Par e1lauren dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 01/09/2006, 12h59
  2. Passage par copie vs passage par référence
    Par bolhrak dans le forum C++
    Réponses: 11
    Dernier message: 20/08/2006, 23h37
  3. Réponses: 4
    Dernier message: 26/12/2005, 17h01
  4. Passage par référence
    Par difficiledetrouver1pseudo dans le forum Langage
    Réponses: 9
    Dernier message: 28/09/2005, 11h17
  5. Problème très rapide de passage par référence
    Par Noxexplorer dans le forum ASP
    Réponses: 2
    Dernier message: 23/06/2005, 10h02

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