Zmienne I i Wartość, zadeklarowane w bloku deklaracji funkcji mają dość ciekawą własność: są na zewnątrz niewidoczne. Próba wypisania ich wartości w głównym bloku programu skończy się niepowodzeniem przy kompilacji: Error 3: Unknown identifier. Taka zmienna nosi nazwę zmiennej lokalnej funkcji. Z kolei taka, która jest zadeklarowana w głównym bloku deklaracyjnym programu, to zmienna globalna. Istnieje możliwość zadeklarowania w bloku deklaracji funkcji zmiennych o takich samych nazwach, jak zmienne globalne. Ba, mogą być nawet innych typów! Dotknęliśmy tu zagadnienia zasięgu zmiennych, które określa, gdzie zmienna jest widoczna, w zależności od tego, gdzie została zadeklarowana. Zauważmy, że jeżeli w bloku deklaracji funkcji napisalibyśmy kolejną funkcję (tak, to jest możliwe!) — to zmienne I i Wartość byłyby widoczne na zewnątrz. Ale zmiennych lokalnych tej wewnętrznej funkcji na zewnątrz znów nie byłoby widać.
Zmienne globalne (i ich niewidoczność) są bardzo przydatne. Wyobraźmy sobie program korzystający z setek funkcji (są takie...), w których zmienne zadeklarowane w tych funkcjach są widoczne na zewnątrz i oddziałują na siebie. Pisanie programu w takich warunkach byłoby prawdziwym koszmarem. Na przykład w przypadku gdy funkcja Silnia jest już napisana i tylko z niej korzystamy, wartości kolejnych obliczeń silni w pętli (czyli zmienna Wartość) kompletnie nas nie interesują. I dobrze, że takie informacje funkcja trzyma dla siebie.
Jeżeli tylko się da, używaj zmiennych lokalnych, eliminując globalne. Powyższy program działałby tak samo, gdybyś zadeklarował zmienne I i Wartość w głównym bloku deklaracji. Byłoby to jednak złe programowanie. Jako pewną zasadę powinieneś sobie założyć, że pisane przez Ciebie funkcje nie będą zmieniać wartości zmiennych globalnych, a tylko lokalne. Co robiłaby funkcja Silnia, gdyby zmienne I i Wartość zostały zadeklarowane w bloku głównym programu? Liczyłaby silnie? Tak, to też. Ale oprócz tego zmieniałaby wartość globalnych zmiennych. To także musiałbyś napisać w komentarzu funkcji. I pewnie wielokrotnie używając funkcji, szukałbyś w wielu miejscach programu przyczyny, z której zmienna I ma nieoczekiwaną wartość. Taki przypadek nosi nazwę efektu ubocznego funkcji i, o ile nie jest celowy, uważany jest za błąd w programowaniu. To trochę tak jak z blefowaniem w brydżu — da się, tylko po co? Oszukujemy nie tylko parę przeciwników, ale i swoją.
ĆWICZEŃ
3.48
Tym razem użyjemy programu z ćwiczenia 3.42.
program cw3_48;
{ Program znajduje największy wspólny dzielnik A i B }
var
A, B : Integer;
function NWD (A, B : Integer) : Integer;
{ Funkcja oblicza największy wspólny podzielnik liczb } { A i B. }