Parametry przekazywane przez wartość i przez zmienną


Dwa najpowszechniej stosowane mechanizmy przekazywania parametrów zilustrowano przykładami.

function DoubleByValue(X: Integer): Integer;     
// X jest przekazywane przez wartość
begin
  X := X * 2;
  Result := X;
end;
function DoubleByRef(var X: Integer): Integer;   
// X jest przekazywane przez zmienną
begin
  X := X * 2;
  Result := X;
end;

Obie funkcje zwracają tę samą wartość, ale tylko druga DoubleByRef może zmienić wartość parametru przekazywanego do niej. Przykłąd zastosowania:

var I, J, V, W: Integer;
begin
  I := 4;
  V := 4;
  J := DoubleByValue(I);   // J = 8, I = 4
  W := DoubleByRef(V);     // W = 8, V = 8
end;

Po wykonaniu tego kodu, zmienna I, która została przekazana jako parametr (przekazywany przez wartość) do funkcji DoubleByValue ma niezmienioną wartość, pomimo instrukcji podstawienia ( X := X * 2;) zamieszczonej wewnątrz funkcji. Tymczasem zmienna V, która została przekazana jako parametr (przekazywany przez zmienną) do DoubleByRef, po wykonaniu kodu ma zmienioną wartość.

Parametry przekazywane przez wartość funkcjonują wewnątrz funkcji/procedury jak zwykłe zmienne lokalne o wartościach zainicjowanych podczas wywołania. Podczas przekazywania parametru przez wartość program tworzy jego kopię; wszelkie zmiany wykonywane na parametrze wewnątrz funkcji/procedury są wykonywane na tej właśnie kopii i nie mają wpływu na wartość oryginalnej zmiennej użytej w wywołaniu, i są tracone kiedy wykonanie procedury/funkcji dobiegnie końca.

Parametr przekazywany przez zmienną działa jak wskaźnik do oryginalnej zmiennej. Zmiany dokonane na parametrze pozostają w mocy po zakończeniu wykonania procedury/funkcji; jedynie nazwa parametru jest tracona, ponieważ zakres jej ważności ogranicza się do wnętrza funkcji/procedury.

Nawet jeśli ta sama zmienna jest przekazywana (przez zmienną) jako kilka parametrów, nie wykonywane są żadne kopie. Ilustruje to przykład:

procedure AddOne(var X, Y: Integer);
begin
  X := X + 1;
  Y := Y + 1;
end;

...

var I: Integer;
begin
  I := 1;
  AddOne(I, I);
end;

Po wykonaniu tego kodu I ma wartość 3.

Uwaga! Jeśli deklaracja specyfikuje parametr przekazywany przez zmienną, podczas wywołania trzeba w tym miejscu listy parametrów aktualnych umieszczać podstawialne wyrażenie tj., zmienną, stałą zdefiniowanego typu (przy dyrektywie {$J+}), zmienną wskazywaną, pole rekordu, lub zmienną indeksowaną.

Wywołanie zdefiniowanej wcześniej funkcji w sposób:

 DoubleByRef(7); //ŹLE!

powoduje bład, podczas gdy wywołanie:

 DoubleByValue(7); //DOBRZE!

jest poprawne.