web-dev-qa-db-fra.com

Passer l'argument de pointeur, passer par la valeur en C++?

Passer l'argument de pointeur, passer par la valeur en C++? Depuis que je vois que tout changement au pointeur en tant que tel n'est pas reflété en dehors de la méthode. Les changements que je fais en déréférencant le pointeur sont cependant reflétés.

Dans ce cas, est-ce une procédure acceptable/standard d’utiliser un pointeur à un pointeur comme argument d’une fonction pour modifier la valeur du pointeur en tant que telle dans une fonction?

26
Sulla

Oui aux deux. 

Les pointeurs sont passés par valeur comme n'importe quoi d'autre. Cela signifie que le contenu de la variable de pointeur (l'adresse de l'objet pointé) est copié. Cela signifie que si vous modifiez la valeur du pointeur dans le corps de la fonction, cette modification ne sera pas reflétée dans le pointeur externe qui pointera toujours vers l'ancien objet. Mais vous pouvez changer la valeur de l'objet pointé.

Si vous souhaitez refléter les modifications apportées au pointeur sur le pointeur externe (faites-le pointer sur autre chose), vous avez besoin de deux niveaux d'indirection (pointeur à pointeur). Lorsque vous appelez des fonctions, vous devez placer un & avant le nom du pointeur. C'est la manière standard de faire les choses.

Lorsque vous utilisez C++, il est préférable d'utiliser des références au pointeur (désormais également au pointeur à pointeur).

Pour le pourquoi les références devraient être préférées aux pointeurs, il y a plusieurs raisons:

  • les références introduisent moins de bruit syntaxique que les pointeurs dans le corps de la fonction
  • les références contiennent plus d'informations que les pointeurs, ce qui peut être utile pour le compilateur

Les inconvénients des références sont principalement:

  • ils enfreignent la simple règle de C par valeur, ce qui rend moins évident la compréhension du comportement d'une fonction en ce qui concerne les paramètres (seront-ils modifiés?). Vous avez également besoin d'un prototype de fonction pour en être sûr. Mais ce n’est pas pire que les multiples niveaux de pointeur nécessaires lors de l’utilisation de C.
  • ils ne sont pas supportés par C, ce qui peut poser problème lorsque vous écrivez du code qui devrait fonctionner à la fois avec les programmes C et C++ (mais ce n’est pas le cas le plus courant).

Dans le cas spécifique du pointeur à pointeur, la différence réside principalement dans la simplicité, mais en utilisant référence, il peut également être facile de supprimer les deux niveaux de pointeurs et de ne transmettre qu'une seule référence à la place d'un pointeur à l'autre.

30
kriss

Je comprends la confusion ici. Les concepts de "passage par valeur" et de "passage par référence" ne sont pas aussi clairs même s’ils semblent le N'oubliez pas que l'ordinateur ne connaît pas ces concepts et ne se comporte pas en conséquence. L’ordinateur ne connaît pas les types. Par conséquent, il ne fait pas de distinction entre les pointeurs et les valeurs. Permettez-moi d'essayer d'expliquer par et par exemple:

void func1(int x)
{
   x = 5;
}

void func2(int *x)
{
   int a;
   x = &a;
}

L'opération est la même pour la machine dans les deux fonctions: elle récupère l'argument et le modifie. Notez que, en deuxième fonction, il ne modifie pas * x, il modifie x

Maintenant, si nous appelons ces fonctions,

int y = 10;

func1(y); //value of y does not change

func2(&y); //value of &y does not change, but the value of the address which y points may change. 

Je préfère dire que, en gros, chaque appel de fonction est "appel par valeur" . Mais dans le cas d'un type de pointeur, nous avons un moyen de changer le contenu d'une autre adresse en mémoire. 

Si nous avions écrit func2 comme

void func2(int *x)
{ 
   *x = 5; 
}

Il s'agirait alors d'un cas réel "d'appel par référence". 

8
Atilla Baspinar

Oui, comme en C.

Dans ce cas, est-ce une procédure acceptable/standard d’utiliser un pointeur à un pointeur comme argument d’une fonction pour modifier la valeur du pointeur en tant que telle dans une fonction?

Dans quel cas? Qu'est-ce que tu veux? Vous pouvez utiliser de vraies références avec le modificateur &.

void func(type &ref);
0
nils

Un pointeur vers un pointeur ou une référence à un pointeur est ce que vous utiliseriez si vous souhaitiez modifier le pointeur lui-même. Pour répondre à votre question initiale, techniquement, tous les paramètres sont passés par valeur.

0
Jim Buck