Lors de l'appel d'une fonction, les arguments sont copiés, c-à-d que
la fonction manipule de nouvelles variables ayant les mêmes valeurs que
celles données en arguments, mais que ces variables sont différentes
des précédentes et locales au bloc d'instruction de la fonction. Exemple:
si la fonction ajoute_un
est définie ainsi:
void ajoute_un(int a){ a++; }
alors l'appel suivant:
int x = 5; ajoute_un(x);
est équivalent au bloc:
int x = 5; { int a = x; a++; }
ce qui fait que la valeur de x
ne sera pas modifiée !
Si l'on veut changer la valeur de la variable x
, il faut passer la
variable par référence afin que la fonction manipule la même variable et
non pas une copie. La fonction ressemble alors à:
void ajoute_un(int& a){ a++; }
et dans ce cas le bloc précédent devient équivalent à:
int x = 5; { int& a = x; a++; }
Ici, comme a
est une référence sur la variable x
, a
n'est qu'un autre nom pour la même variable. Modifier a
affecte donc
x
puisqu'il s'agit de la même variable.
Une fonction peut aussi retourner une référence. Cela peut s'avérer
utile si l'on cherche à renvoyer une variable que l'on souhaite
modifier. Supposons par exemple que nous disposions de deux variables
x
et y
et que nous voulions manipuler la plus grande
des deux. La fonction:
int& plusgrande(int& a, int& b){ if (a>b) return a; else return b; }
retourne une référence vers le plus grand de ses arguments (qui doivent
aussi être passés en référence si on ne veut pas retourner une référence
vers une simple copie des arguments qui soit locale à la fonction). L'on
peut alors appeler la fonction ainsi:
int x = 4; int y = 12; plusgrande(x, y) += 3;
Ce bloc aura de fait le même comportement que celui-ci:
int x = 4; int y = 12; { int& a = x; int& b = y; if (a>b) a += 3; else b += 3; }
qui lui-même aura le même comportement que:
int x = 4; int y = 12; if (x>y) x += 3; else y += 3;