Podprogramy 1 W Adzie mamy dwa rodzaje podprogramów (subprograms, subroutines): funkcje (functions) i procedury (procedures) 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; 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: Pierwszą część nazywamy deklaracją podprogramu (subprogram declaration) i ta część mówi jak używać podprogramu, Drugą część nazywamy treścią podprogramu (subprogram body) 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 Projektowanie podprogramów Określenie tego co robi podprogram i jak należy go wywołać nazywamy interfejsem podprogramu. Definicja Interfejsem podprogramu (subprogram interface) nazywamy formalne określenie celu działania podprogramu i mechanizmu komunikowania się z podprogramem Definicja Ukrywaniem informacji (information hiding) nazywamy ukrywanie szczegółów implementacyjnych modułu programowego. Uwaga. Modułem programowym (program module) nazywamy tu procedurę, funkcję, albo podprogram główny.
Podprogramy 7 Projektowanie podprogramu powinno być podzielone na dwie części: Projektowanie interfejsu, 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: Wartości, które procedura otrzymuje z podprogramu wywołującego, Wartości, które procedura oblicza i przekazuje do podprogramu wywołującego, 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. 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 Parametrem formalnym (formal parameter) nazywamy zmienną deklarowaną w nagłówku podprogramu. Definicja Parametrem aktualnym (actual parameter) 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 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 jego wykorzystania. Parametr formalny in jest ostatecznie stałą w podprogramie – podprogram nie może zmienić jego 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 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 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 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 Deklaracje typów określanych przez programistę, Deklaracje stałych, Konkretyzacja pakietów ogólnych, Treści procedur i funkcji, 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. Związanie parametrów aktualnych z parametrami formalnymi Definicja Związaniem nazywanym (przez nazwy) (named association) 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 Związaniem pozycyjnym (position association) 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. Zagnieżdżanie podprogramów Definicja Obszarem deklaracji jest deklaracja podprogramu razem z jego treścią. Definicja 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 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 Identyfikatory takie nazywamy homografami. Mimo że nazwy są takie same, to związane są z różnymi obszarami pamięci.
Podprogramy 24 Reguły zasięgu Reguły zgodnie z którymi można używać identyfikatora nazywamy regułami zasięgu identyfikatorów. Zasięg identyfikatora nie obejmuje zagnieżdżonego obszaru deklaracji, w którym umieszczono deklarację odpowiedniego homografu. 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 Podprogramy_001_Kwalifikacja_Procedur Efekty uboczne Definicja Wpływ jednego modułu programowego na inny moduł wywołany poza jawnie określonym interfejsem modułów nazywamy efektem ubocznym (side effect). 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. Jeżeli moduł programowy ma obliczyć więcej niż jedną wartość, albo zmienić wartości parametrów aktualnych nie stosuj funkcji, Jeżeli moduł programowy ma wykonać operację We-Wy, nie stosuj funkcji,
Podprogramy 27 Jeżeli moduł oblicza jedną wartość typu logicznego, stosuj funkcję, Jeżeli moduł programowy oblicza jedną wartość, którą zamierzamy wykorzystać jako argument wyrażenia, stosuj funkcję, 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. Jeżeli obydwa rodzaje podprogramów są równie dobre, wybierz ten rodzaj, który zapewnia Ci większą wygodę przy wywołaniu.
Zadania. Literatura podstawowa APP_Zadania_06_Podprogramy.pdf Literatura podstawowa Morawski, M., Zajączkowski, A. M. (2003). Wstęp do programowania w języku Ada’95. Rozdział 6.