Object Pascal/Procedury i funkcje
Do czego służą procedury i funkcje?
[edytuj]Procedury służą do zamknięcia pewnych standardowych, wielokrotnie wykonywanych ciągów czynności w pewną całość "widzianą" przez program pod konkretną nazwą i operującą w danej chwili na konkretnych argumentach. Funkcja jest podobna do procedury, różni się od niej tym, że pod swoją nazwą zwraca pewną wartość. Zastosowanie procedur i funkcji pozwala na optymalizację wykorzystania pamięci. Pamięć jest przydzielana dynamicznie podczas wywołania.
Procedury
[edytuj]Deklaracja procedury
[edytuj]procedure nazwa [(lista_parametrów_formalnych)]; {deklaracje lokalnych stałych, zmiennych i typów} begin {część operacyjna} end;
Deklaracja procedury powinna znajdować się przed częścią operacyjną programu, czyli przed głównym słowem begin,a po deklaracji zmiennych, z których ona korzysta. Nie jest konieczne umieszczanie po deklaracji zmiennych, ale stosowanie się do tej zasady pozwala na zastosowanie porządku w zapisie programu.
Jeżeli chcemy aby procedura była zadeklarowana za miejscem jej pierwszego wywołania, należy użyć słowa kluczowego forward:
procedure nazwa [(lista-parametrów-formalnych)]; forward;
Wewnątrz procedury można deklarować zmienne lokalne, czyli zmienne wewnętrzne, obowiązujące tylko w tej procedurze, w której zostały zadeklarowane. Zmienne lokalne mogą mieć takie same identyfikatory jak zmienne globalne (zmienne zewnętrzne, obowiązujące w całym programie), wtedy znaczenie zmiennej globalnej zostanie przysłonięte znaczeniem zmiennej lokalnej. Wewnątrz deklaracji można używać zmiennych globalnych (nie przysłaniając ich), pokazane na przykładzie, jednak należy pamiętać o częstych błędach przy drobnej nieuwadze.
Przykład deklaracji
[edytuj]procedure srednia; var i:integer; s:real; begin s:=0.0; for i:=1 to ilosc do //ilosc - zmienna zewnętrzna s:=s+dane[i]; wynik:=s/ilosc end;
Wywołanie procedury
[edytuj]nazwa_procedury [(lista_parametrów_aktualnych)];
Wywołanie procedury polega na podaniu w zapisie programu jej nazwy, a także listy parametrów aktualnych, czyli zawierających ich bieżące wartości. Lista ta nie istnieje, gdy nie określimy żadnych parametrów formalnych przy deklarowaniu procedury.
Podstawowe procedury
[edytuj]Procedury przerywające wykonanie instrukcji iteracyjnych
[edytuj]BREAK
[edytuj]Procedura powoduje natychmiastowe zakończenie wykonywania pętli, wewnątrz której jest wywołana.
Przykład:
var w,x,i,j:integer; begin w:=1 for i:=3 to 3 do for j:=1 to 8 do begin readln(x); if x=0 then break else w:=w*x end; writeln('iloczyn=',w); end.
CONTINUE
[edytuj]Procedura powoduje natychmiastowe przejście do kolejnej iteracji pętli, wewnątrz której jest wywołana.
Przykład:
var w,x,i,j:integer; begin w:=1 for i:=1 to 3 do for j:=3 to 5 do begin readln(x); if x=0 then continue else w:=w*x end; writeln('iloczyn=',w); end.
Procedury powodujące przerwanie wykonywanego programu
[edytuj]EXIT
[edytuj]Procedura Exit wywołana wewnątrz procedury lub funkcji powoduje jej przerwanie i powrót do miejsca wywołania, a wywołana w części wykonawczej programu powoduje jego zakończenie.
HALT
[edytuj]Procedura Halt, której wywołanie ma postać:
Halt (kod_wyjścia);
lub
Halt
co jest równoważne wywołaniu Halt(0) (0 – zakończenie bez błędu, kod_wyjścia jest wyrażeniem typu integer) powoduje przerwanie programu i powrót do systemu.
RUNERROR
[edytuj]Procedura RunError lub RunError_(kod_błędu) powoduje przerwanie programu i wygenerowanie błędu jego wykonania o podanym kodzie (kod_błędu jest argumentem typu Byte, gdy brak tego argumentu, to przyjmuje się wartość 0).
Funkcje
[edytuj]Funkcja jest rodzajem procedury, która po wywołaniu zwraca obliczoną przez siebie wartość pod swoją nazwą.
Deklaracja funkcji
[edytuj]function nazwa [(lista-parametrów-formalnych)] : typ_wyniku; {deklaracje lokalnych stałych, zmiennych i typów} begin {część operacyjna} end;
Deklaracja funkcji powinna znajdować się przed częścią operacyjną programu, czyli przed głównym słowem begin,a po deklaracji zmiennych, z których ona korzysta. Nie jest konieczne umieszczanie po deklaracji zmiennych, ale stosowanie się do tej zasady pozwala na zastosowanie porządku w zapisie programu.
Jeżeli chcemy aby funkcja była zadeklarowana za miejscem jej pierwszego wywołania, należy użyć słowa kluczowego forward:
function nazwa [(lista-parametrów-formalnych)]:typ_wyniku; forward;
Wewnątrz funkcji można deklarować zmienne lokalne tak samo jak to jest przy procedurach.
W części operacyjnej funkcji przynajmniej raz powinna wystąpić instrukcja przypisania postaci:
nazwa:=wyrażenie;
lub
RESULT:=wyrażenie;
Przykład deklaracji
[edytuj]function srednia: integer; var i:integer; s:real; begin s:=0.0; for i:=1 to ilosc do //ilosc - zmienna zewnętrzna s:=s+dane[i]; srednia:=s/ilosc end;
Wywołanie funkcji
[edytuj]Wywołanie funkcji ma miejsce w wyrażeniu po prawej stronie instrukcji przypisania lub w instrukcji wywołania procedury:
zmienna:=nazwa [(lista-parametrów-aktualnych)];
Przykład wywołania
[edytuj]Srednia_ocen:=srednia; writeln(Srednia_ocen);
Pozostałe informacje
[edytuj]Procedury i funkcje działające na argumentach typu porządkowego
[edytuj]- Dec(x), Dec(x,n) - bezpośrednio poprzedni, dekrementacja zmiennej x
- Inc(x), Inc(x,n) - bezpośrednio następny, inkrementacja zmiennej x,
- Odd(x) - badanie parzystości, przyjmuje wartość TRUE, gdy x nieparzyste
- Pred(x) - poprzednik elementu x
- Succ(x) - następnik elementu x
Przeciążanie procedur i funkcji
[edytuj]Przeciążanie procedur i funkcji występuje wtedy, gdy:
- dwie procedury lub funkcje mogą mieć ten sam identyfikator
- musi być użyta dyrektywa języka overload
- listy parametrów formalnych muszą się różnić ilością lub typem
Przykłady:
[edytuj]Program iloczyny; var a,b:real function iloczyn (a,b: integer): integer;overload; begin result:=a*b; end; function iloczyn (a,b:real): real;overload; begin result:=a*b; end; begin c:=iloczyn(5,6) //zostanie wywołana pierwsza funkcja c:=iloczyn(5,5.6) //zostanie wywołana druga funkcja. end.
Rekurencja
[edytuj]Rekurencja jest to zdolność procedury lub funkcji do wywoływania samej siebie. Przykład:
function Potega(a:real; n:integer): real;
begin
if (n=0) and (a<>0) Result := 1;
if (n=1) Result := a;
if (n>1) Result := a * Potega(a, n-1);
if (n<0) Result := 1 / Potega(a, -n);
end;
Skorzystaliśmy tutaj z definicji rekurencyjnej potęgi:
Oczywiście do obliczania potęg o większym od zera wykładniku prostsza jest definicja iteracyjna:
Rekurencja pochłania więcej pamięci RAM, a często i procesora, więc działa wolniej od pętli. Dlatego należy ją stosować tylko wtedy, gdy jej użycie ma sens, np. przy operacjach na katalogach i ich podkatalogach.