Podprogramy 1
W Adzie mamy dwa rodzaje podprogramów:
funkcje i procedury
1.
Deklaracja i treść funkcji
function_declaration ::=
function_specification;
function_specification ::=
function
designator [parameter_list]
return
subtype_mark
designator ::= function_identifier |
operator_symbol
Podprogramy 2
function_body ::=
function_specification
is
[declarative_part]
begin
sequence_of_statements
end
designator;
2.
Deklaracja i treść procedury
procedure_declaration ::=
procedure_specification;
procedure_specification ::=
procedure
identifier [parameter_list]
Podprogramy 3
parameter_list ::=
(parameter_specification
{; parameter_specification})
parameter_specification ::=
identifier: mode subtype_mark
mode ::=
in
|
out
|
in out
procedure_body ::=
procedure_specification
is
[declarative_part]
begin
sequence_of_statements
end
procedure_identifier;
Podprogramy 4
Słowniczek
designator
– desygnator – miano funkcji,
procedure_declaration
– deklaracja
procedury,
procedure_specification
– definicja
procedury – nagłówek procedury,
parameter_list
– lista parametrów formalnych,
parameter_specification
– definicja
parametru formalnego,
mode
– rodzaj parametru formalnego,
procedure_body
– treść procedury.
Podprogramy 5
Podprogramy definiuje się w dwóch
częściach:
1. Pierwszą część nazywamy deklaracją
podprogramu i ta część mówi jak
używać podprogramu,
2. Drugą część nazywamy treścią
podprogramu i w tej części podana jest
informacja jak działa podprogram
Zarówno deklaracja jak i treść zawierają
nagłówek podprogramu (
subprogram
specification
)
Podprogramy 6
3. Projektowanie podprogramów
Określenie tego co robi podprogram i jak należy go
wywołać nazywamy interfejsem podprogramu.
Definicja 1.
Interfejsem podprogramu
nazywamy formalne określenie celu działania
podprogramu i mechanizmu komunikowania się
z podprogramem
Definicja 2.
Ukrywaniem informacji nazywamy
ukrywanie szczegółów implementacyjnych
modułu programowego.
Uwaga.
Modułem programowym nazywamy tu
procedurę, funkcję, albo podprogram główny.
Podprogramy 7
Projektowanie podprogramu powinno być
podzielone na dwie części:
1. Projektowanie interfejsu,
2. Projektowanie implementacji.
W celu zaprojektowania interfejsu należy
określić funkcje podprogramu i
sposób komunikowania się z
projektowanym podprogramem.
W celu zaprojektowania implementacji
musimy określić algorytm wg którego
podprogram wykonuje swoje funkcje.
Podprogramy 8
Przy projektowaniu interfejsu
zaleca się
sporządzenie listy następujących
elementów:
1. Wartości, które procedura otrzymuje z
podprogramu wywołującego,
2. Wartości, które procedura oblicza i
przekazuje do podprogramu
wywołującego,
3. Wartości, które procedura otrzymuje z
podprogramu wywołującego, zmienia
je i następnie przekazuje do
podprogramu wywołującego.
Podprogramy 9
Jeżeli mamy taką listę, to możemy utworzyć
listę parametrów formalnych, przy czym
parametry pierwszej grupy są rodzaju
in
,
parametry drugiej grupy są rodzaju
out
, a
parametry trzeciej grupy są rodzaju
in out
.
4.
Parametry procedur
Parametry służą do przesyłania informacji do
i z procedury.
procedure
Get (Item :
out
Num;
Width :
in
Field := 0);
Podprogramy 10
Następujące wywołanie:
Ada.Integer_Text_IO.Get (Item =>
Liczba);
powoduje przesłanie wartości z procedury do
zmiennej Liczba.
Podobnie jak zmienne, parametry są
nazwami obszarów pamięci używanymi
do przechowywania danych.
Item jest nazwą innego obszaru pamięci niż
obszar przypisany do Liczba. Po
pomyślnym zakończeniu procedury Get
wartość z Item jest skopiowana do Liczba.
Podprogramy 11
Definicja 3.
Parametrem formalnym nazywamy
zmienną deklarowaną w nagłówku podprogramu.
Definicja 4.
Parametrem aktualnym nazywamy
zmienną, albo wyrażenie związane z nazwą
parametru formalnego przy wywołaniu
podprogramu.
Określenie parametru formalnego musi zawierać
identyfikator i typ danych.
Typ parametru aktualnego musi odpowiadać
typowi parametru formalnego.
Nie można używać zakresów w definicjach
parametrów formalnych.
Podprogramy 12
Rodzaje parametrów
Każda definicja parametru formalnego
obejmuje informację o jego rodzaju.
Mamy trzy rodzaje parametrów:
in
– wejściowy
Wartość parametru aktualnego jest
kopiowana do parametru formalnego
przy wywołaniu procedury. Wartość jest
przekazywana do wnętrza procedury.
Uwaga.
To samo dotyczy funkcji.
Podprogramy 13
out
– wyjściowy
Wartość parametru formalnego jest
kopiowana do parametru aktualnego po
wykonaniu ostatniej instrukcji procedury.
Wartość jest przekazywana na zewnątrz
procedury.
in out
– wejściowo-wyjściowy
Wartość parametru aktualnego jest
kopiowana do parametru formalnego przy
wywołaniu procedury. Po wykonaniu
ostatniej instrukcji procedury wartość
parametru formalnego jest kopiowana do
parametru aktualnego. Dokonywane są dwa
różne transfery danych.
Podprogramy 14
Zalecenia
Należy wybrać rodzaj
in
w przypadku, gdy
wywołanie procedury wymaga przesłania
danych do jej wnętrza.
Używaj rodzaju
out
w celu wyprowadzenia
na zewnątrz wyników działania procedury.
Należy używać rodzaju
in out
, gdy
wywołanie procedury wymaga przesłania
do jej wnętrza danych, które są w niej
modyfikowane i wynik ma być dostępny na
zewnątrz.
Podprogramy 15
Przykład 1.
procedure
Oblicz_Srednia (Pierwszy :
in
Float; Drugi :
in
Float;
Srednia :
out
Float)
is
begin
Srednia := (Pierwszy + Drugi)/2.0;
end
Oblicz_Srednia;
Rodzaj parametru formalnego jaki wybieramy
ma wpływ na sposób wykorzystania.
Parametry formalny
in
jest ostatecznie
stałą w podprogramie – podprogram nie
może zmienić jej wartości.
Podprogramy 16
W przypadku parametru formalnego rodzaju
in
parametr aktualny może być
wyrażeniem. Przed przekazaniem
sterowania do podprogramu wyrażenie jest
obliczane i wynik kopiowany jest do
parametru formalnego.
Przykład 2.
Oblicz_Srednia (Pierwszy =>
0.6*Wynik_Egzaminu,
Drugi => 0.4*Wynik_Cwiczen,
Srednia => Ocena_W_Indeksie);
Podprogramy 17
Parametry aktualne rodzaju
out
i
in out
nie
mogą być wyrażeniami, natomiast muszą być
zmiennymi, do których kopiowane są wyniki
działania procedury.
Parametr rodzaju
out
jest zmienną, do której
powinien zostać podstawiony wynik procedury.
Stosuje się tu instrukcję podstawienia, albo
wywołanie innej procedury.
Nie należy używać parametrów rodzaju
in out
tylko po to, aby ominąć ograniczenia nałożone
na pozostałe rodzaje parametrów.
Dobieraj parametry wyłącznie na podstawie
kierunku przesyłania informacji.
Podprogramy 18
5.
Umiejscowienie podprogramów
Podprogramy mogą znajdować się w osobnych
plikach, w pakietach, albo w naszym programie.
W ostatnim przypadku nie musimy podawać
oddzielnej deklaracji podprogramu. Treść
podprogramu służy również za jej deklarację.
Treść podprogramu umieszczamy w części
deklaracyjnej programu.
Zasada.
Identyfikator musi być zdefiniowany
przed jego użyciem.
Przykład 3.
Musimy zadeklarować typ
wyliczeniowy przed konkretyzacją pakietu do
obsługi wejścia-wyjścia tego typu
wyliczeniowego.
Podprogramy 19
Zalecenie kolejności deklaracji w programie
1. Deklaracje typów określanych przez programistę,
2. Deklaracje stałych,
3. Konkretyzacja pakietów ogólnych,
4. Treści procedur i funkcji,
5. Deklaracje zmiennych.
Zalecenia stylistyczne
Identyfikator procedury powinien być czasownikiem
Oblicz_Srednia (X1, X2, Srednia);
Podprogram powinien zawierać komentarze
wyjaśniające sposób jego wywołania i ewentualnie
źródło lub opis algorytmu wg którego
podprogram realizuje obliczenia.
Podprogramy 20
Komentarz opisujący parametr formalny można
umieścić bezpośrednio po definicji parametru.
6.
Związanie parametrów aktualnych z
parametrami formalnymi
Definicja 5.
Związaniem nazywanym (przez
nazwy) nazywamy związanie parametrów
aktualnych z formalnymi przez jawne podanie
nazw parametrów formalnych przy wywołaniu
podprogramu.
W tym przypadku porządek parametrów nie
musi być taki sam jak na liście parametrów
formalnych w nagłówku podprogramu.
Podprogramy 21
Definicja 6.
Związaniem pozycyjnym nazywamy
związanie parametrów aktualnych z formalnymi
przez ich pozycje na listach parametrów aktualnych i
formalnych.
W tym przypadku na liście parametrów aktualnych
znajdują się tylko ich desygnatory, przy czym ich
kolejność musi być taka sama jak odpowiednich
parametrów formalnych na liście w nagłówku
podprogramu.
Związanie pozycyjne jest w wielu przypadkach
gorsze od związania przez nazwę. Przy stosowaniu
związania pozycyjnego łatwo pomylić porządek
parametrów, a błędy wynikające z tego powodu mogą
być trudne do wykrycia. Poza tym związanie przez
nazwę daje bardziej czytelną formę programu.
Podprogramy 22
Są jednak przypadki kiedy związanie nazywane
wydaje się przesadą - podprogramy
jednoparametrowe.
7.
Zagnieżdżanie podprogramów
Definicja 7.
Obszarem deklaracji jest
deklaracja podprogramu razem z jego treścią.
Definicja 8.
Identyfikatory zadeklarowane
wewnątrz obszaru deklaracji nazywamy
lokalnymi w tym obszarze.
Jeżeli podprogramy są zagnieżdżone, to
dostaniemy zagnieżdżone obszary
deklaracji.
Podprogramy 23
Definicja 9.
Deklaracje występujące w
najbardziej zewnętrznym obszarze deklaracji
nazywamy globalnymi w stosunku do
wewnętrznych obszarów deklaracji.
Można używać tych samych identyfikatorów w
deklaracjach pod warunkiem, że
identyfikatory te występują w różnych
obszarach deklaracji.
Definicja 10.
Identyfikatory takie nazywamy
homografami.
Mimo że nazwy są takie same, to związane są z
różnymi obszarami pamięci.
Podprogramy 24
8.
Reguły zasięgu.
Reguły zgodnie z którymi można używać identyfikatora
nazywamy regułami zasięgu identyfikatorów.
I.
Zasięg identyfikatora nie obejmuje
zagnieżdżonego obszaru deklaracji, w którym
umieszczono deklarację odpowiedniego
homografu.
II. Zasięgiem identyfikatora nazywamy wszystkie
instrukcje występujące po definicji identyfikatora i
znajdujące się w obszarze deklaracji zawierającym
definicję identyfikatora z wyłączeniem wg. reguły
I
Druga reguła nazywana jest czasami priorytetem
identyfikatorów.
Podprogramy 25
Przykład .
Kwalifikacja_Procedur
9.
Efekty uboczne
Definicja 11.
Wpływ jednego modułu
programowego na inny moduł wywołany
poza jawnie określonym interfejsem
modułów nazywamy efektem ubocznym.
Typowym przykładem jest zmiana wartości
zmiennej globalnej wewnątrz podprogramu.
Aby uniknąć trudnych do wykrycia błędów
wywoływanych przez efekty uboczne,
przesyłanie informacji pomiędzy
podprogramem, a podprogramem
wywołującym powinno odbywać się
wyłącznie poprzez interfejs
Podprogramy 26
Jeżeli procedury zmieniają jedynie wartości
zmiennych lokalnych lub parametrów,
efekty uboczne nie powstaną.
Deklarując zmienne po treściach
podprogramów zapewniamy brak dostępu
do tych zmiennych w podprogramach.
Zalecenia kiedy używać funkcji.
1.
Jeżeli moduł programowy ma obliczyć więcej
niż jedną wartość, albo zmienić wartości
parametrów aktualnych nie stosuj funkcji,
2.
Jeżeli moduł programowy ma wykonać
operację We-Wy, nie stosuj funkcji,
Podprogramy 27
3. Jeżeli moduł oblicza jedną wartość typu
logicznego, stosuj funkcję,
4. Jeżeli moduł programowy oblicza jedną
wartość, którą zamierzamy wykorzystać jako
argument wyrażenia, stosuj funkcję,
5. Jeżeli masz wątpliwości, co stosować, stosuj
procedurę. Każdą funkcję można zamienić
na procedurę, przy czym nazwa funkcji staje
się wtedy parametrem rodzaju
out
.
6. Jeżeli obydwa rodzaje podprogramów są
równie dobre, wybierz ten rodzaj, który
zapewnia Ci większą wygodę przy wywołaniu.
Literatura podstawowa
Literatura podstawowa
Morawski, M., Zajączkowski, A. M.
(2003).
Wstęp do programowania w języku
Ada’95.
Rozdział 6.
Użyteczne materiały dydaktyczne:
zskl.zsk.p.lodz.pl/~zajaczko