Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Call-by-reference


01Detlef - Mo 30.09.02 12:40
Titel: Call-by-reference
hallo,
kann mir einer den unterscheid zwischen Call-by-value und call-by-reference erklären?

ich sehe da keinen unterschied:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
..
function malZwei(a:integer):Integer;
begin
   a:=7;
   malZwei:=a*2;
end;
procedure button1....
var b:integer
begin
   b:=malZwei(6);
   label1.caption:=inttostr(b);
end;

es wird immer 14 herauskommen!!


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function malZwei(var a:Integer):Integer;
begin
   a:=7
   malZwei:=a*2;
end;
procedurebutton1...
var a,b Integer;
begin
   b:=2;
   a:=malZwei(b);
end;


Wird auch 14 herauskommen, da b nur ein Synonym für a ist!

Kann mir einer die Unterscheide erklären?

Danke Detlef


Tino - Mo 30.09.02 13:18

Das bei beiden Methoden 14 als Ergebnis geliefert wird ist doch klar. Denn schließlich wird der übergebene Parameter überschrieben:

Quelltext
1:
  a:=7;                    


Gruß
TINO


01Detlef - Mo 30.09.02 13:26

ja,
aber wo ist dann der unterschied zwischen den beiden Typen?

Detlef


Ex0rzist - Mo 30.09.02 13:48

Worauf willst du hinaus? :?:
Ich verstehe nicht ganz, was du meinst. :nixweiss:
Die beiden Varianten sind doch sehr ähnlich.
In der ersten Variante wird der Parameter direkt übergeben (6). Bei der zweiten wird ein b übergeben, was vorher als 2 deklariert wurde.

Was vor dem ":=" steht, ist in diesem Fall ja egal.


Klabautermann - Mo 30.09.02 14:14

Hallo,

der Unerschied ist recht einfach.

Mal angenommen dur rufst deine Funktion so auf:

Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure Test;
  VAR
     Wert, Ergebnis : Integer;
begin 
  Wert := 5;
  Ergebnis := malZwei(Wert);
end;


Dann hat im falle der ersten Variante (ohne Var):
Wert = 5
Ergebnis = 14

Im valle von Variante 2 (mit Var)
Wert = 7
Ergebnis = 14

Wenn du also einen Var Parameter verwendest, dann werden alle änderungen die du an dem Parameter vornimmst auch an der Ausgangsvariable vorgenommen.
Folgerichtig währe in dem Falle ein Funktionsafruf aller

Quelltext
1:
Ergebnis := malZwei(6);                    

nicht gültig, da du keine Variable im Aufruf hast.

Gruß
Klabautermann


Delete - Mo 30.09.02 14:16

Call-by-value übergibt eien Kopier der Variablen an die Funktion / Prozedure. Call-by-refernce über gibt die Speicheradresse der Variable.

Folge: Mit call-by-value kann ich innerhalb der Prozedur / Funktion mit der Variable anstellen, was ich will, es wirkt sich nicht auf den Wert der Variablen außerhalb der Prozedur / Funktion aus. Im Gegenteil zu call-by-reference, da hier ja direkt der Inhalt der Speicheradresse verändert wird.


Motzi - Mo 30.09.02 14:16

Ich glaube er meint die Parameter:

function malZwei(a:integer):Integer;
function malZwei(var a:Integer):Integer;

Der Unterschied ist folgender:
bei der ersten Version wird eine Kopie des übergebenen Parameters am Stack abgelegt dh die Funktion hat ihre eigene persönliche Kopie des Parameters und kann damit anstellen was sie will ohne das die Variable (sofern es eine Variable war) die als Parameter übergeben wurde davon beeinflusst wird.

Bei der zweiten Version wird nur eine Referenz auf die Variable die als Parameter übergeben wurde auf dem Stack abgelegt. Dh. jede Änderung an der Parameter-Variable wirkt sich direkt auf die als Parameter übergebene Variable aus

probier mal folgendes:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function malZwei(a:integer):Integer;
begin
   a:=7;
   malZwei:=a*2;
end;

procedure button1....
var
  a, b: Integer
begin
  a := 6;
  b := malZwei(a);
  label1.caption := Inttostr(b);
  ShowMessage(IntToStr(a));
end;


und dann das:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function malZwei(var a:Integer):Integer;
begin
   a:=7
   malZwei:=a*2;
end;

procedurebutton1...
var
  a,b: Integer;
begin
  a := 6;
  b := malZwei(a);
  label1.Caption := IntToStr(b);
  ShowMessage(IntToStr(a));
end;


Du wirst sehen, der Wert der Variable ist unterschiedlich!


01Detlef - Mo 30.09.02 14:54

also, ich meinte das so, wie Klabautermann das beschrieben hat!

also ist der unterschied darin, das der Wert eine andere Zahl hat, aber das Ergebnis gleich ist?

Call by reference ändern die globale Variable, also haben auswirkungen auf die variable und somit auf die darauffolgenden Unterprogramme, solang sie mit der Variable arbeiten!

Call by Value ändert die globale VAriable nicht, nur innerhalb der Routine!

hab ich das so richtig verstanden??

Wenn man die globale Variable ändert, wird das nicht sehr unübersichtlich bei längeren Programmen?

Danke Detlef