Podprogram (inaczej funkcja lub procedura) – termin związany z programowaniem proceduralnym. Podprogram to wydzielona część programu wykonująca jakieś operacje, możliwa do wykonania podczas wykonywania programu. Podprogramy stosuje się, aby uprościć program główny i zwiększyć czytelność kodu.

Rodzaje podprogramów

W pewnych językach programowania dzieli się podprogramy na funkcje i procedury:

Przez zwracanie wartości należy rozumieć możliwość użycia wywołania funkcji wewnątrz wyrażenia. Procedury często też zwracają wartości, ale poprzez odpowiednie parametry.

Podział ten występuje w językach takich jak Pascal[1][2] i Ada. W pozostałych językach (m.in. w C[3][4][5] i C++[5]) nie ma już takiego rozróżnienia i funkcją jest każdy podprogram, niezależnie od tego czy zwraca jakieś wartości i czy ma wpływ na program.

Oprócz powyższego podziału, wyróżnić także należy podprogram główny, tj. taki od którego rozpoczyna się wykonywanie skompilowanego programu. W językach programowania zastosowano zasadniczo kilka różnych rozwiązań. Albo zdefiniowana jest w składni odrębna jednostka (np. program w Pascalu[1][2]), albo stosuje się specjalną frazę, dyrektywę języka, informującą aby program łączący dany podprogram wybrał jako podprogram główny (np. OPTIONS(MAIN) w języku PL/1[6][7]). W języku C[3][4][5] i pokrewnych definiuje się zwykłą funkcję lecz o specjalnym identyfikatorze main.

Podprogramy wewnętrzne

Różne języki programowania umożliwiają także definiowanie podprogramów wewnętrznych, tzn. podprogramu w innym podprogramie nadrzędnym. Do takich języków należą między innymi Pascal[1][2], PL/1[6][7] i inne. Nie ma takich możliwości np. w języku C[3][4][5].

  procedure z;
    procedure w1;
    begin
      ...
    end;
    procedure w2;
    begin
      ...
    end;
  begin
    ...
    w1;
    ...
    w2;
    ...
  end;

Terminologia dotycząca podprogramów

Twórcy języków programowania stosują różne terminologie i oznaczenia podprogramów:

Identyfikacja podprogramu

Podprogram może być identyfikowany:

Współprogramy

Współprogramy to procedury wykonywane w taki sposób, że sterowanie może zostać przekazywane pomiędzy nimi wielokrotnie, przy czym wywołanie danego współprogramu powoduje wykonywanie instrukcji od miejsca ostatniego przerwania wykonania (ostatniego punktu wyjścia), a nie od początku. Współprogramy często występują parami i stanowią dwa „równorzędne” podprogramy.

Rodziny podprogramów

Istnieją języki programowania, w których można definiować całą rodzinę podprogramów z jednakową nazwą dla wywołania różnych podprogramów. Do takich języków należą PL/1[6][7] i Ada. Nowsze języki umożliwiają zastosowanie takiego mechanizmu poprzez dopuszczenie przeciążenia nazw.

Przykład w PL/1[6][7]:

 DCL A GENERIC (PR1 WHEN(FLOAT),
                PR2 WHEN(CHAR),
                PR3 WHEN(FLOAT, CHAR),
                PR4 WHEN(LABEL));

W powyższym przykładzie wywołanie procedury A spowoduje w rzeczywistości wywołanie jednej z procedur PR1 .. PR4 w zależności od argumentów wywołania procedury A.

Metody wywołania podprogramu

Wartościową cechą podprogramu jest możliwość wielokrotnego jego wywołania. Wywołanie podprogramu może być:

oczywiście taka forma wywołania dotyczy tylko podprogramów mających cechy funkcji, tzn. zwracających wartość,

Konkretne implementacje języków często dopuszczają wywołanie funkcji w postaci proceduralnej, tzn. poza wyrażeniami. W tym przypadku zwracana przez podprogram wartość jest ignorowana – np. jest tak w Borland Pascalu[2].

Komunikacja podprogramu z otoczeniem

Podprogram jako samodzielna, wydzielona część algorytmu, zazwyczaj (z wyjątkiem prostych operacji, np. czyszczenie ekranu) musi komunikować się z otoczeniem. Taką komunikację realizuje się za pomocą:

Podprogramy w językach programowania

Podprogram w asemblerze

W asemblerze podprogram to wydzielona część kodu, do którego przy wywołaniu wykonuje się skok z odłożeniem adresu powrotu na stos, ewentualnie skok bezwarunkowy, a argumenty wywołania są albo odkładane na stos albo umieszczane bezpośrednio w rejestrach. Wartość wynikowa zwracana jest najczęściej w wyznaczonym rejestrze procesora – np. eax dla procesorów zgodnych z architekturą i386.

(składnia intelowska)

 call podprogram   ; wywołanie podprogramu
 ; ...
 podprogram:       ; instrukcje podprogramu
   mov eax, 10h
   mov ebx, 34h
   int 21h
 ret               ; powrót funkcji

Podprogram w języku BASIC

W języku BASIC (wersje wczesne na komputery 8-bitowe) podprogramem jest ciąg instrukcji rozpoczynający się od wiersza o określonym numerze i zakończony instrukcją RETURN. Wywołanie podprogramu ma formę instrukcji skoku do określonego wiersza. Innym rodzajem podprogramu w Basicu jest definicja funkcji w formie wyłącznie prostego wyrażenia zawartego w jednej linii programu. W późniejszych wersjach Basicu wprowadzono definiowanie parametryzowanych podprogramów (SUB).

  10 DEF SUM(X,Y)=X+Y
  20 GOSUB 50
  30 PRINT "WYNIK: ", A
  40 END
  50 A=SUM(1,2)
  60 RETURN

Podprogram w języku C

Podprogram w języku C[3][4][5]:

 <typ> funkcja( [ <lista-parametrow-formalnych> ] )
 {
    // instrukcje do wykonania (ciało funkcji)
    return (/* wyrażenie */);
 }

 /* Deklaracja procedury w jęz. C */
 void funkcja( [ <lista-parametrow-formalnych> ] )
 {
    // instrukcje do wykonania (ciało funkcji)
 }

Podprogram w języku C#

Podprogram w języku C#:

class klasa
{
 [public/protected/private/internal] [static/virtual/override] [unsafe] <typ> metoda( parametry )
 {
    //ciało metody
    return /* wyrażenie */;
 }

//metoda zwracająca 'nic' [void] , bezparametrowa
 [public/protected/private/internal] [static/virtual/override] [unsafe] void metoda()
 {
    //ciało metody
 }
}

Podprogram w języku Clipper

Podprogram w języku Clipper[11]:

 [STATIC] FUNCTION identyfikator([parametry])
   [deklaracje lokalne]
   instrukcje
 RETURN wyrażenie
 [STATIC] PROCEDURE identyfikator([parametry])
   [deklaracje lokalne]
   instrukcje
 RETURN
 * blok kodu'
 * który traktowany jest także jak typ danej
 {|[lista_parametrów]|wyrażenie_1[, wyrażenie_2[, ... [,wyrażenie_n]]]}

Podprogram w języku Comal

Podprogram w języku Comal[8]:

xx PROC nazwa(parametry)
    instrukcje
yy ENDPROC nazwa

gdzie xx i yy to numery wierszy.

Wywołanie:

zz EXEC nazwa(argumenty)

Podprogram w języku Forth

Również charakterystyczna składnia języka Forth wyróżnia postać podprogramu w tym języku na tle innych języków programowania. W języku Forth definiujemy słowa. Słowo może być podprogramem do którego argumenty przekazywane są za pośrednictwem stosu (ale słowo może też być zmienną, stałą, nazwą słownika itd.). W poniższym przykładzie definiowany jest trywialny przykład podprogramu POW_3 w języku Forth, który powoduje podniesienie do 3 potęgi argumentu. Jak widać argument (liczba 5) podawany jest przed wywołaniem podprogramu – umieszczony zostaje na stosie – na którym Forth wykonuje operacje: w tym przypadku dwukrotne skopiowanie argumentu i dwukrotne mnożenie. Napis w nawiasie jest komentarzem. Wynik operacji również zostaje umieszczony na stosie i może być wykorzystany do dalszych obliczeń lub zapamiętany w zmiennej[8][12][13].

( POW_3, a -- b )
: POW_3 DUP DUP * * ;
5 POW_3

Podprogram w języku Fortran 77

Rodzaje podprogramów w języku Fortran 77:

 identyfikator([parametry])=wyrażenie
  SUBROUTINE identyfikator(parametry)
    [deklaracje]
    instrukcje
  END
  type FUNCTION identyfikator([parametry])
    [deklaracje]
    instrukcje
  END

Podprogram w języku Java

W Javie podprogramy są metodami klas.

 class Nazwa {
   ...
   [public | protected | private] [native] [static] [synchronized] type name ( type1 arg1, type2 arg2 ){
     ...
   }
   ...
 }

Podprogram w języku JavaScript

Podprogram w języku JavaScript[18]:

function Nazwa(parametr1, parametr2, parametr3)
{
  // instrukcje do wykonania (ciało funkcji)
  return parametr1; // zwrócenie wartości
}

Podprogram w języku Jean (oraz JOSS)

W języku Jean (oraz JOSS) każda instrukcja poprzedzona jest etykietą składającą się z dwóch części (liczby całkowite): PART.STEP. Wszystkie instrukcja poprzedzone jednakową etykietą PART tworzą bezparametrową procedurę[9][10].

1.1 DEMAND N
1.2 DEMAND A(I) FOR I=1(1)N
1.3 SET T=0
1.4 LET SUM(A,B)=A+B
1.5 DO PART 2 FOR I=1(1)N
1.6 TYPE T
2.1 SET T=SUM(T,A(I)) IF A(I)>0
2.2 SET T=T+1
DO PART 1

Tak jak podprogram można również użyć pojedynczej instrukcji poprzez wywołanie o postaci:

1.7 DO STEP 1.1

Ponadto w języku Jean można definiować funkcje w postaci prostych wyrażeń (podobnie jak w języku Basic):

4.1 LET SINX(X,A)=X+SIN(A)

Podprogram w języku Logo:

 to square :side
 repeat 4 [fd :side rt 90]
 end
 make "inst [fd 40 rt 90]
 run :inst

Podprogram w języku MCPL

Podprogram w języku MCPL:

  FUN ''name''
    : [P, …, Pn] => ''Clist''
   [: …
    : P, …, Pxn => ''Clist-x'']
.

  MATH | EVERY [(''args'')]
     : P, …, Pn => ''Clist''
    [: …
     : P, …, Pxn => ''Clist-x'']
.

Język posiada także mechanizmy umożliwiające definiowanie korutyn.

Podprogram w języku Modula 2

Podprogram w języku Modula-2[15]:

  PROCEDURE nazwa([lista_paramertów])
    deklaracje lokalne
  BEGIN
    instrukcje
  END nazwa;

  PROCEDURE nazwa([lista_paramertów]): typ;
    deklaracje lokalne
  BEGIN
    instrukcje
    RETURN wyrażenie
  END nazwa;

Podprogram w języku Pascal

Podprogram w języku Pascal: jako procedura[1][2]:

 procedure Procedura( {argumenty} );
 begin
    { instrukcje do wykonania }
 end;

jako funkcja[1][2]:

 function Funkcja( {argumenty} ) : integer; { typ wartości funkcji }
 begin
    { instrukcje do wykonania (ciało funkcji) }
 end;

Podprogram w języku PHP

Podprogram w języku PHP:

 // definicja podprogramu, w PHP5 możliwe określenie klasy bazowej zmiennej $wejscie
 function nazwapodprogramu($wejscie) {

 // zawartość podprogramu

 return $wyjscie; // zwrócenie wartości
 } // koniec podprogramu

Podprogram w języku PL/1

W języku PL/1 podprogram definiowany jest w postaci procedury. Podobnie jak danym, procedurom nadaje się różne atrybuty, wśród których można użyć frazy RETURNS(typ), która nadaje procedurze właściwości funkcji określając równocześnie typ zwracanej wartości[6][7].

Charakterystyczną cechę podprogramu w PL/1 jest to, że oprócz – występującej w większości języków programowania – możliwości zdefiniowania wielu punktów wyjść podprogramu (instrukcja RETURN i END), istnieje możliwość wyspecyfikowania wielu punktów wejść (zwanych w nomenklaturze PL/1 ingresjami) do podprogramu i to z różnymi parametrami i atrybutami[6][7] (podobne możliwości wprowadzono w Fortranie IV).

 /* ingresja główna – początek procedury */
 nazwa: PROC (parametry) opcje i atrybuty;
	deklaracje
	instrukcje
	…
	/* ingresja poboczna – kolejny punkt wejścia do procedury */
	nazwa_1: ENTRY (parametry) opcje i atrybuty;
	deklaracje
	instrukcje
	…
	/* ingresja poboczna – kolejny punkt wejścia do procedury */
	nazwa_n: ENTRY (parametry) opcje i atrybuty;
	deklaracje
	instrukcje
	…
 END [nazwa];

Podprogram w języku Prolog

Podprogram w języku Prolog (Turbo Prolog) ma charakterystyczną postać, wynikającą z właściwości tego języka logiki. Nagłówek podprogramu deklarowany jest w sekcji PREDICATES, natomiast definicja podprogramu znajduje się w sekcji CLAUSES i może składać się z wielu faktów i reguł. Podprogram w tym języku jest więc zawsze predykatem, nawet jeśli ma on charakter czysto operacyjny (np. instrukcje wejścia-wyjścia, graficzne itp.).

Przykład:

  PREDICATES
    rodzic(symbol, symbol)
    ojciec(symbol, symbol)
    
  CLAUSES
    rodzic(Adam, Janusz).
    rodzic(Adam, Katarzyna).
    rodzic(Anna, Piotr).
    
    ojciec(Przodek, Potomek) :- rodzic(Przodek, Potomek), mężczyzna(Przodek).
    

Podprogram w języku Python

Podprogram w Pythonie nazywany jest funkcją. Przykład (wcięcia są istotne, ze względu na specyfikę składni języka):

 def funkcja(parametr_pozycyjny,*nienazwane_parametry,**nazwane_parametry):
       Łańcuch dokumentacji opisujący działania funkcji
       print nienazwane_parametry
       print nazwane_parametry
       return parametr_pozycyjny

Możliwe wywołanie (argumenty nienazwane muszą się znaleźć przed nazwanymi):

 print funkcja("Hello World!",123,None,argument="wartosc")

...i jego rezultat:

(123,None)
{'argument': 'wartosc'}
Hello World!

Gdy funkcja jest definiowana jako metoda obiektu, pierwszym parametrem zawsze jest ten obiekt (tradycyjnie nazywany self, jednak język tego nie wymaga).

Podprogram w języku S

 Sub nazwa(parametry)
 deklaracje
 Enter
   instrukcje
 Leave
 Def nazwa(parametry) as typ
 deklaracje
 Enter
   instrukcje
 Leave

Podprogram w języku Snobol

Podprogram w języku Snobol:

  * FUNKCJA ODWRACAJĄCA KOLEJNOŚĆ
  * ZNAKÓW W NAPISIE
        DEFINE('REV(X)C') :(K.REV)
  REV   X LEN(1).C=       :F(RETURN)
        REV=REV(X) C      :(RETURN)
  K.REV

Podprogram w języku Visual Basic

Podprogram w języku Visual Basic:

  [Public | Private] [Static] Function nazwa([lista_parametrów]) [As typ]
  instrukcje
  
  [nazwa=wyrażenie]
  
  [Exit Function]
  
  End Function

  [Public | Private] [Static] Sub nazwa([lista_parametrów])
  instrukcje
  
  [Exit Sub]
  
  End Sub

Zobacz też

Przypisy

  1. a b c d e f g h i Michał Iglewski, Jan Madey, Stanisław Matwin: Pascal. Język wzorcowy – Pascal 360. Wyd. trzecie – zmienione. Warszawa: Wydawnictwa Naukowo-Techniczne, 1984, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-85060-53-7. ISSN 0867-6011. (pol.).
  2. a b c d e f g h i j Andrzej Marciniak: Borland Pascal 7.0. Poznań: Nakom, 1994, seria: Biblioteka Użytkownika Mikrokomputerów. ISBN 83-85060-53-7. ISSN 0867-6011. (pol.).
  3. a b c d e f Brian W. Kernighan, Dennis M. Ritche: Język C. Warszawa: Wydawnictwa Naukowo-Techniczne, 1988, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-1067-3. (pol.).
  4. a b c d e f Jan Bielecki: Turbo C z grafiką na IBM PC. Warszawa: Wydawnictwa Naukowo-Techniczne, 1990, seria: Mikrokomputery. ISBN 83-204-1101-7. (pol.).
  5. a b c d e f g h i Jan Bielecki: Od C do C++, programowanie obiektowe w języku C. Warszawa: Wydawnictwa Naukowo-Techniczne, 1990. ISBN 83-204-1332-X. (pol.).
  6. a b c d e f g h i j Jan Bielecki: Rozszerzony PL/I i JCL w systemie OS/RIAD. Warszawa: Państwowe Wydawnictwo Naukowe, 1986, seria: Biblioteka Informatyki. ISBN 83-01-06146-4. (pol.).
  7. a b c d e f g h i j M. I. Auguston i inni: Programowanie w języku PL/1 OS JS. Warszawa: Państwowe Wydawnictwo Naukowe, 1988. ISBN 83-01-07463-9. (pol.).
  8. a b c d e f Mike Ducka, tłumaczenie: Marcin Turski: Języki mikrokomputerów. Przewodnik dla początkujących. Basic, Pascal, Logo, Prolog, Comal, Forth. Warszawa: Wydawnictwa Naukowo-Techniczne, 1988. ISBN 83-204-0966-7. (pol.).
  9. a b c d Jerzy Bettek, Bronisław Rudak, Barbara Rudakowa: Język konwersacyjny JEAN. Wrocław: Wydawnictwo Politechniki Wrocławskiej, 1975, seria: Skrypt wydany w serii Biblioteka WASC. (pol.).
  10. a b c d Kazimierz Orlicz: Język konwersacyjny JEAN z elementami programowania w Fortranie. Wrocław: Wydawnictwo Politechniki Wrocławskiej, 1977, seria: Skrypt wydany w serii Biblioteka WASC. (pol.).
  11. a b Wojciech Rogowski, Arkadiusz Serodziński: Clipper 5.0. Warszawa: Wydawnictwo PLJ, 1991. ISBN 83-85190-20-1. (pol.).
  12. a b Jan Bielecki: Język FORTH. Warszawa: Wydawnictwa Naukowo-Techniczne, 1988, seria: Mikrokomputery. ISBN 83-204-0930-6. (pol.).
  13. a b Jan Ruszczyc: Poznajemy FORTH. Warszawa: SOETO, 1987, seria: Informatyka mikrokomputerowa. (pol.).
  14. Ralph E. Griswold, Madge T. Griswold: Icon. Warszawa: Wydawnictwa Naukowo-Techniczne, 1987, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-0871-7. (pol.).
  15. a b Niklaus Wirth: Modula 2. Warszawa: Wydawnictwa Naukowo-Techniczne, 1987, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-0828-8. ISSN 0867-6011. (pol.).
  16. Jan Bielecki: PL/M język programowania mikroprocesorów. Wyd. drugie uzupełnione. Warszawa: Wydawnictwa Komunikacji i Łączności, 1987, seria: Elektronizacja. zeszyt 25. (pol.).
  17. Jan Bielecki: System operacyjny ISIS-II. Warszawa: Wydawnictwa Naukowo-Techniczne, 1987, seria: Mikrokomputery. ISBN 83-204-0893-8. (pol.).
  18. Wojciech Romowicz, HTML i JavaScript, HELION 1998 r., ISBN 83-7197-046-3