78 votes

C++ : différence entre l'esperluette "&" et l'astérisque "*" dans la déclaration d'une fonction/méthode ?

Y a-t-il une sorte de différence subtile entre eux :

void a1(float &b) {
    b=1;
};
a1(b);

et

void a1(float *b) {
    (*b)=1;
};
a1(&b);

?

Elles font toutes deux la même chose (du moins, c'est ce qu'il semble d'après main() ), mais la première est manifestement plus courte, alors que la plupart du code que je vois utilise la seconde notation. Y a-t-il une différence ? Peut-être dans le cas où il s'agit d'un objet au lieu d'un flottant ?

62voto

Brian R. Bondy Points 141769

Les deux font la même chose, mais l'un utilise des références et l'autre des pointeurs.

Voir ma réponse ici pour une liste complète de toutes les différences. .

31voto

Charlie Martin Points 62306

Oui. Le * indique que ce qui est transmis sur la pile est un pointeur, c'est-à-dire l'adresse de quelque chose. Le site & dit que c'est une référence. L'effet est similaire mais pas identique :

Prenons deux cas :

   void examP(int* ip);
   void examR(int& i);

   int i;

Si j'appelle examP J'écris

   examP(&i);

qui prend l'adresse de l'élément et la passe sur la pile. Si j'appelle examR ,

   examR(i);

Je n'en ai pas besoin ; maintenant le compilateur passe "en quelque sorte" une référence -- ce qui signifie pratiquement qu'il obtient et passe l'adresse de i . Du côté du code, alors

   void examP(int* ip){
        *ip += 1;
   }

Je dois m'assurer de déréférencer le pointeur. ip += 1 fait quelque chose de très différent.

   void examR(int& i){
        i += 1;
   }

met toujours à jour la valeur de i .

Pour en savoir plus, lisez la rubrique "appel par référence" et "appel par valeur". Le site & notion donne C++ appel par référence.

5voto

Greg Hewgill Points 356191

Dans le premier exemple avec les références, vous savez que b ne peut pas être NULL. Avec l'exemple du pointeur, b pourrait être le pointeur NULL.

Cependant, notez qu'il es Il est possible de passer un objet NULL par le biais d'une référence, mais c'est maladroit et la procédure appelée peut supposer que c'est une erreur de l'avoir fait :

a1(*(float *)NULL);

3voto

finnw Points 24592

Dans le deuxième exemple, le appelant doit préfixer le nom de la variable avec '&' pour transmettre l'adresse de la variable.

Cela peut être un avantage - l'appelant ne peut pas modifier par inadvertance une variable en la passant comme référence alors qu'il pensait la passer par valeur.

3voto

jmucchiello Points 10521

En dehors du sucre syntaxique, la seule différence réelle est la possibilité pour un paramètre de fonction qui est un pointeur d'être nul. La version pointeur peut donc être plus expressive si elle gère correctement le cas nul. Le cas nul peut également avoir une signification particulière. La version de référence ne peut opérer que sur des valeurs du type spécifié sans possibilité de nullité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X