
Wykres porównania:
Podstawa do porównania | Call_By_Value | Call By Reference |
---|---|---|
Podstawowy | Kopia zmiennej jest przekazywana. | Sama zmienna jest przekazywana. |
Efekt | Zmiana kopii zmiennej nie zmienia oryginalnej wartości zmiennej poza stroną funkcji. | Zmiana zmiennej wpływa również na wartość zmiennej poza funkcją. |
Wywoływanie parametrów | nazwa_funkcji (nazwa_zmiennej1, nazwa_zmiennej2, ...); | nazwa_funkcji (i nazwa_zmiennej1 i nazwa_ zmiennej 2, ...); // w przypadku obiektu object.func_name (object); |
Odbieranie parametrów | type nazwa_funkcji (typ nazwa_zmiennej1, typ nazwa_zmiennej2, ...) {. . } | typ nazwa_funkcji (typ * nazwa_zmiennej1, typ * nazwa_zmiennej2, ...). . } // w przypadku obiektu type nazwa_funkcji (class_type nazwa_obiektu) {. . } |
Domyślne połączenia | typ pierwotny jest przekazywany za pomocą "wywołania według wartości". | obiekty są niejawnie przekazywane za pomocą "wywołania przez odniesienie". |
Definicja połączenia według wartości
Jeśli przekazujesz prymitywny typ danych (liczbę całkowitą, znak i łańcuch) do funkcji / metody, tylko jej "wartość" jest przekazywana do kodu funkcji. Funkcja kopiuje tę wartość argumentu do "formalnego parametru" kodu funkcji. Jeśli istnieje jakakolwiek modyfikacja formalnego parametru w kodzie funkcji, nie zmieni on oryginalnej wartości argumentu, który jest używany do wywołania tej funkcji.
W prostych słowach, jeśli funkcja / metoda jest wywoływana przez podejście "wywołanie według wartości"; następnie kopia zmiennej jest przekazywana do kodu funkcji. Jeśli kod funkcji wprowadza jakiekolwiek zmiany wartości w kopii zmiennej, nie zmienia oryginalnej wartości zmiennej.
Zobaczmy krótki przykład, aby to zrozumieć.
// przykład w klasie Java sprawdź {void change (int i, int j) {i = i * i; j = j / 2; system.out.println ("wartość parametru w funkcji"); system.out.println ("wartość" i ", która akceptuje wartość argumentu" a "" + i); system.out.println ("wartość" j ", która akceptuje wartość argumentu" b "" + j); }} class call_by _value {public static void main (string args []) {int a = 12, b = 20; sprawdź C = new check (); system.out.println ("wartość" a "i" b "przed wywołaniem funkcji" + a + "" + b); C.zmian (a, b); // wywołanie według wartości. system.out.println ("wartość" a "i" b "po wywołaniu funkcji" + a + "" + b); }} // wartość wyjściowa "a" i "b" przed wywołaniem funkcji 12 20 wartość parametru wewnątrz wartości funkcji "i", która akceptuje wartość argumentu "a" 144 wartość "j", która akceptuje wartość argument "b" 10 wartość "a" i "b" po wywołaniu funkcji 12 20
Definicja połączenia według referencji
Wywołanie metodą Reference przekazuje referencję / adres argumentu do kodu funkcji. Gdy adres argumentu zostanie przekazany do kodu funkcji, formalny parametr akceptujący ten adres będzie zmienną "wskaźnikową". Teraz, gdy kod funkcji uzyskał adres argumentu, modyfikacja wartości argumentu spowoduje również zmianę oryginalnej wartości argumentu.
W językach C ++ i Java bardzo często przekazuje się obiekt do funkcji / metody, a obiekt jest zawsze przekazywany za pomocą jego odwołania. Zmiany dokonane w obiekcie wewnątrz funkcji / metody wpływają na obiekt używany do wywołania tej funkcji / metody.
Poniższy fragment pokazuje prawidłowy sposób "wywołania przez odniesienie".
// przykład w zamianie klas C ++ {void swap (int * x, int * y) {int temp; temp = * x; * x = * y; * Y = temperatura; }} int main {int a = 10, b = 20; cout << "wartość a, b przed wywołaniem funkcji" << a << "" <Porozmawiajmy teraz o "wywołaniu przez referencję", przekazując "obiekt" jako argument, który jest domyślnie przekazywany przez podejście "wywołanie przez odniesienie".
sprawdzenie klasy {int a, b; check (int x, int b) {// obiekt zainicjalizowany przez ten konwektor a = x; b = y; } void exchange (check ob) {ob.a = a * 2; ob.b = b / 2; }} class main_class {public static void main (string args []) {sprawdź C = new check (20, 40); // inicjowanie obiektu. system.out.println ("wartość" ob.a "i" ob.b "przed wywołaniem funkcji" + ob.a + "" + ob.b); C.exchange (C); // wywołanie przez odniesienie. system.out.println ("wartość" ob.a "i" ob.b "przed wywołaniem funkcji" + ob.a + "" + ob.b); }} // wartość wyjściowa "ob.a" i "ob.b" przed wywołaniem funkcji 20 40 wartość "ob.a" i "ob.b" po wywołaniu funkcji 40 20Kluczowe różnice między wezwaniem według wartości i wezwaniem przez odniesienie
- Przekazanie argumentu za pomocą podejścia "wywołanie według wartości" przekazuje tylko kopię tej zmiennej, więc zmiany wprowadzone do wartości w kopii tej zmiennej nie mają wpływu na oryginalną wartość tej zmiennej. W podejściu "wywołanie przez odwołanie" sama zmienna jest przekazywana jako argument, więc zmiany w niej modyfikują wartość oryginalnej zmiennej.
- Jeśli przekazane argumenty są prymitywnymi typami danych, są po prostu "wywoływaniem przez wartość", ale jeśli referencje / adresy argumentów lub obiektów są przekazywane, wówczas funkcja jest wywoływana przez metodę "wywołania przez odwołanie".
- W "podejściu według wartości" przekazywane argumenty są tylko nazwą zmiennych, natomiast w podejściu "wywołanie przez odwołanie" przekazywane są następujące argumenty: nazwa zmiennej wzdłuż znaku "&" lub obiekt, który jest przekazywany tylko przez jego nazwę.
- Odbieranie parametrów argumentu w podejściu "call by value" to nazwa zmiennej wraz z jej typem danych. W podejściu "wywołanie przez odwołanie" parametr przyjmujący jest zawsze zmienną wskaźnika wraz z typem danych, aw przypadku obiektu jest nazwą obiektu wraz z typem klasy.
Wniosek:
C ++ i Java wykorzystują oba podejścia w zależności od tego, co zostało przekazane. Jeśli chcesz przekazać tylko wartość zmiennej use'call według wartości i jeśli chcesz zobaczyć zmianę oryginalnej wartości zmiennej, użyj metody "wywołanie przez odwołanie".