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.