Pascal 10 17, 1


  1. Podprogramy - funkcje

Stosowanie procedur i funkcji (podprogramów) umożliwia rozbicie złożonego ciągu operacji na mniejsze struktury. Zwiększa to czytelność programu, poprawia kontrolę nad rozbudowanym programem i umożliwia wielokrotne wykorzystanie bloków instrukcji ze zmienionymi danymi wejściowymi. Podprogramy mogą mieć strukturę hierarchiczną, a zatem kolejna procedura może być definiowana we "wnętrzu" innej.

Zadaniem funkcji jest obliczenie pojedynczej wartości zaś procedura wykonuje sekwencję działań i może wyprowadzać wiele obliczonych wartości.

Definicja procedury lub/i funkcji umieszczana jest w części deklaracyjnej programu głównego (także innej procedury lub funkcji):

function nazwa (lista parametrów formalnych): typ prosty;

definicje, deklaracje

begin

....

nazwa := wyrażenie;

....

end;

W nagłówku definicji muszą się znaleźć parametry przekazywane do wnętrza funkcji z określeniem ich typów (elementy listy oddzielane są średnikami) oraz typ funkcji (prosty).

Funkcja zapewnia w zasadzie zwrot pojedynczej wartości poprzez jej nazwę (obiekt określonego typu prostego), chociaż można również stosować przekazanie przez zmienną (jak w procedurze, patrz następne ćwiczenie). W bloku wykonawczym funkcji musi zatem znaleźć się instrukcja dokonująca nadanie wartości funkcji (np. instrukcja przypisania dla nazwy funkcji).

Przykładowe nagłówki deklaracji funkcji:

function suma (x1, x2: real):real;

function sprawdzaj(x1, x2: real; y1, y2: integer ):boolean;

Wykonanie (wywołanie) funkcji odbywa się w wyrażeniu odpowiedniego typu (także w procedurze wyprowadzenia write(ln)). Parametry wywołania, zwane parametrami aktualnymi, mogą być stałymi, zmiennymi lub wyrażeniami, oddzielane są przecinkami. Liczba i typ parametrów aktualnych musi być zgodna z deklaracją funkcji

Przykładowy program ilustruje możliwe sposoby wywołania funkcji:

program p10_1;

var a, b,c :real;

{definicja funkcji}

function iloczyn (x1, x2: real): real;

begin

iloczyn := x1*x2; {nadanie wartości funkcji}

end; {koniec definicji funkcji}

begin {program główny}

a := 3.4;

b := 5.6;

writeln (iloczyn( a, b ) ); {użycie funkcji jako parametru instrukcji writeln}

c := 3 iloczyn (a, b);

writeln (c:10:5);

c := 2 iloczyn (b, 1- a)/iloczyn (a, 2*b +1); {użycie funkcji w wyrażeniu}

writeln( c:10:5);

c := 1/iloczyn (c-1, a);

writeln( c:10:5);

end.

Wywołanie (wykonanie) funkcji w programie dokonywane jest zatem tak jak użycie zmiennej (podobnie jak funkcje standardowe). Wartości parametrów aktualnych (lub obliczonych wyrażeń) przekazywane są do funkcji (kopiowane na parametry formalne), następnie wykonywane są instrukcje w ciele funkcji i wartość obliczona zwracana jest pod nazwą funkcji do miejsca wywołania.

Poniższy program tabelaryzuje wartości funkcji opisanej przedziałami, w 21 punktach zakresu (0.0, 2.0):

program p10_2;

uses crt;

var i: 0..20;

function fun(x: real): real; {definicja funkcji}

var xkw: real;

begin

xkw := xx;

if x := 0.5 then fun := 0.2xkw-x+0.1

else fun := xkw/(xkw-0.1)

end; {koniec definicji funkcji}

begin {początek programu głównego}

clrscr;

writeln;

writeln ('Tabela wartosci funkcji':45);

writeln;

writeln ('x':30, 'f(x)':20);

for i := 0 to 20 do

begin

writeln(i:12, i0.1:20:3, fun(i0.1):20:5)

end;

repeat until keypressed

end .

Ćwiczenie

  1. Wykonać programy przykładowe p10_1, p10_2. Przeanalizować postać deklaracji funkcji, cel jej stosowania, postaci instrukcji wykorzystującej funkcje.

  2. Wykonywać program krokowo (Trace into) obserwując przejście do bloku funkcji w momencie napotkania wywołania funkcji. W oknie Watch obserwować wartości zmiennych i moment nadania wartości zmiennej reprezentującej funkcję.

  3. Napisać program zawierający deklarację funkcji określonej jako:

f(x) = -x +2 dla x<0

f(x) = x - 2 dla x>=0

Program główny wyznacza i wyprowadza na ekran wartości funkcji dla x = -5, -2, 1, 4.5 i 6.34.

  1. Zmodyfikować poprzedni program tak, aby funkcja była wykorzystywana w iteracji wyprowadzającej wartości w 20 punktach z przedziału (-5.0; 5.0).

  2. Sporządzić program, którego zadaniem będzie wykorzystanie funkcji typu logicznego sprawdzającej czy dwie wprowadzone wartości typu całkowitego są sobie równe.


  1. Podprogramy - procedury

Procedury mogą wykonać sekwencję działań na wartościach wprowadzonych do jej wnętrza i wyprowadzać wiele obliczonych wartości.

Definicja procedury podobnie jak funkcji umieszczana jest w części deklaracyjnej programu głównego (także innej procedury lub funkcji):

procedure nazwa (parametry formalne);

definicje, deklaracje

begin

....

instrukcje

....

end;

Parametry formalne służą do przekazywania danych pomiędzy blokiem, w którym wykonywana jest procedura, a samą procedurą. Niektóre z nich przekazują dane wejściowe do funkcji lub procedury, inne mogą zwrócić wyliczone w podprogramie wartości do programu głównego lub nadrzędnego podprogramu. Deklaracje parametrów są oddzielane średnikami, każda deklaracja składa się z listy zmiennych i nazwy typu.

Przykładowe nagłówki deklaracji procedury :

procedure drukuj (x1, x2: real);

procedure suma (liczba1, liczba2: real; var wynik: real);

Poprzedzające listę słowo kluczowe var określa przekazanie danych przez zmienną, jego brak przekazanie danych przez wartość. Przekazanie przez wartość stosuje się w celu wniesienia danych wejściowych do podprogramu, natomiast przekazanie przez zmienną ma na celu zwrot wyników działania procedury lub funkcji do miejsca wywołania.

Przekazanie przez wartość traktowane jest jako nadanie wartości początkowej zmiennej lokalnej, w momencie zakończenia podprogramu parametr formalny przestaje istnieć, wartość argumentu nie zostaje zmieniona.

Przekazanie przez zmienną może przenieść wartość do procedury (wejście), po jej zakończeniu powoduje zwrot nowej wartości do programu wywołującego procedurę.

Wykonanie procedury jest odrębną instrukcją. Parametry aktualne odpowiadające pozycji wywołania przez wartość mogą być stałymi, zmiennymi lub wyrażeniami, natomiast parametry aktualne odpowiadające przekazaniu przez zmienną muszą być identyfikatorami (naz­wami) zmiennych.

program p11_1;

var a, b, c :real;

procedure suma (liczba1, liczba2: real; var wynik: real);

begin

wynik := liczba1 + liczba2;

end;

begin {początek programu głównego}

a := 2;

b := 2;

{przykładowe wykonania procedury}

suma (6.7, 2*a, c); {trzeci parametr aktualny musi być zmienną}

suma (a , b , c);

suma (c , c , c);

suma (c, b , a)

end.

Zasięg deklaracji zmiennych

Deklaracje obiektów w programie głównym zwane są globalnymi, "widoczne" są w całym programie, także i w podprogramach (czasami mogą być tam "przesłonięte" czyli ponownie deklarowane. Deklaracje obiektów w definicji podprogramu to deklaracje lokalne dla podprogramu, nie będą "widoczne" w programie wywołującym. Jeśli w ciele definicji podprogramu jest deklaracja zagnieżdżonego podprogramu to obiekty lokalne stają się dla niego zewnętrznymi.

Zasięg deklaracji ilustruje poniższy rysunek:

0x08 graphic

deklaracje globalne widoczne w całym programie (chyba że przesłonięte w B, C lub D)

deklaracje lokalne w B (zewnętrzne dla C)

deklaracje lokalne w C (deklaracje A i B można prze­słaniać)

tu można wykorzystać procedurę C

deklaracje lokalne w D (deklaracje A można przesłaniać, procedura C niewidoczna)

blok główny programu, tu można wywołać procedury B i  D lecz nie procedurę C

Rys 11.1 Zasięg deklaracji w Turbo Pascalu.

Ćwiczenie

  1. W przykładzie p11_1 zastanowić się nad działaniem poszczególnych instrukcji wywołujących procedurę. Przewidzieć rezultaty kolejnych wykonań procedury, w razie potrzeby wzbogacić program w wydruki kontrolne, sprawdzające przewidywane wartości parametrów wyprowadzonych przez zmienną.

  2. Napisać program zawierający deklarację procedury obliczającej iloczyn dwóch zmiennych zespolonych, określonej jako:

(a + jb)(c+jd) = ac - bd + j (ad + bd)

Zastosować zmienną typu rekordowego o strukturze:

var zesp= record

re, im :real;

end;

W programie głównym wykonać obliczenia iloczynu dowolnych dwóch liczb zespolonych.

  1. Napisać program, którego zadaniem będzie utworzenie niewielkiej tablicy jednowymiarowej zawierającej liczby rzeczywiste oraz zdefiniowanie i wykorzystanie procedury znajdującej w tablicy element o maksymalnej wartości.

Zadanie domowe:

Przygotować na dyskietce kod programów przykładowych następnego ćwiczenia


  1. Pliki

    1. Typ plikowy

Plik w pojęciu Turbo Pascala jest ciągiem elementów tego samego typu, odwzorowującym fizyczny zbiór danych gromadzonych w pliku umieszczonym w pamięci zewnętrznej. Dostęp do pliku jest sekwencyjny, tzn. po otwarciu pliku dostępny jest pierwszy element, zaś inne elementy mogą być udostępniane tylko po wykonaniu pewnych operacji (czytanie kolejnych elementów, przesunięcie pozycji czytania).

Aby uzyskać dostęp do pliku fizycznego należy zadeklarować w programie zmienną typu plikowego, którą trzeba skojarzyć z plikiem dyskowym. Zmienną tę można kojarzyć kolejno z różnymi plikami.

Plik może mieć dowolny typ składowych (oprócz typu plikowego).

Definicja typu plikowego ma postać:

type nazwa = file of typ; plik elementowy (zdefiniowany)

type nazwa = file; plik blokowy (niezdefiniowany)

type nazwa = text; plik tekstowy (predefiniowany)

Przykład użycia pliku elementowego:

type

osoba = record

nazw: string[30];

imie: string[30]

end;

grupa = file of osoba; {typ plikowy}

var

student: osoba;

gr1, gr2, gr3: grupa; {zmienne typu plikowego}

begin

...

end.

Dla całościowych zmiennych plikowych możliwe są jedynie niektóre operacje systemu plików, natomiast na składowych możemy wykonywać operacje w zależności od typu składowych.

W pliku elementowym zapis dokonuje się w postaci binarnej, a w tekstowym nawet elementy liczbowe zapisywane są jako tekst.

Obsługa plików wymaga:

 opisu zmiennej plikowej w części deklaracyjnej,

 skojarzenia zmiennej plikowej z plikiem fizycznym,

 otwarcia pliku (do zapisu lub do odczytu),

 wykonania niezbędnych operacji (czytanie, zapis i inne),

 zamknięcia pliku.

    1. Operacje plikowe

W poniższej tabeli przedstawiono podstawowe operacje plikowe, w których użyto określeń:

f - nazwa zmiennej typu plikowego,

Wt - wyrażenie tekstowe,

W - wyrażenie odpowiedniego typu,

Z - nazwa zmiennej.

TABELA 12.1. Podstawowe operacje plikowe

Operacja

Typ

Zapis

Przykład

skojarzenie

procedura

assign (f , Wt)

assign(p1,'C:\DANE\gr.dt');

otwarcie do odczytu i odczytu (istniejący plik)

procedura

reset (f);

reset (p1);

otwarcie do zapisu (nowy plik)

procedura

rewrite (f);

rewrite (p2);

dopisanie (na końcu pliku tekstowego )

procedura

append (f);

append (p2);

zamknięcie pliku

procedura

close (f);

close (p3);

detekcja końca pliku

funkcja logiczna

eof (f)

if eof (p1)= true then ...

if eof (p1) then ...

while not eof(gr1) do...

odczyt

procedura

read (f,Z1,..,Zn);

read (gr1, student.nazw);

zapis

procedura

write(f, W);

write (gr2, nazwisko);

Uwagi: