pk procedury i funkcje

background image

.

- 1 -

6. Procedury i funkcje

6.1. Mapa pamięci programu napisanego w Turbo Pascalu
6.2. Wprowadzenie do pojęcia procedury i funkcji.
6.3. Definicja procedur i funkcji

6.3.1. Procedury i funkcje bezparametrowe
6.3.2. Przekazywanie parametrów przez wartości
6.3.3. Przekazywanie parametrów przez zmienne określonego typu
6.3.4. Przekazywanie parametrów przez zmienne nieokreślonego typu

6.4. Podsumowanie
6.5. Przykłady

6.1. Mapa pamięci programu napisanego w Turbo Pascalu

Zanim przejdziemy do przedstawienia sposobu definiowania procedur i funkcji oraz opisania różnych metod

ich definicji, przedstawimy, w jaki sposób programy napisane w Pascalu korzystają z pamięci komputera.

Pamięć komputera, jak wiadomo, jest pewnego rodzaju uporządkowanym ciągiem bajtów, komórek pamięci do

których możliwy jest dostęp przez podanie odpowiedniego adresu. Każdy adres składa się z dwóch części:
• adresu segmentu (segment to ciągły obszar pamięci o długości do 64KB),
• adresu względnego (przesunięcia, offsetu) określającego odległość danej komórki od początku segmentu.
W jaki sposób program, napisany w Turbo Pascalu i skompilowany w trybie rzeczywistym, umieszczany jest w
pamięci przedstawiono poniżej.

wolny obszar stosu

stos dla zmiennych dynamicznych

bufor nakładkowy

segment stosowy dla zmiennych lokalnych

wolny obszar segmentu stosowego

segment danych

blok kodu modułu System

blok kodu pierwszego modułu

blok kodu ostatniego modułu

blok kodu programu

blok wstępny programu (PSP)

bloki kodu kolejnych modułów

HeapEnd

HeapPtr

HeapOrg

SSeg:SPtr

SSeg:0000

DSeg:0000

PrefixSeg

OvrHeapEnd

OvrHeapOrg

literały zmienne

zmienne globalne

zawartość obrazu zbioru .EXE

Podczas wczytywania zbioru .EXE do pamięci, system operacyjny DOS tworzy blok wstępny programu.

Ten obszar pamięci służy do komunikacji pomiędzy systemem operacyjnym i programem. Blok PSP (Program
Segment Prefix) zajmuje zawsze 256 bajtów. Adres segmentu pamięci, od którego rozpoczyna się ten blok jest
pamiętany w predefiniowanej zmiennej PrefixSeg.

Blok kodowy zajmuje kod programu głównego.

background image

- 2 -

W kolejnych blokach pamiętane są kody zadeklarowanych w programie modułów (w odwrotnej kolejności

niż zadeklarowane). W ostatnim bloku kodowym pamiętany jest standardowy moduł System (dla przypomnienia -
nie jest wymagana deklaracja tego modułuw programie).

W segmencie danych pamiętane są wszystkie literały zmienne zdefiniowane w programie i modułach oraz

zmienne globalne zadeklarowane w programie i modułach. Początek adresu tego segmentu jest wartością
standardowej funkcji DSeg. Rozmiar segmentu danych (podobnie jak poszczególnych segmentów kodowych) nie
może przekraczać 64 kB.

W segmencie stosowym pamiętane są zmienne lokalne. Kolejne zmienne zapamiętywane są w kierunku

malejących adresów pamięci. Rozmiar segmentu stosowego (max 64 kB) ustala się za pomocą dyrektywy
kompilatora M lub w menu systemu Turbo Pascal.

Do przechowywania segmentów nakładkowych programu jest wykorzystywany bufor nakładkowy. Jeśli

program nie posiada segmentów nakładkowych, rozmiar tego bufora jest równy zeru. Adresy początku i końca
bufora nakładkowego pamiętane są w predefiniowanych zmiennych OvrHeapOrg i OvrHeapEnd.

Stos zmiennych dynamicznych (sterta) służy do przechowywania zmiennych dynamicznych. Pamięć dla

tych zmiennych jest przydzielana za pomocą standardowych procedur New i GetMem. Zmienne dynamiczne mogą
zajmować cala resztę pamięci dostępna podczas wykonywania programu. Adres początku stosu pamiętany jest w
zmiennej HeapOrg a adres wierzchołka stosu w zmiennej HeapPtr..

Uwaga, żaden z bloków kodowych nie może zając więcej niż 64 kB pamięci, natomiast rozmiar wszystkich

bloków łącznie jest ograniczony jedynie wielkością pamięci komputera.

Na podstawie powyższej mapy pamięci można zauważyć, że zmienne globalne umieszczane są w segmencie

danych. Rozmiar tego segmentu jest niezwykle skąpy jak na wymagania przeciętnego programisty. Jednak w
Pascalu istnieją jeszcze dwa bardzo znaczące segmenty pamięci, to jest stos dla zmiennych lokalnych – w którym
rezerwowana będzie pamięć dla zmiennych deklarowanych wewnątrz procedur i funkcji, oraz stos dla zmiennych
dynamicznych (sterta).

6.2. Wprowadzenie pojęcia procedury i funkcji

Procedurą lub funkcją jest wyodrębniona część programu, stanowiącą pewną całość, posiadającą jednoznaczny

identyfikator i ustalony sposób wymiany informacji z pozostałymi częściami programu. Procedury i funkcje
stosowane są do najczęściej do wykonywania czynności, które wykorzystane mogą być w różnych programach
oraz wykonywania czynności wielokrotnie powtarzanych przez dany program. Szczególnie korzystne jest
zastosowanie procedur i funkcji w programach, w których można wyodrębnić kilka problemów, możliwych do
oddzielnego opracowania każdego z nich.

Dzięki stosowaniu procedur i funkcji można również efektywniej wykorzystać pamięć komputera, gdyż

obiektom określonym wewnątrz procedury lub funkcji pamięć przydzielana jest dopiero z chwilą wywołania danej
procedury lub funkcji, a zwalniana po wyjściu z niej.

Pamiętać należy, że aby procedury i funkcje były uniwersalne, powinny być możliwie najsłabiej związane z

danym programem.

6.3. Definicja procedur i funkcji

Opis funkcji lub procedury w programie następuje za pomocą definicji. W przypadku procedur zachodzi także

niekiedy konieczność ich zadeklarowania.
W nagłówku definicji procedury lub funkcji podaje się identyfikator oraz ewentualnie parametry formalne, tj.
wielkości od których zależeć będzie działanie procedury (funkcji). W przypadku funkcji, w nagłówku określa się
ponadto typ wyniku. Po nagłówku podaje się treść procedury (funkcji). Treść ta składa się z części opisowej, w

background image

.

- 3 -

której definiuje i deklaruje się obiekty lokalne wewnątrz danej procedury lub funkcji oraz z części operacyjnej
(mającej zawsze postać instrukcji złożonej), która zawiera sekwencję instrukcji powodującą wykonanie czynności
przewidzianych przez dany algorytm. Czynności te mogą być wykonywane zarówno na obiektach lokalnych, jak i
na obiektach nielokalnych (zdefiniowanych lub zadeklarowanych na zewnątrz procedury lub funkcji).

Obiekty nielokalne występują w treści procedury lub funkcji w sposób jawny lub są do niej przekazywane

przez parametry.

Definicje procedury i funkcji mają następujące postacie ogólne:

procedure identyfikator_procedury ( lista_parametrów_formalnych);

{ część_opisowa }

begin

{ ciąg_instrukcji }

end;

function identyfikator_funkcji (lista_parametrów_formalnych): typ_wyniku;

{ część_opisowa }

begin

{ ciąg_instrukcji }

end;

W obu przypadkach część opisowa i lista parametrów formalnych jest opcjonalna. Część opisowa procedury lub
funkcji może zawierać takie same elementy jak część opisowa programu, z wyjątkiem deklaracji modułów. Lista
parametrów formalnych zawiera deklaracje parametrów formalnych, oddzielonych średnikami. W zależności od
sposobu przekazywania informacji, to znaczy zastępowania parametrów formalnych występujących w definicji
odpowiednimi parametrami wywołania (argumentami, parametrami aktualnymi) wyróżniamy m.in.

• parametry przekazywane przez wartości,
• parametry przekazywane przez zmienne określonego typu,
• parametry przekazywane przez zmienne nieokreślonego typu.

Deklaracje tych parametrów mają postać odpowiednio:

lista_parametrów : identyfikator_typu

var lista_parametrów : identyfikator_typu
var lista_parametrów

Zamiast identyfikatora typu może wystąpić słowo klucowe string. Dla parametrów tego typu łańcuchowego nie jest
dozwolona specyfikacja długości łańcucha (przyjmuje się domyślnie, że długość ta wynosi 255).
Różnica pomiędzy procedurą i funkcją polega na sposobie przekazywania wartości określanej przez procedurę
(funkcję). Zadaniem procedury jest wykonanie pewnej sekwencji czynności, polegających zwykle na obliczeniu
jednej lub wielu wartości. Z identyfikatorem procedury związany jest adres, gdzie się ona znajduje. Natomiast
zadaniem funkcji jest obliczenie jednej wartości (typu prostego lub wskaźnikowego). Oprócz adresu posiada ona
również identyfikator informujący o wyznaczonej wartości. Odmienne są też sposoby wywołania procedur i
funkcji. Procedury wywołuje się przez nazwę (podając ewentualnie listę parametrów formalnych), funkcję zaś
podstawia się pod zmienną typu zgodnego z typem funkcji. W przypadku funkcji, w ciągu instrukcji musi wystąpić
przynajmniej jedna instrukcja przypisania postaci:

indentyfikator_funkcji := wyrażenie

6.3.1. Procedury i funkcje bezparametrowe

W przypadku procedur (funkcji) bezparametrowych, korzystają one ze zmiennych globalnych

zadeklarowanych w programie lub modułach. Stosowanie tego typu rozwiązań powoduje, że program staje się
czytelniejszy, jednak jest mało uniwersalny.

background image

- 4 -

Zastosowanie procedur i funkcji bezparametrowych przedstawmy dwóch przykładach.

Przykład 1.
Załóżmy, że naszym zadaniem jest wprowadzenie do programu dwóch macierzy A i B, obliczenie macierzy C

jako sumy A+B, a następnie wypisanie wartości wszystkich trzech macierzy na ekranie monitora. Realizujący
powyższy problem program może mieć następującą postać:

Wersja 1.

program procedury_bez_parametrow_formalnych;

uses Crt;
const maxW=10; maxK=5;
type macierz=Array[1..maxW,1..maxK] of Real;
var A,B,C:Macierz;

W,K:Word;

procedure czekaj;
var znak:Char;
begin

Write(' ... nacisnij dowolny klawisz ...');

znak:=Readkey

end;

procedure czytaj_WK;
var i,j:Word;
begin

Repeat

Write('Podaj liczbe wierszy (W<=',maxW,') W = ');

Readln(W);

Until W<=maxW;

Repeat

Write('Podaj liczbe kolumn (K<=',maxK,') K = ');

Readln(K);

Until K<=maxK;

end;

procedure czytaj_macierz_A;
var i,j:Word;
begin

Writeln('Wprowadz elementy macierzy A');

for i:=1 to W do

for j:=1 to K do

begin

Write('A[',i:2,',',j:2,'] = ');

Readln(A[i,j]);

end;

end;

procedure czytaj_macierz_B;
var i,j:Word;
begin

Writeln('Wprowadz elementy macierzy B');

for i:=1 to W do

for j:=1 to K do

begin

Write('B[',i:2,',',j:2,'] = ');

Readln(B[i,j]);

end;

end;

procedure dodaj;
var i,j:Word;
begin

for i:=1 to W do

for j:=1 to K do C[i,j]:=A[i,j]+B[i,j];

end;

procedure wypisz_A;
var i,j:Word;
begin

background image

.

- 5 -

Writeln(' Macierz A');

for i:=1 to W do

begin

for j:=1 to K do Write(A[i,j]:10:2);

Writeln;

end;

end;

procedure wypisz_B;
var i,j:Word;
begin

Writeln(' Macierz B');

for i:=1 to W do

begin

for j:=1 to K do Write(B[i,j]:10:2);

Writeln;

end;

end;

procedure wypisz_C;
var i,j:Word;
begin

Writeln(' Macierz C = A + B ');

for i:=1 to W do

begin

for j:=1 to K do Write(C[i,j]:10:2);

Writeln;

end;

end;

begin

czytaj_WK;

czytaj_macierz_A;

czytaj_macierz_B;

dodaj;

wypisz_A;

wypisz_B;

wypisz_C;

czekaj;

end.

Przykład 2.

Zadanie polega na napisaniu programu rozwiązującego równanie kwadratowe.
Problem ten można rozwiązać następująco:

Wersja 1.

program funkcje_bez_parametrow_formalnych;

uses Crt;

var a,b,c,delta:Real;

x1,x2:Real;

procedure czekaj;

var znak:Char;

begin

Write(' ... nacisnij dowolny klawisz ...');

znak:=Readkey;

end;

procedure dane;
begin

Writeln('Wprowadz parametry rownania kwadratowego');

Write('a = ');

Readln(a);

Write('b = ');

Readln(b);

Write('c = ');

Readln(c);

end;

procedure sprawdz;
begin

if delta < 0 then

background image

- 6 -

begin

Writeln(' Brak pierwiastkow rzeczywistych ');

czekaj;

halt;

end;

if a = 0 then

begin

Writeln(' To nie jest rownanie kwadratowe');;

czekaj;

halt;

end;

end;

function wartosc_delta:Real;
begin

wartosc_delta:=b*b-4*a*c;

Writeln('delta = ',(b*b-4*a*c):10:2);

end;

function pierwiastek_x1:Real;
begin

pierwiastek_x1:=-b-sqrt(delta)/(2*a);

end;

function pierwiastek_x2:Real;
begin

pierwiastek_x2:=-b+sqrt(delta)/(2*a);

end;

begin

dane;

delta:=wartosc_delta;

sprawdz;

x1:=pierwiastek_x1;

x2:=pierwiastek_x2;

Writeln(' x1 = ',x1:10:2);

Writeln(' x2 = ',x2:10:2);

czekaj;

end.

Z powyższych przykładów łatwo wyciągnąć wniosek, że programy te są bardzo mało uniwersalny. Procedury

wykonujące działania na macierzach operują na zmiennych globalnych, przez co są bardzo silnie związane z
programem. Ponadto, procedury czytające macierze z klawiatury oraz wypisujące wartości macierzy na ekranie są
dublowane. Podobna sytuacja występuje w przypadku drugiego przykładu.

6.3.2. Przekazywanie parametrów przez wartości
W wywołaniu procedury lub funkcji odpowiadający mu argument (parametr wywołania, parametr aktualny)

musi być wyrażeniem zgodnym w sensie przypisania z typem tego parametru. Parametry formalne przekazywane
przez wartość traktowane są jako zmienne lokalne. Ich wartość początkowa jest równa wartości argumentu
wywołania. Operacje wykonywane na nich nie powodują zmiany wartości parametrów aktualnych.

W przypadku przekazywania parametru przez wartość, na stosie dla zmiennych lokalnych tworzona jest kopia

wartości argumentu. Procedura lub funkcja otrzymuje tę kopię, natomiast program nie ma do niej dostępu. Po
wyjściu z procedury (funkcji) przechowywane w kopii wartości są tracone. Jeżeli parametr wywołania jest
wyrażeniem, wówczas w kopii na stosie dla zmiennych lokalnych przechowywana jest wartość tego wyrażenia,
obliczana podczas wywołania procedury (funkcji).

background image

.

- 7 -

stos dla zmiennych lokalnych

segment danych

kopia

blok kodu programu lub modułu

zmienna globalna

procedura

Korzystając z możliwości przekazywania parametrów przez wartość, zrealizujmy zadania postawione w

poprzednim punkcie.

Przykład 1 - wersja 2.

program procedury_z_parametami_przekazywanymi_przez_wartosc;

uses Crt;

const maxW=10;

maxK=5;

type macierz=Array[1..maxW,1..maxK] of Real;

var A,B,C:Macierz;

W,K:Word;

procedure czekaj;

var znak:Char;

begin

Write(' ... nacisnij dowolny klawisz ...');

znak:=Readkey;

end;

procedure czytaj_WK;
begin

Repeat

Write('Podaj liczbe wierszy(W<=',maxW,') W = ');

Readln(W);

Until W<=maxW;

Repeat

Write('Podaj liczbe kolumn (K<=',maxK,') K = ');

Readln(K);

Until K<=maxK;

end;

procedure czytaj_macierz_A;

var i,j:Word;

begin

Writeln('Wprowadz elementy macierzy A');

for i:=1 to W do

for j:=1 to K do

begin

Write('A[',i:2,',',j:2,'] = ');

Readln(A[i,j]);

end;

end;

procedure czytaj_macierz_B;

var i,j:Word;

begin

Writeln('Wprowadz elementy macierzy B');

for i:=1 to W do

for j:=1 to K do

begin

Write('B[',i:2,',',j:2,'] = ');

Readln(B[i,j]);

end;

end;

background image

- 8 -

procedure dodaj;

var i,j:Word;

begin

for i:=1 to W do

for j:=1 to K do C[i,j]:=A[i,j]+B[i,j];

end;

procedure wypisz(tablica:macierz;opis:String);

{parametry: tablica i opis przekazywane sa przez wartosc }

var i,j:Word;

begin

Writeln(opis);

for i:=1 to W do

begin

for j:=1 to K do Write(tablica[i,j]:10:2);

Writeln;

end;

end;

begin

czytaj_WK;

czytaj_macierz_A;

czytaj_macierz_B;

dodaj;

wypisz(A,'Macierz A');

wypisz(B,'Macierz B');

wypisz(C,'Macierz C= A +B');

czekaj;

end.

Przykład 2 - wersja 2.

program funkcje_a_parametrami_przekazywanymi_przez_wartosc;

uses Crt;

var a,b,c,delta:Real;

x1,x2:Real;

procedure czekaj;

var znak:Char;

begin

Write(' ... nacisnij dowolny klawisz ...');

znak:=Readkey;

end;

procedure dane;
begin

Writeln('Wprowadz parametry rownania kwadratowego');

Write('a = '); Readln(a);

Write('b = '); Readln(b);

Write('c = '); Readln(c);

end;

procedure sprawdz;
begin

if delta < 0 then

begin

Writeln(' Brak pierwiastkow rzeczywistych ');

czekaj;

halt;

end;

if a = 0 then

begin

Writeln(' To nie jest rownanie kwadratowe');;

czekaj;

halt;

end;

end;
function wartosc_delta(a,b,c:Real):Real;
begin

wartosc_delta:=b*b-4*a*c;

Writeln('delta = ',(b*b-4*a*c):10:2);

end;

background image

.

- 9 -

function pierwiastek(ktory:Byte):Real;
begin

if ktory=1

then pierwiastek:=-b-sqrt(delta)/(2*a)

else pierwiastek:=-b+sqrt(delta)/(2*a)

end;

begin

dane;

delta:=wartosc_delta(a,b,c);

sprawdz;

x1:=pierwiastek(1);

x2:=pierwiastek(2);

Writeln(' x1 = ',x1:10:2);

Writeln(' x2 = ',x2:10:2);

czekaj;

end.

6.3.3. Przekazywanie parametrów przez zmienne określonego typu
Argumenty odpowiadające parametrom przekazywanym przez zmienną określonego (lub nieokreślonego) typu

muszą być zmiennymi typu zgodnego z danym. Operacje wykonywane w treści procedury (funkcji) na parametrach
przekazywanych przez zmienną powodują po wywołaniu wykonanie operacji na odpowiadających im
argumentach, tj. na wielkościach zmiennych, nie kopiach. Dzięki temu uzyskujemy możliwość przekazywania
wyników. W tym przypadku procedura (funkcja) otrzymuje nie kopię a adres do oryginału zmiennej. Adres ten jest
umieszczany w segmencie stosowym i tracony po wyjściu z procedury (funkcji). Przez cały czas działania
procedury (funkcji) ma ona dostęp (przez adres) do oryginalnego parametru wywołania znajdującego się w
segmencie danych, gdzie są zgromadzone zmienne globalne. W tym czasie parametr ten może być on dowolnie

modyfikowany.

Po raz trzeci napiszmy program z przykładu 1, korzystając tym razem również z możliwości przekazywania
parametrów przez zmienne.

Przykład 1 - wersja 3.

program procedury_z_parametami_przekazywanymi_przez_zmienne;

uses Crt;

const maxW=10;

maxK=5;

type macierz=Array[1..maxW,1..maxK] of Real;

var A,B,C:Macierz;

W,K:Word;

procedure czekaj; { procedura bez parametrow formalnych }

var znak:Char;

begin

Write(' ... nacisnij dowolny klawisz ...');

znak:=Readkey;

stos dla zmiennych lokalnych

segment danych

adres

blok kodu programu lub modułu

zmienna globalna

procedura

background image

- 10 -

end;

procedure czytaj_WK(var N_wierszy,N_kolumn:Word);

{parametry N_wierszy i N_kolumn przekazywane sa przez zmienne }

begin

Repeat

Write('Podaj liczbe wierszy (W<=',maxW,') W = ');

Readln(N_wierszy);

Until N_wierszy<=maxW;

Repeat

Write('Podaj liczbe kolumn (K<=',maxK,') K = ');

Readln(N_kolumn);

Until N_kolumn<=maxK;

end;

procedure czytaj_macierz(var tablica:macierz;

oznaczenie:String);

{ parametr tablica jest przekazywany przez zmienna,

parametr oznaczenie - przez wartośc }

var i,j:Word;

begin

Writeln('Wprowadz elementy macierzy ',oznaczenie);

for i:=1 to W do

for j:=1 to K do

begin

Write(oznaczenie,'[',i:2,',',j:2,'] = ');

Readln(tablica[i,j]);

end;

end;

procedure dodaj(X,Y:Macierz;var Z:Macierz);

{ parametry X,Y przekazywane sa przez wartości,

parametr Z - przez zmienna }

var i,j:Word;

begin

for i:=1 to W do

for j:=1 to K do Z[i,j]:=X[i,j]+Y[i,j];

end;

procedure wypisz(tablica:macierz;opis:String);

{ parametry przekazywane sa przez wartości }

var i,j:Word;

begin

Writeln(opis);

for i:=1 to W do

begin

for j:=1 to K do Write(tablica[i,j]:10:2);

Writeln;

end;

end;

begin

czytaj_WK(W,K);

czytaj_macierz(A,'A');

czytaj_macierz(B,'B');

dodaj(A,B,C);

wypisz(A,'Macierz A');

wypisz(B,'Macierz B');

wypisz(C,'Macierz C= A +B');

czekaj;

end.

Zauważmy, że w powyższym przykładzie nie wszystkie parametry przekazywane są przez zmienne. Te

parametry, które wewnątrz procedur nie powinny ulec zmianie, przekazywane są przez wartości. Przez zmienne
przekazywane są parametry, które są wynikiem działania procedury.

Porównując program w którym nie stosowano parametrów formalnych z programem wykorzystującym różne

background image

.

- 11 -

możliwości przekazywania parametrów, widać zdecydowaną przewagę tego drugiego. Program jest nie tylko
znacznie krótszy, ale przede wszystkim bardziej uniwersalny.

6.3.4. Przekazywanie parametrów przez zmienne nieokreślonego typu

Ten sposób przekazywania parametrów stosuje się przede wszystkim w takich procedurach i funkcjach, które

przetwarzają struktury danych o róznych rozmiarach. Parametry nieokreślonego typu nie są zgodne (w treści
procedury lub funkcji) z żadnymi zmiennymi. Aby parametrom tym nadać odpowiednie typy, należy zastosować
konstrukcję postaci:

identyfikator_typu(odwołanie_do_zmiennej)

Zmienna do której następuje odwołanie może być zmienną całościową lub indeksowaną. Po zastosowaniu
powyższej konstrukcji zmienna będzie taraktowana tak jak zmienna typu określonego przez identyfikator typu.
Rozmiar zmiennej musi być przy tym zgodny z rozmiarem typu o podanym identyfikatorze.

Zastosowanie tego sposobu przekazywania parametrów przedstawmy na przykładzie procedury, której

zadaniem jest wczytanie elementów macierzy kwadratowej różnych stopni.

const N1=5; { stopien macierzy }

N2=10;

type macierz1= Array[1..n1,1..n1] of Real;

macierz2= Array[1..n2, 1..n2] of Real;

{ ... }

var A:macierz1;

B:macierz2;

procedure czytaj_macierz(N:Byte; var tablica; oznaczenie:String);

{ parametr tablica jest przekazywany przez zmienną nieokreślonego typu }

var i,j:Word;

begin

if N>10 then Writeln('Za duzy stopien macierzy')

else

begin

Writeln('Wprowadz elementy macierzy ',oznaczenie);

for i:=1 to N do

for j:=1 to N do

begin

Write(oznaczenie,'[',i:2,',',j:2,'] = ');

case N of

1..5 :

Readln(macierz1(tablica)[i,j]);

6..10:

Readln(macierz2(tablica)[i,j])

end;

end;

end; { else }

end;

begin

{...}

czytaj_macierz(5,A, 'macierz pierwsza');

czytaj_macierz(9,B, 'macierz druga');

{...}

end.

6.3.5 Podsumowanie
Niektóre przykłady mogą sugerować, że stosowanie procedur bezparametrowych jest niecelowe ze względu

na ewentualną konieczność wykonywania dodatkowych operacji przed i po ich wywołaniu. Najczęściej tak jednak
nie jest. Procedury (funkcje) bezparametrowe, wykorzystywane są często do wykonywania
niesparametryzowanych, powtarzających się operacji. W zasadzie w typowych programach stosowanie parametrów
w procedurach uzasadnione jest tylko dla wielkości, które będą się zmieniać przy kolejnych wywołaniach
procedur.

Uwaga ta nie dotyczy procedur i funkcji bibliotecznych, które tworzone są w celu późniejszego ich dołączania

do różnych programów. W tego typu procedurach i funkcjach parametry reprezentują przede wszystkim wielkości

background image

- 12 -

charakterystyczne dla danego algorytmu, chociaż w danym programie mogą być one wykorzystywane dla stałych
parametrów aktualnych (argumentów).

Na koniec jeszcze jedna praktyczna rada. Procedury i funkcje powinny być "zamknięte", to znaczy nie

powinny korzystać wprost ze zmiennych globalnych. Przenikanie zmiennych globalnych do procedur (funkcji)
znacznie utrudnia analizę programu oraz może prowadzić do nieprzewidzainych zmian wartości tych zmiennych.
Aby lepiej zrozumieć ten problem, proponuję samodzielnie rozwiązać poniższe zadanie, korzystając z kartki
papieru, po czym porównać odpowiedź z efektem działania programu.

program test;

uses crt;

{ Jaka bedzie postac ekranu monitora po wykonaniu programu ? }

var a,b:String;

function zero:String;

var b: String;

begin

b:='Tomasz';

zero:='Maria';

Writeln('funkcja zero : ',a,b);

end;

function jeden(var a:String; b:String):String;
begin

a:='Jan';

b:='Marcin';

jeden:='Ewa';

Writeln('funkcja jeden : ',a,b);

end;

procedure dwa;

var a :String;

begin

a:='Adam';

Writeln('procedura dwa : ',a,b);

end;

procedure trzy(a:String);
begin

Writeln('procedura trzy : ',a,b);

a:='Filip';

Writeln('procedura trzy : ',a,b);

end;

procedure cztery(var a:String);
begin

Writeln('procedura cztery : ',a,b);

a:='Mateusz';

Writeln('procedura cztery : ',a,b);

end;

begin

a:='Anna';

b:=zero;

b:=jeden(a,b);

Writeln(a,b);

dwa;

Writeln(a,b);

cztery(a);

Writeln(a,b);

trzy(a);

Writeln(a,b);

end.

6.3.6 Przykłady


Wyszukiwarka

Podobne podstrony:
LAB PROCEDURY I FUNKCJE
Procedury i funkcje
Procedury i funkcje trybu grafi Nieznany
procedury i funkcje
PAS procedury funkcje (2)
wykład 4 procedury, funkcje, sekwencje, paczki, wyzwalacze
STRING - Procedury i funkcje, Szkoła, Klasa 1, Programowanie struktularne i obiektowe
procedury i funkcje
06 Procedury i funkcje cwiczenia przygotowujace
6 TurboPascal Procedury i funkcje
PL SQL Procedury i funkcje składowane Politechnika Poznańska
LAB PROCEDURY I FUNKCJE
Procedury i funkcje
Procedury i funkcje trybu grafi Nieznany
widoki,procedury,funkcje
8 Procedury , funkcje

więcej podobnych podstron