Diagramă de comparație:
Bazele comparației | Call_By_Value | Apel prin referință |
---|---|---|
De bază | Se trece o copie a variabilei. | Se trece o variabilă în sine. |
Efect | Modificarea unei copii a unei variabile nu modifică valoarea inițială a variabilei în afara funcției. | Schimbarea variabilei afectează și valoarea variabilei în afara funcției. |
Apelarea parametrilor | nume_funcțional (nume_ variabilă1, nume variabil2, ...; ...); | nume_funcțional (& variable_name1, & variable_name2, ...;); // în cazul obiectului object.func_name (obiect); |
Recepționarea parametrilor | tip nume_funcțional (tip variabilă_name1, tip variabilă_name2, ... ...) {. . } | tip nume_funcție (tip * nume_ variabilă1, tip * variabilă_name2, ....). . } // în cazul obiectului tip nume_funcțional (nume_tip nume_clasă) {. . } |
Apel în așteptare | primitiv tip sunt trecute folosind "apel de valoare". | obiectele sunt trecute implicit folosind "apel prin referință". |
Definiția Call By Value
Dacă treceți un tip de date primitiv (întreg, caracter și șir) la o funcție / metodă, atunci numai codul "funcția" este trecut la codul funcției. Funcția copiază valoarea unui argument într-un "parametru formal" al codului funcției. Dacă există o modificare a parametrului formal într-un cod de funcții, acesta nu va modifica valoarea inițială a argumentului utilizat pentru apelarea acelei funcții.
Cu cuvinte simple, dacă o funcție / metodă este apelată de abordarea "apel prin valoare"; apoi o copie a variabilei este transmisă codului funcției. Dacă un cod de funcții aduce modificări valorii în copia variabilei, acesta nu modifică valoarea inițială a variabilei.
Să vedem un exemplu pentru a înțelege acest lucru pe scurt.
// exemplu în clasa Java verificați {void change (int i, int j) {i = i * i; j = j / 2; system.out.println ("valoarea parametrului din interiorul funcției"); system.out.println ("valoarea lui" i "care acceptă valoarea argumentului" a "" + i); system.out.println ("valoarea lui 'j' care acceptă valoarea argumentului 'b'" + j); }} clasa call_by _value {public static void principal (șir args []) {int a = 12, b = 20; verificați C = verificare nouă (); system.out.println ("valoarea" a "și" b "înainte de apelul funcției" + a + "" + b); C.change (a, b); // apel prin valoare. system.out.println ("valoarea" a "și" b "după apelul funcției" + a + "" + b); }} // valoarea de ieșire a 'a' și 'b' înainte de apelarea funcției 12 20 valoarea parametrului din interiorul valorii funcției 'i' care acceptă valoarea argumentului 'a' 144 'j' care acceptă valoarea argumentul "b" 10 a "a" și "b" după apelul funcției 12 20
Definiția Call by Reference
Apelul prin metoda de referință transmite o referință / o adresă a unui argument la codul funcției. Pe măsură ce adresa unui argument este transmisă codului funcției, parametrul formal care acceptă acea adresă ar fi o variabilă "pointer". Acum, deoarece codul de funcții a obținut adresa unui argument, modificarea valorii unui argument va modifica, de asemenea, valoarea inițială a unui argument.
În C ++ și Java, este foarte comună trecerea obiectului la funcția / metoda și obiectul este întotdeauna trecut prin referința sa. Modificările aduse obiectului din interiorul funcției / metodei afectează obiectul utilizat pentru a invoca acea funcție / metodă.
Următorul fragment prezintă modul corect de a "apela prin referință".
// exemplu în swap de clasă C ++ {void swap (int * x, int * y) {int temp; temp = * x; * X = y *; * Y = temp; }} int principal {int a = 10, b = 20; cout << "a lui a, b inainte de apelul functiei" << a << "" <Acum, să discutăm "apel prin referință" prin trecerea unui "obiect" ca argument, care este implicit adoptat de abordarea "apel prin referință".
clasa de verificare {int a, b; verificați (int x, int b) {// obiect inițializat prin acest constrtuctor a = x; b = y; } void exchange (verificați ob) {ob.a = a * 2; ob.b = b / 2; }} class main_class {public static void principal (string args []) {check C = verificare nouă (20, 40); // initializarea obiectelor. system.out.println ("valoarea" ob.a "și" ob.b "înainte de apelarea funcției" + ob.a + "" + ob.b); C.exchange (C); // apel prin referință. system.out.println ("valoarea" ob.a "și" ob.b "înainte de apelarea funcției" + ob.a + "" + ob.b); }} // valoarea de ieșire a 'ob.a' și 'ob.b' înainte de apelarea funcției 20 40 valoarea 'ob.a' și 'ob.b' după apelul funcției 40 20Diferențele cheie între valoarea apelului și apelul prin referință
- Transmiterea argumentului prin utilizarea abordării "apel prin valoare" trece numai copia acelei variabile, astfel încât modificările aduse valorii în copia acelei variabile nu afectează valoarea inițială a acelei variabile. În abordarea "apel prin referință", variabila însăși este trecută ca argument, astfel încât modificările aduse acesteia modifică valoarea variabilei inițiale.
- Dacă argumentele transmise sunt tipuri de date primitive, acestea sunt pur și simplu "apel prin valoare", dar dacă referințele / adresele argumentelor sau obiectelor sunt transmise, atunci o funcție este apelată prin metoda "apel prin referință".
- În abordarea "apel prin valoare" argumentele transmise sunt doar numele variabilelor, în timp ce în abordarea "apel prin referință" argumentele transmise sunt numele variabilei de-a lungul semnalului "&" sau un obiect care este trecut doar prin numele său.
- Primirea parametrilor argumentului în abordarea "apel prin valoare" este numele variabilei împreună cu tipul de date. În abordarea "apel prin referință", parametrul de primire este întotdeauna o variabilă a indicelui împreună cu tipul de date, iar în cazul obiectului este un nume de obiect împreună cu tipul său de clasă.
Concluzie:
C ++ și Java utilizează ambele abordări în funcție de ceea ce este trecut. Dacă doriți să treceți numai valoarea variabilei use'call by value și dacă doriți să vedeți modificarea valorii inițiale a variabilei, utilizați abordarea "apel prin referință".