background image

Wykład XIV i XV

Object Pascal – 

Podprogramy (funkcje i 

procedury)

Podstawy informatyki
Semestr II Transport

background image

2

O czym będzie?

Funkcje
Procedury
Biblioteki (moduły)

background image

3

Podprogram

Wyodrębniona część programu 
stanowiącą pewną całość, 
posiadającą jednoznaczną nazwę 
i ustalony sposób wymiany 
informacji z pozostałymi 
częściami programu.

background image

4

Rodzaje podprogramów

Istnieje dwa rodzaje podprogramów:

– procedura – wykonanie pewnej 

sekwencji czynności

– funkcja - obliczenie jednej wartości

Procedury i funkcje stanowią wydzielone 

części aplikacji, wykonujące ściśle 

określony, zamknięty blok instrukcji. 

Dodatkowo, funkcja zwraca pod swą 

nazwą wartość określonego typu.

background image

5

Procedury

Nagłówek procedury rozpoczyna się od słowa 

kluczowego procedure, po którym występuje nazwa 

procedury i – nieobowiązkowo – lista parametrów 

formalnych, zamknięta w nawiasy okrągłe; całość 

kończy się średnikiem.
Lista ta ma znaczenie podczas wywoływania 

procedury, kiedy to poszczególnym parametrom 

formalnym przyporządkowane zostaną wg. określonych 

zasad (o czym później) konkretne parametry aktualne.
Część opisowa – zawiera listę deklaracji
Blok procedury składa się z instrukcji złożonej (begin 

... end) wykonywanej przy wywołaniu procedury.

background image

6

Szablon procedury

procedure nazwa-procedury (lista-

parametrów);

cześć-opisowa
begin

ciąg-instrukcji

end;

background image

7

Funkcje

Mają naturę zbliżoną do procedur, inny jest jednak ich sens 

w programie; podczas gdy procedura symbolizuje pewien 

zamknięty zestaw czynności funkcja ucieleśnia pod swą 

nazwą konkretną wartość, określonego typu – inna rzecz, że 

najczęściej wyliczoną również w ramach wykonania ciągu 

instrukcji.
Ma to wpływ na postać nagłówka, w którym po słowie 

kluczowym function następuje nazwa funkcji, potem 

nieobowiązkowo lista parametrów (identycznie jak w 

procedurze), jednak przed średnikiem następuje jeszcze 

wskazanie na typ wyniku funkcji (poprzedzone 

dwukropkiem). Typ funkcji nie może być typem plikowym 

ani też typem strukturalnym zawierającym w sobie typ 

plikowy.

background image

8

Funkcje cd.

Część opisowa – zawiera takie same elementy 
jak w procedurach
Instrukcja złożona – ma takie samo znaczenie 
jak w procedurze jednak z pewną istotną różnicą 
otóż w ramach jej instrukcji musi nastąpić 
przynajmniej raz przypisanie funkcji konkretnej 
wartości. Może się to odbyć przez podstawienie 
wartości funkcji pod jej nazwę lub słowo 
kluczowe Result (symbolizującego niejako 
zmienną przechowującą aktualny wynik funkcji).

background image

9

Szablon funkcji

function nazwa- funkcji(lista-

parametrów):typ-wyniku;

część-opisowa
begin
  ciąg-instrukcji 
  przypisanie funkcji (chociaż raz w ciągu 

instrukcji)

end;

background image

10

Część opisowa dla funkcji i 

procedur

Część opisowa podprogramów może zawierać te same 

deklaracje co program.
Możemy w niej zatem umieścić deklaracje:

– etykiet (label)
– typów (type)
– stałych (const)
– zmiennych (var)
– funkcji (function) i procedur (procedure)

Sposób deklarowania poszczególnych elementów jest 

analogiczny do definicji w głównym bloku programu 

(omówionych na wykładzie pt. „Podstawy 

programowania w Object Pascalu”). 

background image

11

Przypisanie funkcji

nazwa-funkcji:= wyrażenie
lub
Result:=wyrażenie

musi wystąpić przynajmniej raz w części 

wykonawczej funkcji
przynajmniej jedna z instrukcji przypisania 

powinna zostać wykonana po wywołaniu 

funkcji

background image

12

Typ wyniku

określony jest za pomocą 
identyfikatora typu (nie mogą to 
być typy plikowe ani strukturalne 
zawierające typ plikowy)
decyduje o typie zwracanego 
przez funkcję wyniku

background image

13

Rodzaje  parametrów

parametry przekazywane przez wartość,

      lista - parametrów : typ;

parametry przekazywane przez zmienną 

określonego typu

      var lista - parametrów : typ

parametry przekazywane przez wartość 

stałą,
  const lista - parametrów : typ;
parametry przekazywane przez zmienną 

nieokreślonego typu

      var lista-parametrów

background image

14

Kojarzenie parametrów 

przez wartość

Przekazywanie parametru przez wartość 
wiąże się z automatycznym utworzeniem 
jego lokalnej kopii, dostępnej pod 
oryginalną nazwą parametru formalnego.
Innymi słowy wszystkie operacje 
wykonywane wewnątrz treści 
podprogramu na parametrze wykonywane 
są na jego lokalnej kopii, a parametr 
oryginalny pozostaje nienaruszony.

background image

15

Przekazywanie parametrów przez 

adres (zmienną, referencję, 

odwołanie, wskazanie)

Przekazywanie parametru przez adres powoduje, że w treści 

podprogramu pod nazwą parametru formalnego kryje się 

rzeczywisty parametr aktualny, a wszystkie operacje 

wykonywane są bezpośrednio na nim, bez tworzenia 

jakichkolwiek kopii.
Jest  to więc właściwy sposób na przekazanie przez 

procedurę wartości zwrotnej do programu wywołującego.
Parametrem aktualnym może być jedyne zmienna (lub 

konstrukcja równoważna*)
procedure Powieksz(var X: Integer);
begin
  X:=X*2; 

{procedura podwaja wartość swojego parametru}

end;

background image

16

Przekazywanie parametrów przez 

adres cd.

Przy przekazywaniu parametru przez odwołanie 
zasada zgodności w sensie przypisania jest 
niewystarczająca: typ parametru formalnego i 
aktualnego musi być bowiem dokładnie taki sam.
Z punktu widzenia implementacji parametr 
formalny kojarzony przez odwołanie 
reprezentowany jest w treści podprogramu przez 
adres parametru aktualnego, a skojarzenie 
sprowadza się do przekazania tego adresu.

background image

17

Przekazywanie 

parametrów przez stałą

Ten sposób przekazywania parametrów łączy w sobie 
zalety dwu poprzednich sposobów.
Z jednej strony parametr taki podlega tym samym 
regułą składniowym jak parametry przekazywane 
przez wartość.
Z drugiej strony techniczny sposób jego 
przekazywania jest taki sam jak dla zmiennej 
przekazywanej przez adres – nie jest tworzona kopia 
lokalna, zamiast tego w treści procedury zabronione 
są konstrukcje mogące doprowadzić do zmiany 
parametru (powodują one błąd kompilacji).

background image

18

Parametry amorficzne 

(przekazywane przez zmienną 

(lub stałą) nieokreślonego typu)

Możliwe jest określenie parametru formalnego bez 

podania jego typu.
Parametr taki musi być przekazywany przez 

odwołanie lub przez stałą.
Konstrukcja ta rozluźnia reguły składniowe Pascala. W 

charakterze parametru może wystąpić dowolny 

parametr dozwolony dla wywołania przez odwołanie.
Należy zauważyć, że w treści podprogramu parametr 

amorficzny nie posiada określonego typu i nie jest 

zgodny z żadnym typem zmiennych i w większości 

przypadków konieczne jest poddanie go operacji 

rzutowania typów.

background image

19

Parametry amorficzne - 

przykład

procedure WypelnijObszar(var X; Rozmiar: Integer);
var i, k : Integer; Y: array[1..1] of Byte absolute X;
begin

k:=0;
for i:=1 to Rozmiar do
begin
   Y[i]:=k;
   k:=(k+1) mod 255;
end;

end;

background image

20

Typy amorficzne – 

Uwaga!!!

Niewątpliwa elastyczność jaką niosą typy 
amorficzne wymaga od programisty 
zwiększonej ostrożności, bowiem 
zaniechanie kontroli typu przez 
kompilator stanowi równocześnie brak 
ochrony przed wieloma 
niebezpieczeństwami, jak np. 
przekroczenie obszaru pamięci 
zajmowanego przez zmienną.

background image

21

Zasady o których warto 

pamiętać podczas tworzenia 

funkcji i procedur

Stosujmy odpowiednie nazwy. Nazwa podprogramu może 

oddawać jego przeznaczenie;
Można umieścić komentarze opisujące przeznaczenie i 

parametry podprogramu,
Starajmy się deklarować obiekty lokalne;
Dobierajmy poprawnie rodzaj parametrów pamiętając o 

sprawdzeniu czy:

      a)

parametr musi być przekazywany przez zmienną 

czy przez 

wartość;

      b)

parametr będzie ulegał zmianom podczas 

wykonania 

podprogramu

Unikamy przekazywania przez wartość dużych struktur 

danych.

background image

22

Zasięg deklaracji (ang. 

scope)

Zasięg deklaracji jest pojęciem związanym z 

obowiązywaniem poszczególnych deklaracji w 

poszczególnych fragmentach programu.
I tak zmienne globalne zadeklarowane w głównym 

projekcie (lub bibliotece) widoczne są w całym programie, 

podczas gdy zmienne lokalne zadeklarowane w 

podprogramie nie są widoczne na zewnątrz niego.
Może się zdarzyć, że w danym bloku programu np. 

wewnątrz procedury zdefiniowany zostanie lokalny 

identyfikator o takiej samej nazwie, jak – widoczny z 

wnętrza tej procedury – identyfikator globalny; ten ostatni 

przestanie być wtedy dostępny w procedurze, zostanie 

bowiem przesłonięty lokalną deklaracją.

background image

23

Zasięg deklaracji - 

przykład

var Licznik: Integer; 

{zmienna globalna}

...
procedure A(X: Integer);
var Licznik: Byte;
begin
...

Licznik:=Licznik+X; 

{tu modyfikowana 

jest wartość zmiennej lokalnej z 

procedury A, zmienna globalna nie 

jest dostępna gdyż została 

przysłonięta przez lokalną deklarację}

...
end;

begin

...
Licznik:=Licznik+3;

 

{tu modyfikujemy 
zmienną globalną; 
lokalna nie jest 
dostępna gdyż 
jesteśmy poza jej 
zasięgiem – poza 
procedurą A}

...

end.

background image

24

Przykład 1

function fun1 (const x : Double) : Double;
begin

if x<0.5 then Result:=(0.2*x-1)*x+0.1
else Result:=x*x / (x*x-0.1)

end;



5

.

0

1

.

0

5

.

0

1

.

0

2

.

0

)

(

1

2

2

2

x

dla

x

x

x

dla

x

x

x

fun

background image

25

Przykład 2

Obliczanie wartości wielomianu Lagendre’a n-
tego stopnia

  

 

 

 

 

x

x

P

x

P

x

P

n

x

xP

n

x

nP

n

n

n

1

0

2

1

1

)

1

(

1

2

background image

26

Przykład 2 cd

function Legendre (const n 

: Byte; const x : Double) : 

Double;

 var i:Byte;
    p0,p1,p2  : Double;
begin

if n=0 then Legendre:=1 
else 
  if n=1 then Legendre:=x
  else begin
    P1:=1 p2:=x;

 for i:=2 to n do
   begin

p0:=p1;
p1:=p2;     

  p2:=((2*n-1)*x*p1-(n-

1)*p0)/n 

   end;
 Legendre:=p2
 end ;
end;

background image

27

Funkcje rekurencyjne

Pojęcie rekurencji szczegółowo 
wyjaśniono na wykładzie pt. 
„Algorytmy i dane”
W części operacyjnej funkcji 
następuje wywołanie funkcji przez 
samą siebie.  

background image

28

Przykład funkcji 

rekurencyjnej

function silnia (n : Byte) : Integer;
begin

if n>12 then silnia:=0 
else

if n=0 then silnia:=1
else silnia:=n*silnia(n-1)

end;

background image

29

Wywołanie funkcji

Następuje za pomocą, podania nazwy 
funkcji (wraz z odpowiednią do deklaracji 
listą parametrów aktualnych) jako 
argumentu dowolnego wyrażenia . 

Przykład

 X:=Legendre(4, 
12.5)*3+Sin(X)+Silnia(5)

background image

30

Przykład 3

program FunkcjeDemo3;
var alfa,beta,gamma,delta,y,z : Real;
function mianownik (zeta : Real) : Real;
begin

mianownik:=(sqr(zeta)

+sqrt(1+(2+3*zeta)*zeta))

end;
begin
 

... 

      alfa:=(6.9+y)/mianownik(y);
      beta:=((2.1+z*sqr(z))*z)/mianownik(z);
      ganma:=sin(y)/mianownik(sqr(y));         
      delta:=1/mianownik(sin (y) );

... 

end.

( )

( )

( )

( )

y

y

y

y

y

y

y

y

z

z

z

z

z

y

y

y

y

2

2

4

2

4

2

2

4

2

2

sin

3

sin

2

1

sin

3

2

1

sin

3

2

1

1

.

2

3

2

1

9

.

6

+

+

+

=

+

+

+

=

+

+

+

+

=

+

+

+

+

=

background image

31

Przykład 4

uses Dialogs;   ...
procedure
 Srednia(var wynik :Double; ilosc: Byte);
var a, i: Byte;S:string;
begin

wynik:=0;
for i:=1 to ilosc do

      begin

InputQuery(‘Liczba’, ‘Podaj a:’,S);
a:=StrToFloat(S);   wynik:=wynik+a;
  end;
wynik:= wynik/ilosc;

end;

background image

32

Wywoływanie procedury

Do wywoływania  służy instrukcja postaci:

nazwa-procedury

lub

nazwa procedury(lista-parametrów-
aktualnych)
Przykłady
Srednia(wynik, 4 );
ShowMessage(FloatToStr(wynik));

background image

33

Przykład 5

procedure rk(const a, b, c: Double;

          var x1, x2, Delta : Double);

begin

delta:=b*b-4*a*c;
if delta=0 then
begin
  x1:=-b/(2*a);
  x2:=x1; 
end

else
  if
 delta>0 then
    begin 

 delta:=sqrt(delta);
 x1:=(-b-delta)/
(2*a);
 x2:=(-b+delta)/
(2*a)
end ;

end;

background image

34

Moduły  w Delphi (ang. 

units)

Moduły (biblioteki)  stanowią podstawowe 

jednostki programu grupujące deklaracje 

oraz funkcje i procedury oraz 

przechowywania formularzy.
Są osiągalne z programu głównego, a także 

nawzajem pomiędzy modułami.
Nazwa modułu musi być tożsama z nazwą 

pliku, w którym on się znajduje; moduł o 

nazwie banki musi być zapisany w pliku 

banki.pas.

background image

35

Budowa modułu

Każdy moduł składa się z

Dyrektywy unit
części publicznej (opisowej)
części prywatnej (implementacyjnej)

Ponadto w module mogą wystąpić 

następujące elementy
część inicjacyjna
część kończąca

background image

36

Szkielet modułu

Unit

nazwa-modulu;

część opisowa modułu 
część implementacyjna
część inicjująca (opcjonalnie)
część kończąca (opcjonalnie)

end.

background image

37

Dyrektywa unit

Stanowi pierwszą linię modułu
Składa się ze słowa kluczowego unit i 
nazwy modułu.

background image

38

Cześć publiczna

Rozpoczyna się od dyrektywy interface i zawiera 

te części modułu (stałe, zmienne, typy, nagłówki 

funkcji i procedur, itp.), które mają być dostępne 

dla innych modułów oraz programu głównego.
W odniesieniu do funkcji i procedur część publiczna 

zawiera jedynie ich nagłówki, gdyż tylko one są 

istotne dla reszty programu; szczegółowe definicje 

podprogramów (funkcji i procedur) znajdują się w 

części prywatnej modułu.
Wszystkie elementy wewnątrz części publicznej są 

opcjonalne.

background image

39

Część opisowa modułu

interface

deklaracje użycia innych modułów 

(uses)

definicje-interface

literały, stałe (const)

definicje typów (type)

deklaracje zmiennych (var)

lista nagłówków procedur i funkcji
(procedurefunction)

background image

40

Część implementacyjna

Część implementacyjna rozpoczyna się słowem 

kluczowym implementation i zawiera te definicje 

modułu , które mają dla niego znaczenie lokalne
Wszystkie definicje modułów, do których odwołuje się 

część prywatna powinny wystąpić w początkowej 

dyrektywie uses występującej bezpośrednio po słowie 

kluczowym implementation.
Zawiera  deklaracje etykiet, literałów i zmiennych oraz 

definicje typów, funkcji i procedur wewnętrznych.
Zawiera treść funkcji i procedur udostępnianych na 

zewnątrz (ich nagłówki znajdują się w sekcji interface)

background image

41

Część inicjująca

Składa się ze słowa kluczowego 
initialization, po którym występują 
instrukcje,która będą wykonane 
jednokrotnie przed rozpoczęciem 
programu głównego w celu zainicjowania 
modułu (np. przydzielenie pamięci, 
wczytanie zasobów)
Występowanie tej części jest opcjonalne.

background image

42

Część kończąca

Składa się ze słowa kluczowego finalization, po 
którym występują instrukcje, która będą podczas 
kończenia pracy modułu (po zakończeniu 
programu głównego np. zwalnianie pamięci, 
zwalnianie zasobów)
Występowanie tej części jest opcjonalne, wystąpić 
może jednak tylko łącznie z sekcją inicjującą.
kolejność wykonywania części kończących jest 
odwrotna w stosunku do kolejności wykonania 
części inicjujących.

background image

43

Szkielet modułu

unit Nazwa;
interface
...
implementation
...
initialization
...
finalization
...
end.

background image

44

Przykład 6

unit cplxproc;
interface

procedure addcplx (aRe,aIm,bRe,bIm: Double; var 

cRe,CIm: Double);

procedure subcplx(aRe,aIm,bRe,bIm: Double; var 

cRe,CIm: Double);

procedure multcplx (aRe,aIm,bRe,bIm: Double; var 

cRe,CIm: Double);

procedure divcplx (aRe,aIm,bRe,bIm: Double; var 

cRe,CIm: Double);

background image

45

Przykład 7 cd

implementation
procedure
 addcplx;
begin

cRe:=aRe+bRe;

cIm:=aIm+bIm;

end;
procedure
 subcplx;
begin

cRe:=aRe-bRe;

cIm:=aIm-bIm 

end;

background image

46

Przykład 7 cd

procedure multcplx;
begin

cRe:=aRe*bRe-aIm*blm;

cIm:=aRe*bIm+aIm*bRe;

end;
procedure
 divcplx;
var diwv : Real;
begin

diw:=sqr(bRe)+sqr(bIm);
cRe:=(aRe*bRe+aIm*bIm)/diw;   cIm:=(alm*bRe-

aRe*bIm) /diw;

end;
end.

background image

47

Moduły wzajemnie zależne

Wykorzystują wzajemnie elementy w nich  
zdefiniowane.
W części implementacyjnej pierwszego modułu 
występuje deklaracja drugiego modułu, a w części 
implementacyjnej drugiego modułu  deklaracja 
pierwszego.
Dzięki  takiej konstrukcji ewentualne procedury 
zdefiniowane w wykropkowanej części 
implementacyjnej pierwszego modułu dostępne są 
w wykropkowanej części implementacyjnej 
drugiego modułu i na odwrót.

background image

48

Szkielet konstrukcji modułów

wzajemnie zależnych

unit modul1; 

interface
...                            
implementation
uses
 modul2;
...
end.

unit modul2; 

interface
...                            
implementation
uses
 modul1;
...
end.


Document Outline