Zmienne i parametry


Lekcja 14

Stosowanie zmiennych nielokalnych
i parametrów w programach

Wiemy, że program w Logo składa się z procedur. W przypadku złożonych programów, składających się z wielu procedur, w których stosujemy zmienne i parametry, bardzo ważne jest, w jaki sposób argumenty poszczególnych procedur przekazywane są z jednej procedury do drugiej. W ogólnym przypadku w logo możliwa jest dwukierunkowa komunikacja między procedurami za pomocą zmiennych. W tym miejscu zajmiemy się przekazywaniem argumentów do procedury wywoływanej (podrzędnej) z procedury wywołującej, (czyli tylko w jedną stronę). Mianowicie argumenty do procedury wywoływanej możemy przekazać na dwa sposoby:

  • za pomocą zmiennych nielokalnych względem tej procedury,
  • za pomocą parametrów.

Omówimy je kolejno.

Przekazywanie argumentów za pomocą zmiennych nielokalnych względem procedury wywoływanej

Wprowadzając zmienne powiedzieliśmy, że zmienne lokalne dostępne są w procedurze, w której zostały utworzone oraz wszystkich procedurach wywoływanych z tej procedury (zasięg zmiennej) za wyjątkiem procedur, w których zadeklarowano zmienne lokalne o takiej samej nazwie. Inaczej mówiąc, każda zmienna jest scharakteryzowana przez swój zasięg, czyli fragment programu, w którym dostępna jest jej wartość. Wyjaśnimy na przykładach, na czym idea ta polega. Weźmy procedury:

oto rozeta

(lokalna "zwrot "bok)

przyp "bok 50

przyp "zwrot 360 / 7

powtórz 7 [ trójkąt ugp 2 ukp 0 np :bok pw :zwrot]

już

oto trójkąt

ukp 4 ugp 0

powtórz 3 [np :bok lw 120]

już

Zadanie 1

Przepisz powyższe procedury i sprawdź ich działanie.

Po wykonaniu procedury rozeta otrzymamy rysunek:

W diagramie, oprócz wywołania procedur, podane są deklaracje zmiennych i przypisanie im wartości. Widzimy, że w procedurze trójkąt została użyta zmienna bok, której w tej procedurze nie zadeklarowano i nie określono. Mimo to został narysowany trójkąt o takiej samej długości boku jak długość boku siedmiokąta określona w procedurze nadrzędnej. Oznacza to, że zmienna bok z procedury rozeta (nadrzędnej) jest dostępna w procedurze trójkąt (podrzędnej).

W ogólnym przypadku zmienne zadeklarowane w procedurze wywołującej (nadrzędnej) są widoczne (dostępne) w procedurze wywoływanej (podrzędnej).

Zmienne lokalne dla procedury wywołującej są zmiennymi nielokalnymi dla procedury wywoływanej i są w niej widoczne (zmienne globalne, możemy także zdefiniować jako zmienne, które nie są lokalne dla żadnej procedury).

Widzimy, że za pomocą zmiennych nielokalnych względem procedury wywoływanej, możemy przekazywać dane do wywoływanej procedury. Wprowadzając wówczas w programie zmienne (reprezentujące odpowiednie dane) bierzemy pod uwagę czy zmienna jest potrzebna w jednej procedurze czy w kilku procedurach.

Jeżeli zmienna jest wykorzystywana tylko w jednej procedurze powinna zostać zadeklarowana jako zmienna lokalna w tej procedurze. Natomiast, gdy zmienna jest wykorzystywana w wielu procedurach, deklarujemy ją jako zmienną lokalną w procedurze nadrzędnej dla wszystkich procedur, w których jest wykorzystywana. Zmienna będzie wówczas dostępna we wszystkich procedurach podrzędnych.

W ogólnym przypadku stosowanie zmiennych nielokalnych (także zmiennych globalnych) do komunikacji między procedurami nie jest zalecane. Istnieją dwie przyczyny, dla których w procedurach podrzędnych unikamy stosowania zmiennych nielokalnych, mimo, że są w nich dostępne.

Pierwsza z nich polega na tym, że zmienna nielokalna tego typu, może być zmieniana wewnątrz procedury podrzędnej i zmiany te będą przekazywane do innych procedur. W ogólnym przypadku zmiana wartości zmiennej nielokalnej w procedurze jest niepożądana ze względu na możliwość popełnienia błędu. Trudno jest wtedy przetestować taki program, wykryć i usunąć błąd.

Druga przyczyna polega na tym, że procedury działające na wielkościach nielokalnych nie dadzą się przenieść wprost do innego programu. Z przedstawionych przyczyn stosuje się do komunikacji między procedurami parametry formalne, czyli przekazywanie argumentu przez wartość.

Przekazywanie argumentu za pomocą parametrów

W poprzednim punkcie powiedzieliśmy, że zmienne zadeklarowane w procedurze wywołującej są widoczne w procedurze wywoływanej. Jednak nie zawsze tak jest. W wypadku, gdy w procedurze wywoływanej zadeklarowane są zmienne lokalne o takich samych nazwach jak w procedurze wywoływanej to zachodzi tzw. zasłanianie zmiennych. Innymi słowy, w takim przypadku w procedurze wywoływanej jest dostępna wartość zmiennej lokalnej w niej zadeklarowanej. Ideę zasłaniania zmiennych wyjaśnimy na przykładzie z poprzedniego punktu.

Co się stanie, gdy w procedurze trójkąt zadeklarujemy zmienną bok i przypiszemy jej wartość inną niż wartość tak samo nazwanej zmiennej w procedurze rozeta?. Zdefiniujmy, więc procedurę:

oto trójkąt_b

lokalna "bok

przyp "bok 40

ukp 4 ugp 0

powtórz 3 [np :bok lw 120]

już

Po zapisaniu procedury Rozeta pod nazwą Rozeta_b i zastąpieniu w niej wywołania procedury trójkąt przez wywołanie procedury trójkąt_b otrzymamy rysunek jak poniżej:

Zadanie 2

Przepisz powyższe procedury i sprawdź ich działanie.

W diagramie, oprócz wywołania procedur, podane są deklaracje zmiennych i przypisanie im wartości. Widzimy, że w obydwu procedurach zmienna bok ma taką samą nazwę, ale inną wartość. Na rysunku wyraźnie widać, że zmienne w procedurze wewnętrznej przesłaniają tak samo nazwane zmienne w procedurze zewnętrznej. Narysowane są figury o różnej długości boków (długości boku trójkąta i siedmiokąta są różne - zmienna bok).

Zasłaniane zmiennych stoi u źródeł przekazywania danych do procedury podrzędnej za pomocą parametrów tzn. poprzez wartość zmiennej. Wartości zmiennych przekazuje się do procedury przypisując je odpowiednim parametrom formalnym procedury.

Przekazywanie argumentów przez wartość polega, więc na przekopiowaniu wartości argumentu do parametru formalnego procedury. Wartość przekazywanego argumentu w wyniku działania procedury nie zmienia się. W procedurze podrzędnej zostanie utworzona zmienna lokalna zawierająca jego kopię i wszystkie operacje wykonywane są na tej kopii wewnątrz procedury. Procedury, które korzystają z parametrów formalnych i wielkości lokalnych są łatwe do przeniesienia do innych programów. Wyeliminowane są, więc wady zmiennych nielokalnych w przypadku ich stosowania do przekazywania danych między procedurami i sposób ten jest powszechnie zalecany.

Dalej podamy przykłady zastosowania parametrów do przekazywania danych między procedurami w programach.

Wielokąty

  1. Procedury rysujące ustalone wielokąty foremne o coraz dłuższym boku.

    Procedura kwadraty  :ilekw  :bok  :przyrost rysuje podaną za pomocą parametru :ilekw liczbę kwadratów o coraz dłuższym boku. Pierwszy narysowany kwadrat ma długość boku podaną za pomocą parametru :bok. Następnie, w każdym kroku iteracji, zwiększana jest wielkość zmiennej bok o podaną jako parametr :przyrost wartość. W kolejnym kroku procedura kwadrat wywoływana jest, więc już z nową wartością zmiennej bok i w efekcie rysowany jest kolejny kwadrat z nową długością boku. Wartość zmiennej bok przekazywana jest jako parametr aktualny do wywoływanej procedury kwadrat

Zadanie 3

Przepisz powyższe procedury i sprawdź ich działanie.

Dla przykładowego wywołania:

kwadraty 10 10 5

otrzymamy rysunek:

Zadanie 4

Wzorując się na powyższym przykładzie:

  1. napisz procedury: trójkąt, pięciokąt, siedmiokąt, ośmiokąt, jedenastokąt i okrąg z parametrem :bok wykonujące rysunki: trójkąta, pięciokąta, siedmiokąta, ośmiokąta, jedenastokąta i okręgu  o boku podanym jako parametr :bok,
  2. napisz procedury: trójkąty, pięciokąty, siedmiokąty, ośmiokąty, jedenastokąty i okręgi z parametrami :bok :przyrost :ile, zawierające wywołania procedur z poprzedniego punktu wykonujące: podaną jako parametr :ile liczbę odpowiednio: trójkątów, pięciokątów, siedmiokątów, ośmiokątów, jedenastokątówokręgów o boku podanym jako parametr :bok i zwiększanym o stałą wielkość podaną jako parametr :przyrost,
  3. pod rysunkami podaj wywołania procedur.

Zadanie 5

Napisz procedurę DEMO1 zawierającą wszystkie wywołania procedur z zadania 4  i wykonującą rysunki rozłożone na całym ekranie jak na powyższym rysunku. Do przesuwania żółwia użyj procedury: przesuń :poziomo :pionowo z odpowiednimi parametrami aktualnymi.

  1. Procedury rysujące wielokąty foremne o ustalonej w momencie wywołania liczbie boków i coraz dłuższym boku.

    Podane w poprzednim punkcie procedury możemy uogólnić. W tym celu skorzystamy z uogólnionej procedury wykonującej wielokąt foremny zwykły i napiszemy procedurę wykonującą wielokąty z parametrami jak poniżej:

Wartości zmiennych bok i ileboków przekazywane są jako parametry aktualne do wywoływanej procedury wielokątzw

Zadanie 6

  1. Podaj wywołania procedury wielokąty, z którymi procedura ta wykona rysunki takie jak w poprzednim zadaniu. Parametry wywołań wpisz odpowiednio do komórek tabeli.

  1. Napisz procedurę DEMO2 zawierającą wszystkie wywołania procedury z poprzedniego punktu zadania i wykonującą rysunki rozłożone na całym ekranie jak na rysunku do zadania 4. Do przesuwania żółwia użyj procedury: przesuń :poziomo :pionowo z odpowiednimi parametrami aktualnymi.

Rozety

  1. dla ustalonego wielokąta zewnętrznego np. trójkąta (trójkątl :bok, trójkątp :bok)

    Wiemy, że w przypadku rozet, wielokąt rysowany w pętli wewnętrznej, może być lewy lub prawy tj., może być rysowany na zewnątrz lub wewnątrz wielokąta rysowanego w pętli zewnętrznej. Przy rysowaniu wielokąta zewnętrznego żółw może być opuszczony bądź podniesiony. Mamy, zatem cztery podstawowe typy rozet. Na tym etapie naszej wiedzy do narysowania wszystkich typów rozet potrzebne są, więc cztery typy procedur. Podamy dla przykładu dwa typy.

Przykładowe wywołania (sprawdź!):

Rozeta1tr 4 100 50 Rozeta2tr 4 100 50
Rozeta1tr 4 0 50 Rozeta2tr 4 0 5

Zadanie 7

  1. napisz procedury z parametrem :bok wykonujące rysunki wielokątów (jakich?) potrzebnych dla wykonania rozet jak na poniższym rysunku,

  2. napisz procedury z parametrami :ileboków :bok1 :bok2 wykorzystujące odpowiednie procedury z poprzedniego punktu i wykonujące rozety jak na poniższym rysunku,

  3. nad rysunkami rozet podaj wywołania procedury wykonującej daną rozetę,

  4. Napisz procedurę DEMO3 zawierającą wszystkie wywołania procedur z poprzedniego punktu zadania i wykonującą rysunki rozet rozłożone na całym ekranie jak na poniższym rysunku. Do przesuwania żółwia użyj procedury: przesuń :poziomo :pionowo z odpowiednimi parametrami aktualnymi.

Wsk.  Rozety znajdujące się w tej samej kolumnie (pod sobą) uzyskamy za pomocą tej samej procedury, ale wywołanej z różnymi parametrami.

  1. dla przypadku ogólnego

Zadanie 8

Sprawdź następujące wywołania procedury rozeta1

  1. rozeta1 4 160 3 80 1
  2. rozeta1 4 120 3 60 -1
  3. rozeta1 7 70 5 30 1
  4. rozeta1 7 50 5 30 -1
  5. rozeta1 5 120 4 50 1
  6. rozeta1 13 40 7 13 1
  7. rozeta1 4 0 3 100 1
  8. rozeta1 6 0 3 100 1
  9. rozeta1 6 0 6 50 1
  10. rozeta1 8 0 4 50 1
  11. rozeta1 4 0 4 50 1
  12. rozeta1 8 0 36 6 1

Zadanie 9

  1. Sprawdź wywołania procedury rozeta2 z parametrami z poprzedniego zadania,
  2. Sprawdź następujące wywołania procedury rozeta2
    1. rozeta2 5 100 5 60 2
    2. rozeta2 7 50 7 40 5
    3. rozeta2 10 30 5 30 -1
    4. rozeta2 12 35 36 2 1

Zadanie 10

Podaj wywołania procedury rozeta1 lub rozeta2, z którymi wywoływana procedura wykona rysunki takie jak poniżej. Parametry wywołań wpisz odpowiednio do komórek tabeli.

Zadanie 11

Napisz procedurę DEMO4 zawierającą wszystkie wywołania procedur z zadania 10 i wykonującą rysunki rozłożone na całym ekranie jak na rysunku do tego zadania. Do przesuwania żółwia użyj procedury: przesuń :poziomo :pionowo z odpowiednimi parametrami aktualnymi.

Sposób oceniania

Ocena

Wykonane zadania

6

1, 2, 3, 4, 5, 6, 7, 8, 9, 10,  11

5

1, 2, 3, 4, 5, 6, 7a, 7b, 7c, 7d,

4

1, 2, 3, 4, 5, 6, 7a, 7b, 7c

3

1, 2, 3, 4, 5, 6.1 i 6.2

2

1, 2, 3, 4, 5 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Lekcja 15

Rozety z łuków

Dla procedur:

oto łukp :wielkość :krok

powtórz :wielkość [np :krok pw 1]

pod powtórz :wielkość [lw 1 ws :krok] opu

już

oto łukl :wielkość :krok

powtórz :wielkość [np :krok lw 1]

pod powtórz :wielkość [pw 1 ws :krok] opu

już

zdefiniujemy przykładowe procedury następująco:

Przykładowe wywołania:

rozeta1ł  9 1 40 2

rozeta2ł  9 1 40 2

Zadanie 12

  1. Sprawdź następujące wywołania procedury rozeta1ł
    1. rozeta1ł 12 1 60 1
    2. rozeta1ł 15 1 45 1
    1. rozeta1ł 30 0 72 1
    2. rozeta1ł 24 0 30 3
  2. Sprawdź wywołania procedury rozeta2ł z parametrami z poprzedniego punktu,

Zadanie 13

Podaj wywołania powyższych procedur dla następujących rysunków rozet:

Zadanie 14

Napisz procedurę DEMO5 zawierającą wszystkie wywołania procedur z zadania 13 i wykonującą rysunki rozłożone na całym ekranie jak na rysunku do tego zadania. Do przesuwania żółwia użyj procedury: przesuń :poziomo :pionowo z odpowiednimi parametrami aktualnymi.

Korona kwiatu

oto korona :ilepłatków :krok

lokalna "wielkość

przyp "wielkość 360 / :ilepłatków

ukm 1 + losowa 14

powtórz :ilepłatków [płatek :wielkość :krok pw :wielkość]

już

oto płatek :wielkość :krok

powtórz 2 [powtórz :wielkość [np :krok pw 1] pw 180 - :wielkość]

pod pw :wielkość / 2 np :wielkość / 2 zamaluj ~

ws :wielkość / 2 lw :wielkość / 2 opu

już

Zadanie 15

Sprawdź "grupami" następujące wywołania:

  1. korona 5 1.5
  2. korona 5 1
  1. korona 8 3
  2. korona 8 2.4
  3. korona 8 1.8

 

  1. korona 12 5
  2. korona 12 4.2
  3. korona 12 3.4
  4. korona 12 2.6
  5. korona 12 1.8
  1. korona 6 3
  2. korona 6 2.5
  3. korona 6 2
  1. korona 9 4
  2. korona 9 3
  3. korona 9 2
  4. korona 9 1

Zadanie 16

Podaj wywołania procedury korona dla następujących rysunków koron:

Zadanie 17

Napisz procedurę DEMO6 zawierającą wszystkie wywołania procedur z zadania 16 i wykonującą rysunki rozłożone na całym ekranie jak na rysunku do zadania 16. Do przesuwania żółwia użyj procedury:
przesuń :poziomo :pionowo
z odpowiednimi parametrami aktualnymi.

Korony kwiatów

Zadanie 18

Napisz procedury: korony3, korony4 i korony5 wykorzystujące procedurę korona z odpowiednimi parametrami i wykonujące następujące rysunki:

Zadanie 19

Napisz procedurę DEMO7 zawierającą wszystkie wywołania procedur z zadania 18 i wykonującą rysunki rozłożone na całym ekranie jak na rysunku do tego zadania. Do przesuwania żółwia użyj procedury:
przesuń :poziomo :pionowo
z odpowiednimi parametrami aktualnymi.

Przedstawione procedury wykonujące "korony kwiatów" można uogólnić w następujący sposób:

Zadanie 20

Sprawdź następujące wywołania procedury korony:

  1. korony 5 3 4 1
  2. korony 7 2.8 5 0.3
  3. korony 10 4 4 0.5
  4. korony 3 1 2 0.5

Podsumowanie

Zadanie 21

Napisz procedurę DEMO8 wykonującą rysunki rozłożone na całym ekranie jak na rysunku poniżej. Do przesuwania żółwia użyj procedury: przesuń  :poziomo  :pionowo z odpowiednimi parametrami aktualnymi.

Sposób oceniania

Ocena

Wykonane zadania

6

12, 13, 14, 15, 16, 17, 18, 19, 20, 21

5

12, 13, 14, 15, 16, 17, 18, 19

4

12, 13, 14, 15, 16, , 17

3

12, 13, 14, 15, 16   

2

12, 13, 14