Quelle est la différence entre passer par la référence et passer par la valeur?

Quelle est la différence entre

  1. un paramètre passé par référence
  2. un paramètre passé en valeur?

Pourriez-vous me donner des exemples, s’il vous plaît?

    Lorsqu’un paramètre est passé par référence , l’appelant et l’appelé utilisent la même variable pour le paramètre. Si l’appelé modifie la variable de paramètre, l’effet est visible pour la variable de l’appelant.

    Lorsqu’un paramètre est passé par valeur , l’appelant et l’appelé ont deux variables indépendantes de même valeur. Si l’appelé modifie la variable de paramètre, l’effet n’est pas visible pour l’appelant.

    Toutefois , si la valeur en question est un object de type référence mutable ou si, indirectement, elle référence d’autres valeurs, vous pouvez émuler l’ appel par référence dans un environnement appel par valeur: si l’appelé modifie l’object (ou d’autres valeurs pointées) à l’object), ces modifications sont visibles pour l’appelant. Mais l’émulation n’est pas exactement la même, car seules les modifications apscopes à l’ object , et non à la variable , sont visibles. Cela conduit à des explications déformées comme “appeler par valeur où la valeur est une référence”. Cet état de choses quelque peu déroutant est le suivant: combien de langages de programmation populaires fonctionnent aujourd’hui et, par conséquent, les gens confondent souvent les objects passants mutables par la valeur de référence par référence.

    Pour plus d’explications, voir les autres réponses ci-dessous.


    REMARQUE : Pendant longtemps, cette réponse disait:

    Disons que je veux partager une page Web avec vous. Si je vous dis l’URL, je passe par référence. Vous pouvez utiliser cette URL pour voir la même page Web que je peux voir. Si cette page est modifiée, nous voyons tous les deux les changements. Si vous supprimez l’URL, vous ne faites que détruire votre référence à cette page – vous ne supprimez pas la page elle-même.

    Si j’imprime la page et vous donne l’impression, je passe par valeur. Votre page est une copie déconnectée de l’original. Vous ne verrez aucune modification ultérieure et les modifications que vous apportez (par exemple, gribouillage sur votre impression) n’apparaîtront pas sur la page d’origine. Si vous détruisez l’impression, vous avez détruit votre copie de l’object – mais la page Web d’origine rest intacte.

    C’est une analogie simple, facile à comprendre, qui a eu ce billet des centaines de commentaires. Cependant, l’analogie est erronée: l’appel par référence et l’appel par valeur ne sont pas comme les URL. (Un type de référence dans un langage comme C # est comme une URL; consultez les excellentes informations de Jon Skeet sur les types de référence dans .NET pour plus de détails. Mais les types de référence ne sont pas la même chose que la référence .)

    Comme cette analogie n’est pas correcte, elle a été retirée de cette réponse. Voir aussi les commentaires ci-dessous où cela a été discuté.

    C’est un moyen de transmettre des arguments à des fonctions. Passer par référence signifie que le paramètre des fonctions appelées sera le même que l’argument passé des appelants (pas la valeur, mais l’identité – la variable elle-même). Passer par valeur signifie que le paramètre des fonctions appelées sera une copie de l’argument passé de l’appelant. La valeur sera la même, mais l’identité – la variable – est différente. Ainsi, les modifications apscopes à un paramètre par la fonction appelée dans un cas modifient l’argument passé et, dans l’autre cas, modifient simplement la valeur du paramètre dans la fonction appelée (qui n’est qu’une copie). En toute hâte:

    • Java ne supporte que le passage par valeur. Copie toujours les arguments, même si lors de la copie d’une référence à un object, le paramètre de la fonction appelée pointe vers le même object et les modifications apscopes à cet object apparaissent dans l’appelant. Comme cela peut être déroutant, voici ce que Jon Skeet a à dire à ce sujet.
    • C # supporte le passage par valeur et passe par référence (mot clé ref utilisé à l’appelant et fonction appelée). Jon Skeet a également une bonne explication à ce sujet ici .
    • C ++ supporte le passage par valeur et passe par référence (type de paramètre de référence utilisé à la fonction appelée). Vous trouverez une explication de ceci ci-dessous.

    Codes

    Comme ma langue est le C ++, je vais l’utiliser ici

     // passes a pointer (called reference in java) to an integer void call_by_value(int *p) { // :1 p = NULL; } // passes an integer void call_by_value(int p) { // :2 p = 42; } // passes an integer by reference void call_by_reference(int & p) { // :3 p = 42; } // this is the java style of passing references. NULL is called "null" there. void call_by_value_special(int *p) { // :4 *p = 10; // changes what p points to ("what p references" in java) // only changes the value of the parameter, but *not* of // the argument passed by the caller. thus it's pass-by-value: p = NULL; } int main() { int value = 10; int * pointer = &value; call_by_value(pointer); // :1 assert(pointer == &value); // pointer was copied call_by_value(value); // :2 assert(value == 10); // value was copied call_by_reference(value); // :3 assert(value == 42); // value was passed by reference call_by_value_special(pointer); // :4 // pointer was copied but what pointer references was changed. assert(value == 10 && pointer == &value); } 

    Et un exemple en Java ne fera pas de mal:

     class Example { int value = 0; // similar to :4 case in the c++ example static void accept_reference(Example e) { // :1 e.value++; // will change the referenced object e = null; // will only change the parameter } // similar to the :2 case in the c++ example static void accept_primitive(int v) { // :2 v++; // will only change the parameter } public static void main(Ssortingng... args) { int value = 0; Example ref = new Example(); // reference // note what we pass is the reference, not the object. we can't // pass objects. The reference is copied (pass-by-value). accept_reference(ref); // :1 assert ref != null && ref.value == 1; // the primitive int variable is copied accept_primitive(value); // :2 assert value == 0; } } 

    Wikipédia

    http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_value

    http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_reference

    Ce type le cloue à peu près:

    http://javadude.com/articles/passbyvalue.htm

    Voici un exemple:

     #include  void by_val(int arg) { arg += 2; } void by_ref(int&arg) { arg += 2; } int main() { int x = 0; by_val(x); std::cout << x << std::endl; // prints 0 by_ref(x); std::cout << x << std::endl; // prints 2 int y = 0; by_ref(y); std::cout << y << std::endl; // prints 2 by_val(y); std::cout << y << std::endl; // prints 2 } 

    Beaucoup de réponses ici (et en particulier la réponse la plus fortement votée) sont inexactes sur le plan des faits, car elles comprennent mal ce que signifie réellement «appel par référence». Voici ma tentative de mettre les choses au clair.

    TL; DR

    En termes simples:

    • call by value signifie que vous transmettez des valeurs comme arguments de fonction
    • appeler par référence signifie que vous passez des variables en tant qu’arguments de fonction

    En termes métaphoriques:

    • Call by value est l’endroit où j’écris quelque chose sur un bout de papier et que je vous le remets . Peut-être que c’est une URL, peut-être une copie complète de War and Peace. Quoi qu’il en soit, c’est sur un bout de papier que je vous ai donné, et c’est maintenant votre papier . Vous êtes maintenant libre de griffonner sur ce bout de papier ou d’utiliser ce bout de papier pour trouver quelque chose d’autre et le manipuler, peu importe.
    • L’appel par référence est quand je vous donne mon cahier qui contient quelque chose . Vous pouvez griffonner dans mon cahier (peut-être que je le veux, peut-être que je ne le fais pas), et ensuite je garde mon cahier avec tous les gribouillis que vous avez mis là. De plus, si ce que vous ou moi écrivons, il y a des informations sur la façon de trouver quelque chose ailleurs, vous ou moi pouvons aller là-bas et manipuler cette information.

    Ce que “call by value” et “call by reference” ne signifient pas

    Notez que ces deux concepts sont complètement indépendants et orthogonaux du concept de types de référence (qui en Java sont tous des types qui sont des sous-types d’ Object et en C # tous class types de class ), ou le concept de type pointeur comme C sémantiquement équivalent aux “types de référence” de Java, simplement avec une syntaxe différente).

    La notion de type de référence correspond à une URL: elle est à la fois une information et une référence (un pointeur , si vous voulez) à d’autres informations. Vous pouvez avoir plusieurs copies d’une URL à des endroits différents et elles ne modifient pas le site Web auquel elles sont toutes associées. Si le site Web est mis à jour, chaque copie d’URL mènera toujours à l’information mise à jour. Inversement, la modification de l’URL à un endroit quelconque n’affectera aucune autre copie écrite de l’URL.

    Notez que C ++ a une notion de “références” (par exemple, int& ) qui n’est pas comme les “types de référence” de Java et de C #, mais est comme “appel par référence”. Les “types de référence” de Java et C #, et tous les types de Python, sont comme ce que C et C ++ appellent les “types de pointeurs” (par exemple int* ).


    OK, voici l’explication plus longue et plus formelle.

    Terminologie

    Pour commencer, je veux mettre en évidence quelques éléments importants de la terminologie, pour aider à clarifier ma réponse et pour nous assurer que nous faisons tous référence aux mêmes idées lorsque nous utilisons des mots. (Dans la pratique, je pense que la grande majorité de la confusion sur des sujets tels que ceux-ci provient de l’utilisation de mots de manière à ne pas communiquer pleinement le sens voulu.)

    Pour commencer, voici un exemple de langage C-like d’une déclaration de fonction:

     void foo(int param) { // line 1 param += 1; } 

    Et voici un exemple d’appeler cette fonction:

     void bar() { int arg = 1; // line 2 foo(arg); // line 3 } 

    En utilisant cet exemple, je veux définir quelques éléments importants de la terminologie:

    • foo est une fonction déclarée sur la ligne 1 (Java insiste sur la création de toutes les méthodes de fonctions, mais le concept est le même sans perte de généralité; C et C ++ distinguent déclaration et définition que je n’entrerai pas ici)
    • param est un paramètre formel pour foo , également déclaré sur la ligne 1
    • arg est une variable , en particulier une variable locale de la bar fonctions, déclarée et initialisée sur la ligne 2
    • arg est aussi un argument pour une invocation spécifique de foo sur la ligne 3

    Il y a deux ensembles de concepts très importants à distinguer ici. Le premier est la valeur par rapport à la variable :

    • Une valeur est le résultat de l’évaluation d’une expression dans la langue. Par exemple, dans la fonction bar ci-dessus, après la ligne int arg = 1; , l’expression arg a la valeur 1 .
    • Une variable est un conteneur pour les valeurs . Une variable peut être mutable (c’est la valeur par défaut dans la plupart des langages de type C), en lecture seule (par exemple, déclarée en Java final ou en C # en readonly ) ou profondément immuable (par exemple en utilisant C ++).

    L’autre paire importante de concepts à distinguer est le paramètre et l’ argument :

    • Un paramètre (également appelé paramètre formel ) est une variable qui doit être fournie par l’appelant lors de l’appel d’une fonction.
    • Un argument est une valeur fournie par l’appelant d’une fonction pour satisfaire un paramètre formel spécifique de cette fonction

    Appel par valeur

    Dans l’ appel par valeur , les parameters formels de la fonction sont des variables nouvellement créées pour l’invocation de la fonction et qui sont initialisées avec les valeurs de leurs arguments.

    Cela fonctionne exactement de la même manière que les autres types de variables sont initialisés avec des valeurs. Par exemple:

     int arg = 1; int another_variable = arg; 

    Ici, arg et another_variable sont des variables complètement indépendantes – leurs valeurs peuvent changer indépendamment les unes des autres. Cependant, au point où another_variable est déclaré, il est initialisé pour contenir la même valeur que arg – qui est 1 .

    Comme ce sont des variables indépendantes, les modifications apscopes à another_variable n’affectent pas les arg :

     int arg = 1; int another_variable = arg; another_variable = 2; assert arg == 1; // true assert another_variable == 2; // true 

    Ceci est exactement la même que la relation entre arg et param dans notre exemple ci-dessus, que je vais répéter ici pour la symésortinge:

     void foo(int param) { param += 1; } void bar() { int arg = 1; foo(arg); } 

    C’est exactement comme si nous avions écrit le code de cette façon:

     // entering function "bar" here int arg = 1; // entering function "foo" here int param = arg; param += 1; // exiting function "foo" here // exiting function "bar" here 

    En d’autres termes, la caractéristique de définition de l’ appel par valeur est que l’appelé ( foo dans ce cas) reçoit des valeurs en tant qu’arguments, mais possède ses propres variables séparées pour ces valeurs à partir des variables de l’appelant.

    Pour revenir à ma métaphore ci-dessus, si je suis bar et que vous êtes foo , quand je vous appelle, je vous remets un morceau de papier avec une valeur écrite. Vous appelez ce morceau de papier param . Cette valeur est une copie de la valeur que j’ai écrite dans mon carnet (mes variables locales), dans une variable que j’appelle arg .

    (À titre d’exception: selon le matériel et le système d’exploitation, il existe diverses conventions d’appel sur la façon dont vous appelez une fonction d’une autre. La convention d’appel est comme si nous décidions d’écrire la valeur sur une feuille , ou si vous avez un morceau de papier sur lequel je l’écris, ou si je l’écris sur le mur devant nous deux. Il s’agit également d’un sujet intéressant, mais dépassant largement le cadre de cette réponse déjà longue.)

    Appeler par référence

    En appel par référence , les parameters formels de la fonction sont simplement de nouveaux noms pour les mêmes variables que l’appelant fournit en arguments.

    Pour revenir à notre exemple ci-dessus, cela équivaut à:

     // entering function "bar" here int arg = 1; // entering function "foo" here // aha! I note that "param" is just another name for "arg" arg /* param */ += 1; // exiting function "foo" here // exiting function "bar" here 

    Comme param est juste un autre nom pour arg – c’est-à-dire qu’ils sont la même variable , les modifications apscopes à param sont reflétées dans arg . C’est la manière fondamentale par laquelle l’appel par référence diffère de l’appel par la valeur.

    Très peu de langages supportent l’appel par référence, mais C ++ peut le faire comme ceci:

     void foo(int& param) { param += 1; } void bar() { int arg = 1; foo(arg); } 

    Dans ce cas, param n’a pas simplement la même valeur que arg , il s’agit en fait d’ arg (par un nom différent) et bar peut donc observer que arg a été incrémenté.

    Notez que ce n’est pas ainsi que Java, JavaScript, C, Objective-C, Python ou presque n’importe quel autre langage populaire fonctionnent. Cela signifie que ces langues ne sont pas appel par référence, elles sont appelées par valeur.

    Addendum: appel par partage d’objects

    Si ce que vous avez est un appel par valeur , mais que la valeur réelle est un type de référence ou un type de pointeur , alors la “valeur” elle-même n’est pas très intéressante (par exemple, en C Ce qui est intéressant est ce que cette valeur indique .

    Si ce sharepoint référence (c’est-à-dire un pointeur) est modifiable, alors un effet intéressant est possible: vous pouvez modifier la valeur pointée et l’appelant peut observer les modifications de la valeur pointée, même si l’appelant ne peut pas observer change le pointeur lui-même.

    Pour reprendre l’analogie de l’URL, le fait que je vous ai remis une copie de l’URL sur un site Web n’est pas particulièrement intéressant si ce qui nous intéresse tous les deux, c’est le site Web et non l’URL. Le fait que vous écriviez par-dessus votre copie de l’URL n’affecte pas ma copie de l’URL n’est pas une chose à laquelle nous tenons (et en fait, dans des langages comme Java et Python, la valeur “URL” ne soit pas modifié du tout, seulement la chose indiquée par elle peut.

    Barbara Liskov, lorsqu’elle a inventé le langage de programmation CLU (qui possédait ces sémantiques), s’est rendu compte que les termes existants “appel par valeur” et “appel par référence” n’étaient pas particulièrement utiles pour décrire la sémantique de ce nouveau langage. Elle a donc inventé un nouveau terme: call by object sharing .

    Quand on parle de langages qui sont techniquement appel par valeur, mais où les types courants sont des types de référence ou de pointeur (c’est-à-dire: presque tous les langages de programmation impératifs, orientés object ou multi-paradigmes), je trouve que évitez tout simplement de parler d’ appel par valeur ou d’ appeler par référence . S’en tenir à l’ appel par le partage d’objects (ou simplement appeler par object ) et personne ne sera confus. 🙂

    Avant de comprendre les 2 termes, vous DEVEZ comprendre ce qui suit. Chaque object a 2 choses qui peuvent le faire distinguer.

    • Sa valeur.
    • Son adresse

    Donc, si vous dites employee.name = "John"

    sachez qu’il y a 2 choses à propos du name . Sa valeur qui est "John" et aussi son emplacement dans la mémoire qui est un nombre hexadécimal peut-être comme ceci: 0x7fd5d258dd00 .

    Selon l’architecture de la langue ou le type (classe, structure, etc.) de votre object, vous transféreriez "John" ou 0x7fd5d258dd00

    Passer "John" est considéré comme un dépassement de valeur. Passer 0x7fd5d258dd00 est considéré comme passant par référence. Quiconque pointe vers cet emplacement mémoire aura access à la valeur de "John" .

    Pour plus d’informations à ce sujet, je vous recommande de lire le déréférencement d’un pointeur et aussi de choisir struct (type de valeur) sur class (type de référence)

    La manière la plus simple de l’obtenir est sur un fichier Excel. Disons par exemple que vous avez deux nombres, 5 et 2 dans les cellules A1 et B1 en conséquence, et que vous voulez trouver leur sum dans une troisième cellule, disons A2. Vous pouvez le faire de deux manières.

    • Soit en passant leurs valeurs à la cellule A2 en tapant = 5 + 2 dans cette cellule. Dans ce cas, si les valeurs des cellules A1 ou B1 changent, la sum dans A2 rest la même.

    • Ou en passant les “références” des cellules A1 et B1 à la cellule A2 en tapant = A1 + B1 . Dans ce cas, si les valeurs des cellules A1 ou B1 changent, la sum dans A2 change également.

    Comparaison: Valeur vs. Référence

    Valeur par défaut Les parameters locaux sont des copies des arguments d’origine transmis dans Modifications apscopes dans la fonction à ces variables n’affectent pas les originaux

    Référence par défaut Les parameters locaux sont des références aux emplacements de stockage des arguments d’origine transmis. Les modifications apscopes à ces variables dans la fonction affecteront les originaux. Aucune copie n’est effectuée, de sorte que la copie de la copie (heure, stockage) est enregistrée.

    En passant par ref, vous passez essentiellement un pointeur sur la variable. Passez par valeur que vous transmettez une copie de la variable. Dans l’utilisation de base, cela signifie normalement que les modifications apscopes à la variable seront considérées comme la méthode appelante et qu’elles passeront par valeur.

    Pass by value envoie une COPIE des données stockées dans la variable que vous spécifiez, le passage par référence envoie un lien direct vers la variable elle-même. Donc, si vous passez une variable par référence et que vous modifiez ensuite la variable à l’intérieur du bloc dans lequel vous l’avez transmise, la variable d’origine sera modifiée. Si vous passez simplement par valeur, la variable d’origine ne pourra pas être modifiée par le bloc dans lequel vous l’avez transmise, mais vous obtiendrez une copie de tout ce qu’elle contenait au moment de l’appel.

    La principale différence entre ces variables est que les variables de type valeur stockent des valeurs. La spécification d’une variable de type valeur dans un appel de méthode transmet une copie de la valeur de cette variable à la méthode. Les variables de type référence contiennent des références à des objects. Par conséquent, la spécification d’une variable de type référence en tant qu’argument transmet à la méthode une copie de la référence réelle qui fait référence à l’object. Même si la référence elle-même est transmise par valeur, la méthode peut toujours utiliser la référence reçue pour interagir avec l’object d’origine et éventuellement la modifier. De même, lors du retour d’informations à partir d’une méthode via une instruction return, la méthode retourne une copie de la valeur stockée dans une variable de type valeur ou une copie de la référence stockée dans une variable de type référence. Lorsqu’une référence est renvoyée, la méthode appelante peut utiliser cette référence pour interagir avec l’object référencé. Donc, en effet, les objects sont toujours passés par référence.

    Dans c #, pour passer une variable par référence afin que la méthode appelée puisse modifier la variable, C # fournit les mots-clés ref et out. L’application du mot-clé ref à une déclaration de paramètre vous permet de transmettre une variable à une méthode par référence – la méthode appelée pourra modifier la variable d’origine dans l’appelant. Le mot-clé ref est utilisé pour les variables qui ont déjà été initialisées dans la méthode appelante. Normalement, lorsqu’un appel de méthode contient une variable non initialisée en tant qu’argument, le compilateur génère une erreur. Le fait de précéder un paramètre avec un mot-clé en sortie crée un paramètre de sortie. Cela indique au compilateur que l’argument sera transmis par référence à la méthode appelée et que la méthode appelée assignera une valeur à la variable d’origine dans l’appelant. Si la méthode n’atsortingbue pas de valeur au paramètre de sortie dans chaque chemin d’exécution possible, le compilateur génère une erreur. Cela empêche également le compilateur de générer un message d’erreur pour une variable non initialisée transmise en tant qu’argument à une méthode. Une méthode peut renvoyer une seule valeur à son appelant via une instruction return, mais peut renvoyer plusieurs valeurs en spécifiant plusieurs parameters de sortie (ref et / ou out).

    voir la discussion et les exemples c # ici lien texte

    Pass by value – La fonction copie la variable et travaille avec une copie (elle ne change rien dans la variable d’origine)

    Passer par référence – La fonction utilise la variable d’origine, si vous modifiez la variable dans l’autre fonction, elle change également dans la variable d’origine.

    Exemple (copier et utiliser / essayer vous-même et voir):

     #include  using namespace std; void funct1(int a){ //pass-by-value a = 6; //now "a" is 6 only in funct1, but not in main or anywhere else } void funct2(int &a){ //pass-by-reference a = 7; //now "a" is 7 both in funct2, main and everywhere else it'll be used } int main() { int a = 5; funct1(a); cout< 

    Gardez les choses simples, peeps. Les murs de texte peuvent être une mauvaise habitude.

    Exemples:

     class Dog { public: barkAt( const std::ssortingng& pOtherDog ); // const reference barkAt( std::ssortingng pOtherDog ); // value }; 

    const & est généralement le meilleur. Vous n’encourez pas la pénalité de construction et de destruction. Si la référence n’est pas constante, votre interface suggère qu’elle changera les données transmises.

    En bref, Passed by value est ce que c’est et passé par référence est WHERE où il est.

    Si votre valeur est VAR1 = “Happy Guy!”, Vous ne verrez que “Happy Guy!”. Si VAR1 devient “Happy Gal!”, Vous ne le saurez pas. Si elle est passée par référence et que VAR1 change, vous le ferez.

    Par définition, le passage par valeur signifie que vous faites une copie en mémoire de la valeur réelle du paramètre transmise, une copie du contenu du paramètre réel. Utilisez pass by value lorsque vous utilisez uniquement le paramètre pour un calcul, sans le modifier pour le programme client.

    En passant par référence (également appelée adresse de passage), une copie de l’adresse du paramètre réel est stockée. Utilisez pass by reference lorsque vous modifiez le paramètre transmis par le programme client.

    pass by value signifie comment transmettre une valeur à une fonction en utilisant des arguments. en passant par valeur nous copions les données stockées dans la variable que nous spécifions et cela est plus lent que le passage par référence bcse t les données sont copiées. de nous apportons des modifications aux données copiées, les données d’origine ne sont pas affectées. En passant, par référence ou par adresse, nous envoyons un lien direct vers la variable elle-même. ou en passant un pointeur sur une variable. c’est plus rapide bcse moins de temps est consommé

    Si vous ne voulez pas changer la valeur de la variable d’origine après l’avoir passée dans une fonction, la fonction doit être construite avec un paramètre ” pass by value “.

    La fonction aura alors UNIQUEMENT la valeur mais pas l’adresse de la variable passée. Sans l’adresse de la variable, le code contenu dans la fonction ne peut pas modifier la valeur de la variable vue de l’extérieur de la fonction.

    Mais si vous voulez donner à la fonction la possibilité de changer la valeur du variabl * e vu de l’extérieur, vous devez utiliser le mot de passe par référence . Comme la valeur et l’adresse (référence) sont transmises et disponibles à l’intérieur de la fonction.

    Voici un exemple qui montre les différences entre les valeurs par point – valeur du pointeur – référence :

     void swap_by_value(int a, int b){ int temp; temp = a; a = b; b = temp; } void swap_by_pointer(int *a, int *b){ int temp; temp = *a; *a = *b; *b = temp; } void swap_by_reference(int &a, int &b){ int temp; temp = a; a = b; b = temp; } int main(void){ int arg1 = 1, arg2 = 2; swap_by_value(arg1, arg2); cout << arg1 << " " << arg2 << endl; //prints 1 2 swap_by_pointer(&arg1, &arg2); cout << arg1 << " " << arg2 << endl; //prints 2 1 arg1 = 1; //reset values arg2 = 2; swap_by_reference(arg1, arg2); cout << arg1 << " " << arg2 << endl; //prints 2 1 } 

    La méthode de «passage par référence» a une limitation importante . Si un paramètre est déclaré comme transmis par référence (il est donc précédé du signe &), son paramètre réel correspondant doit être une variable .

    Un paramètre réel faisant référence au paramètre formel «transmis par la valeur» peut être une expression en général. Il est donc permis d'utiliser non seulement une variable, mais également un résultat littéral ou même un invocation de fonction.

    La fonction n'est pas capable de placer une valeur dans autre chose qu'une variable. Il ne peut pas affecter une nouvelle valeur à un littéral ou forcer une expression à modifier son résultat.

    PS: Vous pouvez également vérifier la réponse de Dylan Beattie dans le fil de discussion actuel qui l'explique en termes clairs.

    Par valeur: lorsque des arguments sont transmis par valeur à une méthode, cela signifie qu’une copie de la variable réelle est envoyée à la méthode et non la méthode réelle. Par conséquent, toute modification appliquée à la méthode affecte réellement la version de copie.

    Par référence: Lorsque des arguments sont transmis par référence, cela signifie qu’une référence ou un pointeur vers la variable réelle est transmis à la méthode et non aux données de la variable réelle.

    Consultez cet article pour d’autres exemples.