Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 7: Procedury i funkcje © Jan Kaczmarek
Procedury i funkcje W bardziej rozbudowanych programach często fragmenty wykonywanych obliczeń powtarzają się, np. kilkukrotnie trzeba wyznaczyć mniejszą spośród dwóch danych liczb, policzyć sumę pewnej ilości liczb, wyznaczać wiele razy średnią arytmetyczną, rysować tę samą figurę geometryczną itp. Powstaje pytanie, czy można opracować (zaprogramować) jeden raz algorytm wykonywania pewnej czynności (algorytm jest przecież pewnym uniwersalnym przepisem działań dla wielu zestawów danych), a następnie wielokrotnie go wykorzystywać dla rożnych zestawów danych? Odpowiedź na powyższe pytanie jest twierdząca. Aby wielokrotnie wykorzystać pewien algorytm w naszym programie (w przyszłości okaże się, że także w innych naszych programach), należy zaprogramować go w postaci procedury lub funkcji.
Aby zaprogramować algorytm w postaci procedury, musimy podać jej definicję, która ma następującą strukturę: procedure nazwa-procedury (lista-parametrów-formalnych); {lokalne definicje i deklaracje} begin {treść procedury} end; nazwa-procedury to identyfikator, który pozwala identyfikować dany algorytm, lista-parametrów-formalnych zawiera identyfikatory i opisy typów formalnych wzorców obiektów, za pomocą których będziemy przekazywać dane do obliczeń w algorytmie i zwracane będą wyniki jego działania (może jej nie być, gdy procedura nie ma parametrów !) część {lokalne definicje i deklaracje} zawiera informacje o obiektach (modułach, stałych, typach, zmiennych) wykorzystywanych tylko i wyłącznie na potrzeby danego algorytmu część {treść procedury} zawiera instrukcje składające się na formalny zapis algorytmu, które działają na parametrach formalnych i lokalnych obiektach Zwróćmy uwagę na duże podobieństwo do struktury programu.
Przykład 1: procedure wieksza (a, b : integer; var max : integer); {procedura znajdowania większej z dwóch podanych liczb} begin if a>b then max := a else max := b; end; a, b – parametry formalne, za pomocą których przekazujemy dane do obliczeń max – parametr formalny, za pomocą którego zwracany będzie wynik obliczeń Nie określamy tu żadnych obiektów, które będą wykorzystywane tylko i wyłącznie na potrzeby tego algorytmu.
Przykład 2: procedure iloczyn (n : integer; var il : integer); {procedura znajdowania iloczynu il = 1*2*3*…*n dla danego n} var i : integer; begin il := 1; for i:=1 to n do il := il*i; end; n – parametr formalny, za pomocą którego przekazujemy dane do obliczeń il – parametr formalny, za pomocą którego zwracany będzie wynik obliczeń i – zmienna całkowita wykorzystywana tylko i wyłącznie na potrzeby tego algorytmu
Procedury (i funkcje) wykorzystywane w programie muszą zostać zdefiniowane w części {definicje i deklaracje} programu po deklaracjach modułów, stałych, typów i zmiennych. Generalnie w Pascalu obowiązuje zasada mówiąca, że każdy obiekt (moduł, stała, typ, zmienna, procedura lub funkcja), który jest używany w programie, musi być najpierw zdefiniowany lub zadeklarowany (chyba, że jest to obiekt predefiniowany, czyli znany już kompilatorowi). Obiekty definiowane i deklarowane w części {definicje i deklaracje} programu (w szczególności zmienne) nazywać będziemy obiektami globalnymi. Obiekty definiowane i deklarowane w częściach {lokalne definicje i deklaracje} definicji procedur (i funkcji) nazywać będziemy obiektami lokalnymi. Definicje i deklaracje wyznaczają tzw. zasięg identyfikatora identyfikującego obiekt. Zasięg ten może być globalny lub lokalny. Obiekty lokalne mają zdolność przysłaniania obiektów globalnych w obrębie swojego zasięgu, jeśli posiadają ten sam identyfikator.
program przyklad; {$APPTYPE CONSOLE} uses SysUtils; var i : integer; x, y : real; procedure PPP (z : integer); var x : integer; begin x := z; ……… end; begin ……… x := y; PPP(i); writeln(x) ……… end. obowiązuje lokalna deklaracja, zmienna x jest typu integer zmienna y nie jest przysłonięta, co oznacza, że jest typu real obowiązuje globalna deklaracja, zmienna x jest typu real zmienna y jest typu real obowiązuje globalna deklaracja, zmienna x jest typu real zmienna y jest typu real
Gdy w wyniku działań procedury otrzymujemy jeden wynik, wygodnie jest zaprogramować algorytm obliczania tej wartości w postaci funkcji. Musimy podać jej definicję, która ma następującą strukturę: function nazwa-funkcji (lista-parametrów-formalnych) : typ-wyniku; {lokalne definicje i deklaracje} begin {treść funkcji} end; nazwa-funkcji to identyfikator, który pozwala identyfikować daną funkcję i przez ten identyfikator zwracany będzie wynik działania funkcji lista-parametrów-formalnych zawiera identyfikatory i opisy typów formalnych wzorców obiektów, za pomocą których będziemy przekazywać dane do obliczeń w algorytmie (może jej nie być, gdy funkcja nie ma parametrów !) typ-wyniku określa typ zwracanego przez funkcję wyniku część {lokalne definicje i deklaracje} zawiera informacje o obiektach wykorzystywanych tylko i wyłącznie na potrzeby danego algorytmu część {treść funkcji} zawiera instrukcje składające się na formalny zapis algorytmu, które działają na parametrach formalnych i lokalnych obiektach
W części {treść funkcji} przynajmniej raz musi wystąpić instrukcja przypisania postaci: nazwa-funkcji := wyrażenie; określająca, jaką wartość zwróci funkcja jako wynik swego działania. Przykład 1: function max (a, b : integer) : integer; {funkcja zwracająca jako wynik większą z dwóch podanych liczb} begin if a>b then max := a else max := b; end; a, b – parametry formalne, za pomocą których przekazujemy dane do obliczeń max – nazwa funkcji, za pomocą której zwracany jest wynik obliczeń
Przykład 2: function silnia (n : integer) : integer; {funkcja zwracająca jako wynik iloczyn 1*2*3*…*n dla danego n} var i, il : integer; begin il := 1; for i:=1 to n do il := il*i; silnia := il end; n – parametr formalny, za pomocą którego przekazujemy dane do obliczeń silnia – nazwa funkcji, za pomocą której zwracany jest wynik obliczeń i, il – zmienne całkowite wykorzystywane tylko i wyłącznie na potrzeby tego algorytmu