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 :

Parametre de fonction


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 23
    Par défaut Parametre de fonction
    Salut!

    Je souhaiterais avoir des précisions quant à l'emploi de ces différentes signatures de fonctions :

    1/ void f( MyType mt );
    2/ void f( MyType &mt );
    3/ void f( MyType *mt );

    -> 1/ correspond au passage par valeur donc dans la fonction on fait ce qu'on veut de la valeur. En dehors de f, mt a toujours la meme valeur.

    -> 2/ correspond a un passage par référence donc on passe l'adresse d'une variable et si on modifie mt dans la fonction, a la sortie de f la modification est presente

    -> et 3/ correspond a la meme chose que 2/ ms pour des pointeurs

    Est-ce que tout est exact?


    Merci de votre confirmation...

    Tyv

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    C'est bien exact...

    On peut juste rajouter que la différence entre le 2) et le 3), c'est que dans le cas d'un pointeur, il peut etre NULL, alors qu'une référence ne peut pas l'etre

    C'est à vrai dire la seule différence réelle qu'il y aie entre une référence et un pointeur
    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

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Bonjour,
    Citation Envoyé par Tyver
    -> 1/ correspond au passage par valeur donc dans la fonction on fait ce qu'on veut de la valeur. En dehors de f, mt a toujours la meme valeur.
    Exact.
    Lorsqu'on utilise la passage par valeur, le compilateur effectue une copie du paramètre lorsque la fonction est appelée. Par conséquent, les modification du paramètre effectué à l'intérieur de la fonction vont affecter la copie de la variable passée en paramètre, et non la variable elle-même.

    Citation Envoyé par Tyver
    -> 2/ correspond a un passage par référence donc on passe l'adresse d'une variable et si on modifie mt dans la fonction, a la sortie de f la modification est presente
    Exact. RAS.

    Citation Envoyé par Tyver
    -> et 3/ correspond a la meme chose que 2/ ms pour des pointeurs
    Oui, mais...
    Lorsque tu passes un pointeur en paramètre, ce pointeur est copié lors de l'appel à la fonction. Donc si tu modifie le pointeur à l'intérieur de la fonction, il y a de grandes chances pour que cela engendre des problèmes.

  4. #4
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par koala01
    C'est à vrai dire la seule différence réelle qu'il y aie entre une référence et un pointeur
    Je ne suis pas d'accord. Une référence, c'est l'adresse de l'endroit où est stocké l'objet. Un pointeur est une variable dans laquelle est stockée l'adresse où est stocké l'objet. Ce n'est pas du tout la même chose.

    Je vais de ce pas chercher un peu de litérature sur ce sujet pour étayer mon propos

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Je ne suis pas d'accord. Une référence, c'est l'adresse de l'endroit où est stocké l'objet. Un pointeur est une variable dans laquelle est stockée l'adresse où est stocké l'objet. Ce n'est pas du tout la même chose.
    Ben, c'est quand même la même chose
    Une référence ce n'est qu'un pointeur déguisé pour offrir un accès simplifié à la variable. Et le fait que la référence doit obligatoirement pointer vers quelque chose de valide est bien la seule différence avec un pointeur (si on ne pinaille pas).

    De toute façon une fois le code compilé, une référence n'est rien d'autre qu'un bête adresse, tout comme un pointeur.

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Méééé heu!!! Je vous dis que j'ai raison!! Vous êtes tous nul d'abord!!!
    Désolé, j'ai abusé sur l'apéro

    Plus sérieusement:
    Il est très important de distinguer les pointeurs, qui sont des adresses mémoire, des références qui sont des variables de types très divers.
    (http://www.ann.jussieu.fr/courscpp/S...Sect03-C1.html)

    Citation Envoyé par faqlite
    Utilisez les références quand vous pouvez, et les pointeurs quand vous devez.
    (http://jlecomte.ifrance.com/c++/c++-...rences-fr.html)

    Un pointeur dispose de toute une série d'opérateurs, une référence n'en a pas.
    Contrairement à un pointeur, il est impossible de déclarer une référence sans l'initialiser.
    Comme l'a dit koala01, un pointeur peut prendre la valeur NULL, la référence non.
    Les références n'existent qu'en C++. Les pointeurs existent en C et en C++.
    L'utilisation d'une référence fait gagner un adressage par rapport à un pointeur. Je ne suis pas adepte de l'optimisation, et j'avoue que je ne sais pas si ça a une quelconque importance.

    Toutes ces différences, et en particulier les 2 premières, font qu'un pointeur est beaucoup plus dangereux à utiliser qu'une référence.

    Le code suivant, par exemple, illustre une erreur assez classique qui ne peut pas arriver si on utilise une référence à la place d'un pointeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void foo(int* p)
    {
    	p+=5;
    }
     
    int main(int argc, char* argv[])
    {
    	int p = 0;
     
    	foo(&p); //on appelle foo en pensant que ça va modifier la valeur de p
    	return 0;
    }
    Ensuite, lorsque l'on choisi d'utiliser un pointeur ou une référence, cela implique un choix sémantique. Par exemple, la fonction suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(const int* p)
    {
    	*p+=5;
    }
    compile, et on ne sait pas à quoi sert ce const. Alors que l'utisation d'une référence constante est trés explicite.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 23
    Par défaut
    Merci beaucoup pour ces précisions c'est sympa!!
    Je crois que ça a fait du bien a tout le monde :p

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    171
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 171
    Par défaut
    Bonjour,

    Pour rajouter une chose sur les références et les pointeurs.
    Lorsque dans mon code je lis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MonObjet t;
    foo(t);
    où foo est une fonction qui prend une référence vers un MonObjet et le modifie.

    Si je ne connais pas le prototype de la fonction, rien ne me dis ne me dis dans ce code que t sera modifié (où non). Je peux croire qu'il s'agit d'un passage par valeur.

    Alors que si j'avais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MonObjet t;
    foo(&t);
    Où foo est déclaré comme prenant un pointeur vers un MonObjet alors à la lecture de ce code, je vois que t est susceptible d'être modifié.

    Par conséquent, je n'utilise les références comme paramètres de fonction lorsque celle-ci ne modifie pas l'objet référencé mais que je gagne à épargner une recopie par valeur (j'utilise alors une référence constante pour garantir cette non modification).
    Et j'utilise les pointeurs lorsque la fonction modifie l'objet pointé.
    On y gagne en lisibilité, non ?

  9. #9
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Aurelpitiless
    Si je ne connais pas le prototype de la fonction, rien ne me dis ne me dis dans ce code que t sera modifié (où non). Je peux croire qu'il s'agit d'un passage par valeur.
    Je ne vois comment il est possible d'utiliser une fonction sans en connaitre la signature. Je ne vois donc pas l'intérêt de cette remarque.

    Citation Envoyé par Aurelpitiless
    [...]alors à la lecture de ce code, je vois que t est susceptible d'être modifié.

    Par conséquent, je n'utilise les références comme paramètres de fonction lorsque celle-ci ne modifie pas l'objet référencé mais que je gagne à épargner une recopie par valeur (j'utilise alors une référence constante pour garantir cette non modification).
    D'où l'intérêt de respecter la const conformité, ainsi la question de se pose plus.

    Citation Envoyé par Aurelpitiless
    Et j'utilise les pointeurs lorsque la fonction modifie l'objet pointé.
    On y gagne en lisibilité, non ?
    Je ne sais pas, c'est plus une question d'habitude je pense. Ces petites habitudes qui font que lorsqu'on doit travailler sur le code d'un collègue, on a souvent l'impression que ce code est mauvais

  10. #10
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    171
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 171
    Par défaut
    Je ne vois comment il est possible d'utiliser une fonction sans en connaitre la signature. Je ne vois donc pas l'intérêt de cette remarque.
    Je pensais surtout en terme de lisibilité dans le cas où tu dois reprendre un source écris par quelqu'un d'autre par exemple.
    Dans ce cas je ne tiens pas à lire la doc de chaque fonction utilisée pour savoir si elle modifie ou pas un objet, j'aime bien le voir a la seule lecture du code.

    Ca peut permettre de ne pas passer un temps fou à déceler un bug, parce que l'on pense que le paramètre est passé par valeur, et non par référence.

  11. #11
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    C'est pas faux...

  12. #12
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    En même temps, si tu passes un paramètre à une fonction sans savoir ce qu'elle va en faire, c'est assez grave... Avec un bon EDI tu fais clic droit + "Go to declaration" et hop tu sais si c'est une référence ou autre chose.

    Ceci-dit, le débat (pour ne pas dire troll) pointeur vs référence a déjà eu lieu, je suis sûr que ceux que ça intéresse trouveront plein de pages à lire en fouillant un peu sur ce forum.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Au passage: Si on est malin, on peut faire une référence nulle. Mais c'est du truandage...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int *p = NULL;
    int &r = *p;
    Edit: Et le pire, c'est qu'on peut aussi le faire involontairement...
    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.

  14. #14
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Citation Envoyé par Tyver
    1/ void f( MyType mt );

    -> 1/ correspond au passage par valeur donc dans la fonction on fait ce qu'on veut de la valeur. En dehors de f, mt a toujours la meme valeur.

    Tyv

    Attention, si MyType est une classe, le destructeur sera appelé à la fin de la fonction !

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 23
    Par défaut
    Citation Envoyé par millie
    Attention, si MyType est une classe, le destructeur sera appelé à la fin de la fonction !

    Merci pour vos réponse et cette dernière aussi que j'ignorais!
    Excellent week-end!

    Tyv

  16. #16
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Tout élément passé par référence/pointeur serait mieux const.

  17. #17
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Je ne comprend pas pourquoi tu dis ça. I ly a plein de cas où ce n'est pas vrai. Si l'on souhaite modifier le paramètre dans la fonction par exemple.
    Enfin, il doit y avoir un truc qui m'échappe là.

  18. #18
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Pourquoi le modifier ?
    Si ta fonction doit produire un résultat, il est sémantiquement plus juste qu'elle le retourne sous forme de valeur.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Loufoque, deux mots:

    operator <<

    (entre autres, évidemment. Et il y a tant de fonctions qui pourraient vouloir retourner deux valeurs à la fois sans avoir de problèmes, comme ceux de java où une allocation dynamique est obligatoire pour ça...).
    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.

  20. #20
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Citation Envoyé par loufoque
    Pourquoi le modifier ?
    Si ta fonction doit produire un résultat, il est sémantiquement plus juste qu'elle le retourne sous forme de valeur.
    Ca peut également très mal fonctionner dès qu'il y a un peu d'héritage.

    Donner en paramètre l'instance permet de faire des manipulations dessus indépendemment de son implémentation (vu que l'on doit pas donner en retour une instance de la classe).

    Exemple classique, des opérateurs sur des images :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void operateur(Image & out, const Image & in) {
     if(out.getNumComponents() != in.getNumComponents()) {
       throw ...
     }
     ...
    }
    L'image pouvant être spécialisée (ImageRGB, ...)
    Et donc le code fonctionnerait comme ça :
    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
     
    ImageRGB imRGB;
    ImageRGB imRGBout;
     
    ImageIO::loadJPG("./..", imRGB);
     
    operateur(imRGBout, imRGB);
     
    ...
     
    ImageNB imNB;
    ImageNB imNBout;
     
    ImageIO::loadJPGRedComponent("...", imNB);
     
    operateur(imNBout, imNB);

Discussions similaires

  1. reference anomyme en parametre de fonction
    Par seb9999 dans le forum C++
    Réponses: 7
    Dernier message: 03/02/2006, 15h31
  2. [VBA-E]passage de parametre à une fonction
    Par DonKnacki dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 02/02/2006, 17h51
  3. Parametre de fonction
    Par yoshï dans le forum Linux
    Réponses: 1
    Dernier message: 09/01/2006, 10h46
  4. parametre et fonction
    Par jeff_! dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/12/2005, 09h55
  5. Réponses: 13
    Dernier message: 13/10/2005, 16h03

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