Te same uwagi, które tyczyły się zasięgu zmiennych w funkcjach, mają też zastosowanie w procedurach. W tym przypadku I i N w procedurze i w bloku głównym to nie to samo i zmiana wartości I w procedurze nie ma wpływu na wartość I w głównej pętli programu. Nie wierzysz? Popraw procedurę tak, by rysowała 2N-1 gwiazdek — otrzymasz trójkąt bardziej równomierny. Zrób to poprzez poprawienie pętli for (w procedurze, a nie w głównym programie) na: for I := 1 to 2*N-1 do
Uruchom program. Bardzo ładny trójkąt, prawda? A teraz usuń w procedurze deklarację zmiennej I (razem ze słowem var). Spowoduje to, że funkcja, nie mając zmiennej lokalnej I „zobaczy” zmienną globalną i zacznie na niej operować. Uruchom program, pamiętając, że zawsze możesz go zatrzymać, wciskając Ctrl+Break. To są właśnie efekty uboczne.
Napisałem, że jeżeli operuje się na parametrach procedury lub funkcji (o ile są zadeklarowane w znany nam sposób), to nie ma to wpływu na wartości zmiennych na zewnątrz programu. Czy to znaczy, że istnieje jeszcze inny sposób deklarowania parametrów? Tak.
Jeżeli deklarowaliśmy parametry tak, jak do tej pory, program przed wykonaniem funkcji tworzył kopie wartości i pozwalał operować właśnie na nich. Nie miało to w żadnym wypadku wpływu na wartości zmiennych w programie. Taki sposób podawania parametrów nazywa się przekazywaniem przez wartość.
Istnieje też drugi sposób: kiedy program nie operuje na kopii, lecz na „żywej” danej. Jest on nazywany przekazywaniem przez zmienną (czasem też przez wskaźnik, przez nazwę lub przez referencję). Definicja parametrów różni się nieznacznie: przed nazwą pojawia się słówko var). Różnica w działaniu jest znaczna. Jeżeli w funkcji lub procedurze zmienimy wartość takiego parametru, odpowiednia zmienna w programie zostanie też zmieniona.
ĆWICZENIE
3.53
Dlaczego nie może być to funkcja? Dlatego, że w wyniku musimy otrzymać dwie wartości. W przypadku funkcji otrzymujemy jedną. Parametry funkcji definiujemy jako przekazywane przez zmienną, dzięki czemu procedura może modyfikować ich wartość.
program cw3_53;
{ Program ilustruje działanie procedury }
{ która zamienia wartości zmiennych. }
{ Katalog r3_10 : 3_53.pas }
var
X, Y : Byte;
procedurę ZamienZmienne (var A, B: Byte);
{ Procedura zamienia wartości zmiennych. } var
Pom : Byte; begin
Pom A; A B; B := Pom; end; {------------------- ZamienZmienne -}