 
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