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 :

Différence entre int et int&


Sujet :

C++

  1. #1
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut Différence entre int et int&
    Bonjour
    Il me semble qu'il y a aucune différence entre int et int&.
    Par exemple, ces deux fonctions sont identiques:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void f(int o); 
    et
    void f(int&o);
    En gros, pour les types primaires, cela ne sert à rien de passer une variable par référence ou par valeur.
    (Donc autant ne faire passer que des int).
    Idem pour cette fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int f(void);
    int& f(void);
    Mais je ne me rappelle plus pourquoi.

    Merci

  2. #2
    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
    Par défaut
    int et int& sont 2 types radicalement différents. Le premier est un entier, le second est une référence vers un entier. Le comportement n'est pas le même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    f(int&);
    int main()
    {
       int i=0;
       f(i);//ok
       f(3);// erreur
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    f(int );
    int main()
    {
       int i=0;
       f(i);//ok
       f(3);// ok
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    f(int&o)
    {
       ++o;
    }
    int main()
    {
       int i=0;
       f(i);//ok
       assert(1==i);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    f(int o)
    {
       ++o;
    }
    int main()
    {
       int i=0;
       f(i);//ok
       assert(0==i);
    }
    Quand à la valeur retour :
    int f(); retourne une valeur par copie
    int& f(); retourne une référence. L'objet a intérêt d'exister après le retour de la fonction et tant que la référence est liée. Sinon, undefined behaviour (dans ce cas, c'est souvent un plantage).

    Cette question indique la nécessité de se replonger dans les premiers cours pour débutant.

  3. #3
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    je me doute bien que si on a :

    int f(int&) et qu'on fait f(4), ca va planter.

    mais moi, je me restreint au cas où:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int f(int& a)
    {...
    }
    et


    sont, ils me semblent identiques, dans l'appel de la fonction f.

  4. #4
    screetch
    Invité(e)
    Par défaut
    bah non, comme 3darchi l'a pointé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    f(int o)
    {
       ++o;
    }
    int main()
    {
       int i=0;
       f(i);//ok
       assert(0==i);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    f(int&o)
    {
       ++o;
    }
    int main()
    {
       int i=0;
       f(i);//ok
       assert(1==i);
    }

  5. #5
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    oui, mais ce que je voulais dire, c'est que quand tu fais f(Obj o), tu appelles le constructeur par copie, ici, non: f(Obj &o) alors que pour un type primaire, f(int o) ou f(int &o) c'est la même chose, pas d'appel au constructeur par copie.

    Vous voyez?

  6. #6
    screetch
    Invité(e)
    Par défaut
    tout s'eclaire si tu dis const int& au lieu de int&pour un entier, non, ca ne change pas grand chose, souvent les compilateurs passent ca dans les registres si ils peuvent.
    Pour un type plus complexe effectivement, sans passer des références const, ca fait une copie, ce qui est chiant (vas y que je te copie une list ou un vector...)

  7. #7
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    oui, je suis allé trop vite!
    -pourquoi est il nécessaire de préciser const?

    pour moi, une fonction peut renvoyer une ref sur une variable locale de type int, ca ne pose pas de pb.
    Ensuite, pour un objet, oui, ca pose problème, et j'en ai déjà vu.

  8. #8
    screetch
    Invité(e)
    Par défaut
    préciser const revient presque au même qu'envoyer une copie mais coûte moins cher.

    Mettons que tu veuilles donner un objet en paramètre a une fonction, tu n'as pas envie que ta version soit modifiée. Sit u passes juste une référence, la méthode que tu appelles a le droit de bidouiller ton objet comme elle veut.
    Si tu ne veux pas "perdre" ton objet, tu peux soit passer une copie (coûteux) soit passer une référence, pour aller plus vite, mais _const_ pour empêcher la méthode que tu appelles de modifier l'objet.
    Si elle souhaite modifier, elle fera elle même une copie.


    Renvoyer une référence sur un entier local, peut être ca ne crashera pas mais personne ne sait quelle valeur aura ton entier.
    que penses-tu que ce code va faire?
    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
    16
    17
    18
    19
    20
    #include <cstdio>
     
    int& f(int x)
    {
        int y = x;
        return y;
    }
     
    int& g(int x)
    {
        int y = x*2;
        return y;
    }
     
    int main()
    {
        int& x = f(3);
        int& y = g(3);
        printf("%d\n", x);
    }

  9. #9
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    que penses-tu que ce code va faire?
    Je viens de regarder, en Release, avec le plus d'optim possible, ca donne 3 puis 6.

  10. #10
    screetch
    Invité(e)
    Par défaut
    que veux tu dire "3 puis 6"? il n'y a qu'un seul printf

  11. #11
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Pardon, ca donne 3
    J'avais mis deux print.

  12. #12
    screetch
    Invité(e)
    Par défaut
    ah bon
    chez moi, ca compile pas.
    quand je demande au compilateur de la fermer, et que je lance le programme, ca affiche 6.
    chez toi ca affiche 3
    chez mon voisin, ca a éteint les lumières de sa cuisine.

    Autant dire que ca marche pas vraiment

  13. #13
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Tu as quoi comme compilateur? Moi VC2010.

  14. #14
    screetch
    Invité(e)
    Par défaut
    moi GCC sous windows. Et GCC est assez sympa pour me prévenir que ca ne marchera pas
    Ca ne peut pas marcher; tu as une référence sur un temporaire. Lorsque tu quittes la fonction, le compilateur est libre de réutiliser l'espace pour autre chose, ce qu'il ne se gènera pas pour faire.
    même sous VC2010 je parie que je peux avoir plusieurs comportements différents. par exemple si tu le fais tourner en debug, il va te dire que x vaut -572662307.

  15. #15
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    va te dire que x vaut -572662307.
    6
    Monsieur!
    La je suis convaincu.

  16. #16
    Membre Expert

    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 : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Pour la nécessité du const pour faire des références sur des objets temporaires, c'était un problème si par exemple on voulait pouvoir modifier le paramètre, pas le choix de mettre void foo(T&); mais dans ce cas un appel du genre foo(0); ne marchais pas, c'est "corrigé" dans le C++2011 avec les rref. (cf C++Next pour une série d'articles sur le sujet)

    Et en effet on dit souvent que pour les types fondamentales l'interet de passer par des références constantes est faible (dans un contexte ou l'on peut choisir l'un ou l'autre), mais ca ne fait pas pour autant la même chose. La raison pour laquelle l'interet est faible c'est que dans ce cas créer une référence ou copier le type ont le même coût.

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

Discussions similaires

  1. Transformer (int année, int mois, int jour) en millisecondes
    Par Logic_613 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 24/04/2012, 11h08
  2. Différence entre ExitCode et int Maint()
    Par BenoitM dans le forum Débuter
    Réponses: 1
    Dernier message: 27/08/2009, 16h28
  3. [Validate] Différence entre Digits et Int
    Par dorian53 dans le forum Autres composants
    Réponses: 3
    Dernier message: 31/03/2009, 14h37
  4. Différence entre size_type et un int ?
    Par Bakura dans le forum C++
    Réponses: 4
    Dernier message: 20/05/2007, 20h40
  5. Différence entre String et Int
    Par Alchimist dans le forum Langage
    Réponses: 6
    Dernier message: 05/04/2006, 11h00

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