Was ist der Unterschied zwischen Call by Value und Call by Reference in C?


Antwort 1:

Obwohl C keinen Aufruf als Referenz hat, nehmen wir an, dass es einen Zeiger übergibt. Versuchen wir anhand einfacher Beispiele zu verstehen, wie Parameter in Funktionen übergeben werden.

Lasst uns annehmen

Person X.

und

Person Y.

führen einige Anweisungen aus ihren jeweiligen Notizbüchern aus. Da jedes seine eigenen Notizbücher hat, können sie problemlos parallel ausgeführt werden.

Nehmen wir nun eine Situation an, in der

Person X.

und

Person Y.

Teilen Sie das gleiche Notizbuch. In diesem Fall, wenn Person X das Notebook verwendet, kann Person Y das Notebook nicht verwenden. Nur eine Person kann das Notebook verwenden. Außerdem weisen wir Person X einen bestimmten Teil und Person Y einen bestimmten Teil zu. Person X verwendet seinen Teil des Notizbuchs, wenn er das Notizbuch erhält, und Person Y verwendet seinen Teil des Notizbuchs, wenn er das Notizbuch erhält.

Jetzt möchte Person X die Hilfe von Person Y. Person Y kann eine Aktion ausführen, die von Person X benötigt wird. Dann muss Person X einige Informationen an Person Y weitergeben, damit Person Y die Aktion unter Verwendung dieser Informationen ausführen und die geben kann Ergebnis. Die Frage ist nun, wie die Person X die Informationen weitergibt. Ein Teil des Notizbuchs ist für die Weitergabe der Informationen vorgesehen.

Wenn Person X einige Informationen von ihrem lokalen Teil (1 - 300) übertragen möchte, kopiert sie diese von ihrem lokalen Teil in den gemeinsamen Teil (401 - 600). Dann kopiert Person Y vom gemeinsamen Teil in seinen lokalen Teil (701-1000).

Bei dieser Methode kann die Person Y nur ihren lokalen Teil ändern, nicht den gemeinsamen Teil oder den Teil der Person X.

Das Hauptproblem besteht jedoch darin, dass Person Y nach Abschluss der Operation nur einen Wert an Person X zurückgeben kann.

Lassen Sie uns dies anhand eines Beispiels verstehen. Person X möchte zwei Nummern 35 und 45 hinzufügen. Da diese Nummern zu Person X gehören, werden sie in Zeile 1 und Zeile 2 gespeichert.

Da Person X keine Addition kennt und die Hilfe von Person Y möchte, kopiert Person X die Zahlen von seinem Teil des Notizbuchs in den gemeinsamen Teil. Also wird 35 in Zeile 401 und 45 in Zeile 402 kopiert.

Jetzt ruft Person X Person Y an, um die Add-Funktion auszuführen. Dann kopiert Person Y die Werte vom gemeinsamen Teil in seinen Teil und führt die Operationen aus.

Jetzt führt Person Y die Addition von Zahlen in seinem Teil durch und speichert die Antwort in seinem Teil.

Hier ist ein Problem. Jetzt denken wir, dass Person Y das Ergebnis durch den gemeinsamen Teil übertragen wird. Das passiert aber nicht. Tatsächlich wird das Ergebnis über einen weiteren 1-zeiligen gemeinsamen Teil geteilt, der nicht Teil dieses Hauptnotizbuchs ist. Da dieser gemeinsame Teil nur eine Zeile ist, kann nur eine Antwort von Person Y an Person X zurückgegeben werden. Person X kann jedoch viele Nummern über den gemeinsamen Teil senden.

Jetzt kopiert Person X den Wert von diesem gemeinsamen Teil in seinen lokalen Teil.

Das ist alles. Jetzt bekam Person X die Antwort. Diese Methode ist im Allgemeinen gut, wenn Person Y eine Operation mit einer kleinen Anzahl von Werten ausführt und nur eine Ausgabe zurückgibt.

Diese Methode wird als "Aufruf nach Wert" bezeichnet.

Wenn Person Y mehr als 1 Wert zurückgibt, kann diese Methode nicht verwendet werden. Auch wenn Person Y eine große Anzahl von Eingaben verarbeitet, ist diese Methode nicht effizient. Also fanden die Leute eine neue Methode. Lassen Sie uns das jetzt diskutieren. Die neue Methode ist möglich, da sowohl Person X als auch Person Y ein einziges Notizbuch gemeinsam nutzen. So kann Person X auch das gesamte Notizbuch lesen und Person Y kann auch das gesamte Notizbuch lesen. dh Person X kann den Teil von Person Y lesen, auch Person Y kann den Teil von Person X lesen.

Betrachten wir nun dasselbe vorherige Problem, während wir auch diese Methode erläutern. Person X hat 3 Stellen in seinem Teil des Notizbuchs (1,2 & 3) zugewiesen, um die Zahlen und das Ergebnis zu speichern. Wie üblich speichert die Person X die beiden Nummern 35 und 45 an Position 1 und 2 ihres Portionsnotizbuchs.

Anstatt die Werte (35 und 45) in den gemeinsamen Teil (401, 402 und 403) zu kopieren, schreibt Person X die Positionen der Zahlen 1, 2 und 3.

Jetzt kopiert Person Y die Ortsnummern aus dem gemeinsamen Teil seines lokalen Teils (701, 702 und 703).

Da Person Y die Positionen der Werte hat, führt sie die Additionsoperation durch. Da Person X bereits den Ort angegeben hat, an dem Ergebnis (3) gespeichert werden muss, speichert Person X das Ergebnis (80) direkt an Ort 3.

""

Diese Methode wird als "Call by Reference" bezeichnet.

Versuchen wir nun, das obige Beispiel mit C zu vergleichen. Person X und Person Y sind "Funktion1" und "Funktion2". Notebook ist "Hauptspeicher", lokaler Teil des Notebooks heißt lokaler Speicher, der gemeinsame Teil ist Stapel. Der eine Ort, der Rückgabeort, ist der Akkumulator.

Die C-Implementierung von "Call by Value" und "Call by Reference" wird von anderen gut erklärt. Ich habe gerade versucht, allgemein zu erklären. Ich werde diesen Beitrag später mit weiteren Beispielen aktualisieren.



Antwort 2:

Wertaufruf bedeutet im Wesentlichen, dass eine Kopie der Variablen an die Funktion übergeben wird. Die Funktion ändert die ursprüngliche Variable nicht, wenn sie in die Funktionseingabevariable schreibt. Referenzübergabe bedeutet, dass im Wesentlichen die Variable selbst übergeben wird (obwohl sich der Name ändern kann). Schreibvorgänge in die Funktionseingabevariable gelten auch für die ursprüngliche Variable, und beim Aufrufen der Funktion wird keine Kopie der Variablen erstellt.



Antwort 3:

Angenommen, Sie möchten ein Bild bearbeiten. Dafür gibt es zwei Methoden:

Methode 1: Wenn Sie das Originalbild sowie das bearbeitete Bild beibehalten möchten. Sie erstellen eine Kopie des Bildes, ändern es und speichern es. Dies ist eine Aufrufmethode nach Wert - Sie erstellen eine Kopie der tatsächlichen Parameter, führen Operationen an diesen Kopien durch, ändern jedoch nicht die tatsächlichen Parameter.

Methode 2: Wenn Sie das Originalbild dauerhaft ändern möchten. Sie greifen auf das Bild von seiner Position (Referenz) zu, ändern es und speichern es. Dies wird als Referenzaufruf aufgerufen. Sie verwenden Referenzen, um auf die tatsächlichen Parameter zuzugreifen, Operationen mit diesen Parametern unter Verwendung dieser Referenzen auszuführen und am Ende Änderungen vorzunehmen die tatsächlichen Parameter.



Antwort 4:

Unterschied zwischen Call by Value und Call by Reference

Unterschied zwischen

Aufruf nach Wert

und

Anruf durch Referenz

Im

Aufruf nach Wert

wird eine Kopie der tatsächlichen Argumente an formale Argumente der aufgerufenen Funktion übergeben, und jede Änderung der formalen Argumente in der aufgerufenen Funktion hat keine Auswirkungen auf die Werte der tatsächlichen Argumente in der aufrufenden Funktion.

Im

Aufruf nach Wert

Die tatsächlichen Argumente bleiben sicher und können nicht versehentlich geändert werden.

Im

Anruf durch Referenz

wird der Ort (die Adresse) der tatsächlichen Argumente an formale Argumente der aufgerufenen Funktion übergeben. Dies bedeutet, dass wir durch Zugriff auf die Adressen der tatsächlichen Argumente diese innerhalb der aufgerufenen Funktion ändern können.

Im

Anruf durch Referenz

Eine Änderung der tatsächlichen Argumente ist innerhalb der aufgerufenen Funktion möglich. Daher muss der Code die Argumente sorgfältig behandeln, sonst erhalten Sie unerwartete Ergebnisse.

Beispiel mit Call by Value

Das klassische Beispiel für den Wunsch, den Speicher des Anrufers zu ändern, ist a

swapByValue ()

Funktion, die zwei Werte austauscht. Für C verwendet call by value die folgende Version von

Tauschen

swapByValue ()

wird nicht funktionieren...

  1. #umfassen void swapByValue (int, int); / * Prototyp * / int main () / * Hauptfunktion * / {int n1 = 10, n2 = 20; / * Die tatsächlichen Argumente sind unverändert * / swapByValue (n1, n2); printf ("n1:% d, n2:% d \ n", n1, n2);} void swapByValue (int a, int b) {int t; t = a; a = b; b = t;} OUTPUT ====== n1: 10, n2: 20

Das

swapByValue ()

wirkt sich nicht auf die Argumente aus

n1

und

n2

in der aufrufenden Funktion wird nur gearbeitet

ein

und

b

lokal zu

swapByValue ()

selbst. Dies ist ein gutes Beispiel für das Verhalten lokaler Variablen.

Beispiel mit Call by Reference

Beim Aufruf per Referenz, um eine Variable zu übergeben

n

Als Referenzparameter muss der Programmierer einen Zeiger auf übergeben

n

anstatt

n

selbst. Der formale Parameter ist ein Zeiger auf den interessierenden Wert. Die aufrufende Funktion muss verwendet werden

&

um den Zeiger des Aktualparameters zu berechnen. Die aufgerufene Funktion muss den Zeiger mit dereferenzieren

* *

gegebenenfalls, um auf den Wert von Interesse zuzugreifen. Hier ist ein Beispiel für eine korrekte

Tauschen

swapByReference ()

Funktion. Jetzt haben Sie den Unterschied zwischen Call by Value und Call by Reference!

  1. #umfassen void swapByReference (int *, int *); / * Prototyp * / int main () / * Hauptfunktion * / {int n1 = 10, n2 = 20; / * tatsächliche Argumente werden geändert * / swapByReference (& n1, & n2); printf ("n1:% d, n2:% d \ n", n1, n2);} void swapByReference (int * a, int * b) {int t; t = * a; * a = * b; * b = t;} OUTPUT ====== n1: 20, n2: 10

Ich hoffe, es hilft…



Antwort 5:

Wenn Daten an Funktionen übergeben werden, können Sie dies entweder in Form eines Aufrufs nach Wert oder eines Aufrufs nach Referenz tun.

Beim Aufruf von Wert geben Sie der Funktion einen Wert, und die Funktion speichert diesen Wert irgendwo lokal und arbeitet daran. Infolgedessen ist die Änderung lokal, dh im Rahmen der Funktion.

Beim Aufruf per Referenz übergeben Sie eine Adresse an die Daten, und die Funktion verwendet die Daten an dieser Adresse. Die Änderungen an den Daten sind also global. Wenn jetzt eine andere Funktion diese Daten verwendet, erhält sie den neuen Wert der Daten.

Ein Problem, mit dem unerfahrene Programmierer möglicherweise konfrontiert sind, besteht darin, dass sie nicht erkennen, dass sie Daten in der Aufruf-nach-Wert-Form übergeben, und dass die Ergebnisse nicht den Erwartungen entsprechen, da die Daten außerhalb des Funktionsumfangs gleich bleiben.

Um Ihnen zu helfen, habe ich einen kleinen C ++ - Code geschrieben, in dem Sie diesen Fehler sehen können.

  1. #umfassen Verwenden des Namespace std; void erhöhen (int a) {a ++; return} int main () {int start = 0; erhöhen (Start); cout << start << endl; return 0;}


Antwort 6:

In C gibt es keinen Aufruf durch Referenz. Sie können das Argument nur durch Aufruf durch Wert übergeben.

Beim Aufruf nach Wert senden Sie den Wert des Arguments, und innerhalb der Funktion wird eine lokale Variable erstellt, die diesen Wert enthält. Änderungen, die an dieser lokalen Variablen vorgenommen werden, werden also nicht in der aufrufenden Funktion berücksichtigt.

Sie können die Illusion eines Anrufs durch Referenz in C durch Zeiger erzeugen. In diesem Fall senden Sie den Speicherort des Arguments über einen Zeiger (der als Wert übergeben wird), und innerhalb der Funktion wird eine lokale Variable erstellt, die diese Adresse enthält. Da alle in der Funktion vorgenommenen Manipulationen an dieser Speicheradresse vorgenommen werden, werden alle vorgenommenen Änderungen in der aufrufenden Funktion wiedergegeben.



Antwort 7:

Eine Variable ist eine Stelle im Speicher, die einen Wert enthält. Betrachten Sie die folgende Variable "x", die eine Ganzzahl mit dem Wert 5 ist:

Immer wenn Sie den Namen x im richtigen Bereich verwenden, verknüpft der PC diesen mit der Adresse im Speicher und den Typinformationen. Wenn Sie nach dem Wert x fragen, kann der PC Ihnen die Informationen bei 0x01 geben und als ganzzahlige Daten interpretieren.

Nehmen wir nun an, Sie übergeben x

nach Wert

in einem Funktionsparameter berücksichtigen

  1. .... int y = Quadrat (x); ... int Quadrat (int toBeSquared) {toBeSquared = toBeSquared * toBeSquared; return toBeSquared; }}

Folgendes passiert, wenn x an die Square-Funktion übergeben wird

nach Wert

.

Eine weitere Variable wird erstellt

an einer anderen Adresse

Dies ist so lange vorhanden, wie die Funktion ausgeführt wird, die denselben Wert und Typ wie die übergebene Variable enthält.

Innerhalb der Funktion toBeSquared gibt es also eine andere Variable:

Nachdem diese Funktion zurückgekehrt ist, bleibt der Wert in x 5 und der Wert 25 wird fünf zugewiesen. Die Tatsache, dass der Wert von toBeSquared geändert wurde, wird nicht an x ​​zurückgegeben, da es sich um eine andere Variable handelt (wenn auch mit anfänglich demselben Wert), die an einer anderen Stelle im Speicher gespeichert ist.

Betrachten Sie nun die Übergabe von x als Referenz:

  1. .... int y = Quadrat (x); ... int Quadrat (int & toBeSquared) {toBeSquared = toBeSquared * toBeSquared; return toBeSquared; }}

In diesem Fall wird es geben

Kein Kopieren des Wertes 5 in eine andere Variable

. Stattdessen erhält die Variable 5 einen Alias: einen anderen Namen, mit dem die aufgerufene Funktion auf den zugreifen kann

Original

Variable X am Speicherplatz 0x01:

Jetzt kann die Funktion über ihren temporären Alias ​​auf x zugreifen

toBeSquared

. Nachdem die Funktion zurückgekehrt ist, wird x mit 25 bewertet, ebenso wie y. Die Funktion wurde überschrieben

toBeSquared

das bezog sich auf den gleichen Speicher wie x.