06 Rekurencja

background image

Wstęp

do programowania

Wykład

6 – rekurencja

background image

Zmienne globalne i lokalne

Można zdefiniować pewne zmienne,

które będą widoczne we wszystkich

funkcjach danego programu – są to tzw

zmienne globalne

Wewnątrz funkcji można definiować

zmienne, które są

zmiennymi lokalnymi

tej funkcji

background image

Nazwa zadeklarowana na zewnątrz wszystkich funkcji

ma zasięg globalny, czyli jest dostępna wewnątrz

wszystkich funkcji umieszczonych w danym pliku

Nazwa jest widziana dopiero poniżej linii w której została

zadeklarowana

Zmienna lokalna danej funkcji jest widoczna tylko w

tej funkcji w której została zadeklarowana

Nie można zatem w jednej funkcji odwołać się do

zmiennej lokalnej innej funkcji...

Dwie funkcje mogą mieć zmienne lokalne o takich

samych nazwach

Nazwy zmiennych lokalnych i globalnych mogą być

jednakowe (zmienne lokalne przysłaniają zmienne

globalne)

background image

•Jeśli w obrębie funkcji definiujemy jakieś zmienne,

to są one zazwyczaj pamiętane na tzw.

stosie

(czyli

w obszarze „podręcznym”).

Zmienne globalne są pamiętane w „normalnym”

obszarze pamięci

„Normalny” obszar pamięci przed uruchomieniem

programu jest zerowany. Niezainicjalizowana zmienna

globalna ma zatem na początku wartość 0 (odpowiednią

dla danego typu)

Zmienne podręczne nie są zerowane przy „powoływaniu

do życia”. Mają wartość losową

background image

Po zakończeniu bloku, w którym została powołana do życia

zmienna lokalna, przestaje ona istnieć.

•Przy ponownym wejściu do danego bloku – np. ponownym

wywołaniu tej samej funkcji – zmienna jest powołana do

życia po raz kolejny

•oczywiście przerwanie wykonywania jednej funkcji przez

wywołanie innej nie powoduje zlikwidowania zmiennych

pierwszej funkcji znajdujących się na stosie

background image

program zmienne_globalne1;
{$APPTYPE CONSOLE} {$O-,Q+,R+}
uses SysUtils;
var a,zm_globalna :integer;
Function efekt_ub:integer;
Var a,zm_lok :Integer;
Begin

a:=2; writeln('a=' ,a);
zm_globalna:=5;
zm_lok:=1;
result:=zm_globalna;

end;

var b:byte;

begin

zm_globalna:=1;
a:=10;
writeln(efekt_ub);
writeln(zm_globalna, 'a= ',a ); //5
zm_globalna:=8;
writeln(efekt_ub);
writeln(zm_globalna ); //5

readln;
END.

background image

program z1;

{$APPTYPE CONSOLE} {$O-,Q+,R+}
uses SysUtils;

var x :integer;

function zad1(a:integer; var b:integer):integer;

function wew1(c,d :integer):integer;

begin

d:=c+d;
wew1:=d+x;

//Result:=d+x;

end;

begin

a:=a+b;
b:=a+b;
Result:=wew1(a,b);

//zad1:=wew1(a,b);

end;
BEGIN

x:=2;
writeln(zad1(x,x));

//z=16 x=6

writeln(zad1(x,x));

//z=48

writeln(x); readln;

//x=18

END.

background image

Funkcje rekurencyjne

Rekurencja polega na tym że funkcja może

wywoływać samą siebie.

Może to robić każda funkcja, tyle że jeśli nie ma w niej

warunku zatrzymującego rekurencję, to funkcja będzie się

wywoływała się w nieskończoność, tzn. aż do wyczerpania

pamięci

Gdy funkcja rekurencyjna wywołuje samą siebie, na

stosie są już zmienne lokalne będące własnością

pierwszego wywołania tej funkcji.

Kolejne jej wywołanie umieszcza na stosie swoje własne

zmienne lokalne

background image

Procedura rekurencja

Program procedura_rek;

{$APPTYPE CONSOLE} {$O-,Q+,R+}
uses SysUtils;
var k : integer;

procedure inkrementacja ( x : integer);
begin

x:= x+1;

if x < 4 then inkrementacja(x)

else writeln(' Koniec wywoływania rekursyjnego dla x = ',x);

writeln('Jestem ostatnim poleceniem na poziomie ',x);

end;
begin

k:=0;
inkrementacja (k);

Readln;
end.
__________________________________________________________

background image

Funkcje rekurencyjne

program silnia_rekurencyjna;

{$APPTYPE CONSOLE} {$O-,Q+,R+}
uses SysUtils;

function Rsilnia(liczba:integer):Cardinal;
begin

if liczba=0 then Rsilnia:=1

else Rsilnia:=liczba*Rsilnia(liczba-1)

end;
Var n: byte;

Begin
writeln('Podan n');
readln(n);

writeln (' n! = ', Rsilnia(n)); // writeln (' 4! = ‘, Rsilnia(4));

Readln;
end.

background image

Funkcje rekurencyjne

program NWPrekur;
{$APPTYPE CONSOLE}
uses SysUtils;

function NWP(a, b :cardinal) :cardinal;
begin

if b = 0 then

Result := a

else

Result := NWP(b, a mod b);

end;

begin

writeln(NWP(18,24));
readln;

end.

program NWPnierekur;
{$APPTYPE CONSOLE}
uses SysUtils;

function NWP(a, b :cardinal) :cardinal;
var

r :cardinal;

begin

while b <> 0 do
begin

r := a mod b;
a := b;
b := r;

end;
Result := a;

end;

begin

writeln(NWP(18,24));
readln;

end.

background image

Rekurencja

program FibRekur;
{$APPTYPE CONSOLE} {$O-,Q+,R+}

Uses SysUtils;
// F_0=0 F_1=1 F_k = F_k-1+F_k-2
function Fib(k :cardinal) :cardinal;
begin

if k <= 1 then

Result := k

else

Result := Fib(k-1)+Fib(k-2);

end;

Var i :Integer;
Begin //writeln(Fib(10));

for i := 0 to 40 do

writeln(i:4,': ',Fib(i));

readln;

end.

program FibNieRekur;
{$APPTYPE CONSOLE} {$O-,Q+,R+}
uses SysUtils;
function Fib(k :cardinal) :cardinal;
Var i, F_k_1, F_k_2 :cardinal;
begin

Result := k;
if k > 1 then begin

F_k_1 := 1; F_k_2 := 0;
for i := 2 to k do
begin

Result := F_k_1 + F_k_2;
F_k_2 := F_k_1;
F_k_1 := Result;

end;

end;

end;
Var i :Integer;
begin
for i := 0 to 40 do writeln(i:4,': ',Fib(i));

readln; end.

background image

Rekurencja

Dany jest pewien ciąg rekurencyjny q:

q0 = 1,

q1 = 2

qn = (qn-1-qn-2)*qn-2

Należy zaprojektować algorytm funkcji rekurencyjnej obliczający wartość
dowolnego wyrazu ciągu. Rozwizanie - rekurencja :

Wśród wyrazów ciągu q, zgodnie z def., możemy wyróżnić trzy grupy:

- wyraz q0,

- wyraz q1,

-

pozostałe wyrazy qn.

Taki podział pozwala skonstruować warunki stopu. W przypadku dwóch

pierwszych wyrazów, wartość jest znana, więc należy wyliczyć wyraz q0
albo q1

i podać jako wynik odpowiednio 1 i 2.

W przypadku następnych wyrazów należy wyliczy , wartość ze

wzoru na qn.

background image

Rekurencja

Algorytm zapisany w postaci listy krok

ów wygląda następująco

( n jest parametrem formalnym i oznacza indeks wyrazu ci

ągu do

wyliczenia):

Krok 1: Je

śli n=0 to zwróć wynik 1, w przeciwnym razie,

Krok 2: Je

śli n=1 to zwróć wynik 2, w przeciwnym razie,

Krok 3: Jako wynik działania zwr

óć wartość :

((Wywołaj funkcje dla n-1)-(Wywołaj funkcje dla n- 2))*(Wywołaj funkcje dla n-2),

Krok 4:

Zakończ działanie.

background image

Rekurencja

program Rek_ciag;
{$APPTYPE CONSOLE} {$O-,Q+,R+}
Uses SysUtils;

function ciag(n :integer) :integer;
begin

if n = 0 then ciag:=1

else

if n=1 then ciag:=2

else ciag:=(ciag(n-1)-ciag(n-2))*ciag(n-2);

end;

Var n :integer;
Begin

write('Podaj n='); readln(n);
writeln(n,' _ty wyraz ciagu q= ',ciag(n));

readln;

end.

background image

Rekurencja

Nale

ży opracować rekurencyjny algorytm odwracania ciągu liter

(jeden z parametr

ów formalnych typu string).

Algorytm rekurencyjny będzie
działał na następujących zasadach:

• Warunkiem stopu będzie
napotkanie końca wyrażenia,

• Dla każdego kolejnego znaku
odwrócenia dokonujemy wywołując
funkcje dla pozostałej części ciągu
i dodając do niej aktualny element
na koniec,

•Jeśli osiągniemy koniec ciągu
należy, jako wynik zwracamy ciąg
pusty ‘’.

background image

Rekurencja

program Rek_odwracanie;
{$APPTYPE CONSOLE} {$O-,Q+,R+}
Uses SysUtils;

function rewers(indeks :integer; tekst :string):string;
begin

if indeks <= length(tekst) then

rewers := rewers(indeks+1,tekst) + tekst[indeks]

else rewers := '';

end;

var tekst :string;

i:integer;

Begin
//atak, rak, arak, Napis, Hetman, ??

write('Podaj tekst='); readln(tekst);
writeln(rewers(i,tekst));

readln;

end.

background image

Typ proceduralny

Typ proceduralny deklarowany słowami kluczowymi Type oraz

procedur lub function stworzony został aby traktować

procedury lub funkcje jako wartości pewnych zmiennych.

W przykladzie wartość zmiennej typu proceduralnego

„mFunkcja” staje się odpowiednią funkcją realizującą

odpowiednie zadania wybrane przez użytkownika.

Typy i zmienne proceduralne można również definiować w

sekcji deklaracji zmiennych np.
Var mojaFunkcja: function (a,b:byte):real;

background image

program PTYP_procedur2;

{$APPTYPE CONSOLE}

uses SysUtils;

type

Tfunkcja=function(a,b:integer):real;

function

dodaj(skladnik1,skladnik2:integer):real;

begin

result:=skladnik1+skladnik2;

end;

function odejmij(sklad1,sklad2:integer):real;

begin

result:=sklad1-sklad2;

end;

function pomnoz(czynnik1,

czynnik2:integer):real;

begin

result:=czynnik1*czynnik2;

end;

function podziel(dzielna,dzielnik:integer):real;

begin

if dzielnik<>0 then result:=dzielna/dzielnik;

end;

var

mFunkcja:Tfunkcja;

x1,x2:integer;

zn:char;

begin

writeln('Podaj dwie liczby');

readln(x1,x2);

writeln('wybierz dzialanie: +

dodawanie, - odejmownie, * mnozenie,

/ dzielenie');

repeat

Readln(zn);

until zn in ['+','-','*','/'];

case zn of

'+':mFunkcja:=dodaj;

'-':mFunkcja:=odejmij;

'*':mFunkcja:=pomnoz;

'/':mFunkcja:=podziel;

end;

writeln('wynik wynosi: ‘ ,

mfunkcja(x1,x2));

readln;

end.

background image

Procedury kierujace działaniem programu :

exit, halt, abort, sleep, runerror

Exit

– procedura ta służy do przerwania bieżącego podprogramu

(procedury lub funkcji) i powrotu do programu głównego. Jeśli wywołana

Jest z programu głównego to kończy jego działanie.

Halt

– Procedura ta kończy działanie programu przekazując sterowanie

do systemu operacyjnego. Procedura halt może być wywolana

bez parametru lub z jednym typu integer, którego wartość jest zwracana

Systemowi operacyjnemu jako kod wyjścia. (kod zero = jeśli brak

Parametru)

Runerror

– procedura wywoływana bez parametów lub jednym typu

Byte przerywa działanie programu zwracają kod błedu wykonywania

Programu (run-time-error) (kod zero = jeśli brak Parametru)

background image

Procedury kierujace działaniem programu :

exit, halt, abort, sleep, runerror

Sleep

- procedura wywoływana z jednym parametrem typu cardinal

Powoduje zatrzymanie programu na liczbę milisekund równą wartości

Podanego parametru

Abort - procedura wywołana bez parametru kończy działanie programu

Z wywołaniem wyjątku „Eabort” (o tym póżniej)

@ - OPERATOR ten zwraca wskaźnik do zmiennej funkcji, procedury

Lub metody dla której jest wywołany. Efektem jest stworzenia

Wskaźnika do zmiennej na której wykonano operację.

background image

program Pr_exit;

{$APPTYPE CONSOLE}

uses SysUtils;

var i:byte;

procedure zewnetrzna;

procedure wewnetrzna;

begin

writeln('To napisala procedura

wewnetrzna');

exit;

writeln('a tego nigdy nie zobaczymy');

end;

begin

writeln('To napisala procedura zewnetrzna');

wewnetrzna;

//tu wyw. procedure wewnetrzna

writeln('ten napis sie pojawi, kiedy wewnetrzna

przekaze sterowanie do zewnetrznej');

exit;

writeln('A ten napis juz sie nie pojawi');

end;

begin

writeln('wywolujemy procedure

zewnetrzna');

zewnetrzna;

readln;

exit;

writeln('ten napis tez sie nie pojawi');

readln;

end.

background image

program Pr_sleep_halt;

{$APPTYPE CONSOLE}

uses SysUtils;

var

s:string;

i:byte;

begin

s:='Dziala opoznienie- (sleep)';

for i:=1 to length(s)

do

begin

write(s[i]);

sleep(400);

end;

readln;

writeln ('a teraz zadziała procedura Halt za 5 sekund');

sleep(5000);

Halt;

Writeln('Tego napisu nie zobaczymy')

end.

background image

program PR_operator_wsk;

{$APPTYPE CONSOLE}

uses SysUtils;

type Ttablica=array[1..10] of byte;

var MojaTablica:Ttablica;

WskaznikNaLiczbe:^byte;

i:byte;

begin

for i:=1 to 10 do MojaTablica[i]:=100-i;

//tablica zostaje wypełniona liczbami od 99 do 90

WskaznikNaLiczbe:=@MojaTablica[1];

//Zmienna wskazujaca zostaje ustawiona na pierwszy element tablicy

inc(WskaznikNaLiczbe);

//wskaznik zostaje zwiekszony

//UWAGA:

zwiekszony zostaje adres, na ktory wskazuje wskaznik

//a nie wartosc zmiennej wskazywanej.

//Wskaznik wskazuje teraz na drugi element tablicy

writeln(wskazniknaliczbe^);

//W drugim elemencie tablicy jest zapisana liczba 100-2=98

readln;

end.


Wyszukiwarka

Podobne podstrony:
MT st w 06
Kosci, kregoslup 28[1][1][1] 10 06 dla studentow
06 Kwestia potencjalności Aid 6191 ppt
06 Podstawy syntezy polimerówid 6357 ppt
06
06 Psych zaburz z somatoformiczne i dysocjacyjne
GbpUsd analysis for July 06 Part 1
Probl inter i kard 06'03
06 K6Z4
06 pamięć proceduralna schematy, skrypty, ramyid 6150 ppt
Sys Inf 03 Manning w 06
Ustawa z dnia 25 06 1999 r o świadcz pien z ubezp społ w razie choroby i macierz

więcej podobnych podstron