Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

obrazek

Autor: Steven Vickers
Tłumaczył: mgr Jerzy Wałaszek

©2021 mgr Jerzy Wałaszek
I LO w Tarnowie

ROZDZIAŁ 14 – Podprogramy

Rozkazy: GOSUB, RETURN

SPIS TREŚCI
ROZDZIAŁ 1 Przygotowanie ZX81
ROZDZIAŁ 2 Wydawanie komputerowi poleceń
ROZDZIAŁ 3 Lekcja historii
ROZDZIAŁ 4 Sinclair ZX81 jako kalkulator kieszonkowy
ROZDZIAŁ 5 Funkcje
ROZDZIAŁ 6 Zmienne
ROZDZIAŁ 7 Łańcuchy tekstowe
ROZDZIAŁ 8 Programowanie komputera
ROZDZIAŁ 9 Dalsze programowanie komputera
ROZDZIAŁ 10 Jeśli ...
ROZDZIAŁ 11 Zestaw znaków
ROZDZIAŁ 12 Pętle
ROZDZIAŁ 13 Wolno i Szybko
ROZDZIAŁ 14 Podprogramy
ROZDZIAŁ 15 Uruchamianie programów
ROZDZIAŁ 16 Pamięć taśmowa
ROZDZIAŁ 17 Wyświetlanie z bajerami
ROZDZIAŁ 18 Grafika
ROZDZIAŁ 19 Czas i ruch
ROZDZIAŁ 20 Drukarka dla ZX81
ROZDZIAŁ 21 Podłańcuchy
ROZDZIAŁ 22 Tablice
ROZDZIAŁ 23 Gdy zaczyna brakować pamięci
ROZDZIAŁ 24 Liczenie na palcach
ROZDZIAŁ 25 Jak pracuje komputer
ROZDZIAŁ 26 Stosowanie kodu maszynowego
ROZDZIAŁ 27 Organizacja pamięci
ROZDZIAŁ 28 Zmienne systemowe
DODATKI
A Zestaw znaków
B Numery komunikatów
C ZX81 dla znających język BASIC

ROZDZIAŁ 14 – Podprogramy

Czasami różne części twojego programu będą posiadały raczej podobne zadania do wykonania i zauważysz, iż wpisujesz po raz kolejny te same polecenia; jednakże nie ma takiej potrzeby. Możesz prowadzić wiersze programu raz w postaci znanej jako podprogram, a następnie użyć ich lub wywołać z dowolnego miejsca w programie bez ponownego wprowadzania.

W celu wykonania tego zadania używasz poleceń GOSUB (IDŹ do PODPROGRAMU) i RETURN (POWRÓĆ).

GOSUB n

gdzie n jest numerem pierwszego wiersza w podprogramie; jest to bardzo podobne do GOTO n, z wyjątkiem tego, iż komputer zapamiętuje numer wiersza polecenia GOSUB, aby później powrócić po wykonaniu podprogramu. Wykonuje to zapamiętywanie przez umieszczenie numeru wiersza (adresu powrotnego) na szczycie stosu adresów (stosu poleceń GOSUB).

RETURN

pobiera numer wiersza ze szczytu stosu GOSUB i idzie do wiersza o numerze bezpośrednio większym.

Jako pierwszy przykład, wpisz:

    10 PRINT "TO JEST GLOWNY PROGRAM",
    20 GOSUB 1000
    30 PRINT "I JESZCZE RAZ";
    40 GOSUB 1000
    50 PRINT "I TO WSZYSTKO."
    60 STOP
1000 REM PODPROGRAM ZACZYNA SIE TUTAJ
1010 PRINT "TO JEST TEN PODPROGRAM,"
1020 RETURN

Polecenie STOP w wierszu 60 jest bardzo ważne, ponieważ w przeciwnym razie program wbiegłby do podprogramu i spowodowałby błąd 7 przy próbie wykonania polecenia RETURN.

Jako mniej trywialny przykład załóżmy, iż masz ochotę napisać program komputerowy zajmujący się funtami, szylingami i pensami (pamiętaj, iż jest to tłumaczenie z j. angielskiego - przyp. tłum.). Posiadający dobrą pamięć wiedzą, iż przed rokiem 1971 funt angielski dzielony był na dwadzieścia szylingów - zatem szyling odpowiada 5 pensom - a z kolei szyling dzielony był na dwanaście starych pensów (d było skrótem dla starego pensa). Będziesz miał trzy zmienne: L, S i D (być może inne - L1, S1, D1 itd.), a arytmetyka jest prosta jak drut. Po pierwsze stosujesz ją rozdzielnie dla funtów, szylingów i pensów - na przykład, aby dodać dwie sumy pieniężne, dodajesz pensy, dodajesz szylingi i dodajesz funty; aby podwoić sumę pieniędzy, podwajasz pensy, szylingi i funty; itd. Gdy będzie wszystko wyliczone, sprowadzasz wyniki do poprawnej postaci tak, aby pensy znalazły się pomiędzy 0 i 11, szylingi pomiędzy 0 i 19, a funty tyle ile wyjdzie. Ostatni etap jest wspólny dla wszystkich tych operacji, zatem możemy przekształcić go w podprogram.

Odkładając na moment pojęcie podprogramu, warto poświęcić chwilę swojego czasu na próbę samodzielnego napisania tego programu. Mając dane dowolne liczby L, S i D, jak sprowadziłbyś je do właściwej liczby funtów, szylingów i pensów? Częścią problemu jest to, iż zaczniesz myśleć o coraz bardziej dziwnych przypadkach.

Najpierw przyjdzie ci pewnie na myśl coś takiego jak 1£ 25s 17d, które chcesz zamienić na 2£ 6s i 5d. Bułka z masłem. Lecz załóżmy, iż masz liczby ujemne. Dług 1£ 25s 17d lub -1£ -25s -17d mógłby równie dobrze zmienić się na -3£ 13s 7d, co raczej jest dziwnym sposobem zapisywania go (jakby ludzie pożyczali sobie nawzajem tylko całe funty). A co z ułamkami? Jeśli podzielisz 1£ 25s 17d przez dwa, dostaniesz 0,5£ 12,5s 8,5d i chociaż ilość pensów 8,5 wpada pomiędzy 0 a 11, ilość szylingów 12,5 wpada pomiędzy 0 a 19, na pewno nie jest to tak dobre, jak 1£ 3s 2,5d. Postaraj się wypracować swoje własne rozwiązania tych problemów i wykorzystaj je w programie komputerowym, zanim zaczniesz czytać dalej (marzenie belfra, no nie? - przyp. tłum.).

Oto jedno z rozwiązań:

1000 REM PODPROGRAM WYLICZAJACY POPRAWNA LICZBE FUNTOW, SZYLINGOW I PENSOW
1010 LET D=240*L+12*S+D
1020 REM TERAZ WSZYSTKO JEST W PENSACH
1030 LET E=SGN D
1040 LET D=ABS D
1050 REM PRACUJEMY Z DODATNIM D, PAMIETAJAC ZNAK W E
1060 LET S=INT (D/12)
1070 LET D=(D-12*S)*E
1080 LET L=INT (S/20)*E
1090 LET S=S*E-20*L
1100 RETURN

Sam z siebie ten podprogram nie jest specjalnie użyteczny, ponieważ nie zawiera poleceń ani ustawiających zmienne L, S i D, ani wykorzystujących wyniki. Wpisz program główny oraz również inny podprogram wyświetlania L, S i D.

    10 INPUT L
    20 INPUT S
    30 INPUT D
    40 GOSUB 2000
    45 REM WYSWIETLENIE WARTOSCI
    50 PRINT
    60 PRINT "obrazekobrazekobrazek = ";
    70 GOSUB 1000
    75 REM POPRAWIANIE
    80 GOSUB 2000
    85 REM WYSWIETLENIE WARTOSCI
    90 PRINT
  100 GOTO 10
2000 REM PODPROGRAM WYSWIETLANIA L,S I D
2010 PRINT "£";L;"..";S;"S..";D;"D";
2020 RETURN

(Przypomnij sobie z rozdziału 9, iż puste polecenie PRINT w wierszu 50 wyświetla jeden pusty wiersz).

Wyraźnie zaoszczędziliśmy na programie wykorzystując podprogram wydruku od wiersza 2000, co samo w sobie jest bardzo powszechnym wykorzystaniem podprogramów: skracanie długości programów. Jednakże podprogram korygowania w rzeczywistości spowodował wydłużenie programu - przez polecenia GOSUB i RETURN; zatem sama długość programu nie jest jedynym powodem stosowania podprogramów. Jeśli zostaną użyte umiejętnie, to podprogramy mogą ułatwić zrozumienie działania całego programu tym, którzy się tutaj liczą - nam, ludziom.

Program główny uległ uproszczeniu dzięki zastosowaniu bardziej zaawansowanych poleceń: każdy GOSUB reprezentuje pewien skomplikowany podprogram, lecz można o tym zapomnieć, liczy się tylko wynik jego działania. Dzięki temu łatwiej uchwycić główną strukturę programu.

Z drugiej strony podprogramy są upraszczane z całkiem innego powodu, mianowicie są one krótsze. Wciąż używają tych samych, starych poleceń LET i PRINT, lecz muszą one wykonać jedynie część całej pracy, a tak łatwiej się je pisze.

Sztuka polega na wybraniu warstwy - lub warstw - na których pisze się podprogramy. Muszą być wystarczająco duże, aby posiadały znaczący wpływ na program główny, a jednak na tyle małe, aby pisało się je łatwiej niż cały program bez podprogramów. Te przykłady (nie polecane) ilustrują opisane problemy:

Pierwszy:

    10 GOSUB 1000
    20 GOTO 10
1000 INPUT L
1010 INPUT S
1020 INPUT D
1030 PRINT " ";L;"..";S;"S..";D;"D";TAB 8;"=";
1040 LET D=240*L+12*S+D
:    :
:    :
2000 RETURN

i drugi:

    10 GOSUB 1010
    20 GOSUB 1020
    30 GOSUB 1030
    40 GOSUB 1040
    50 GOSUB 1050
    :    :
    :    :
  300 GOTO 10
1010 INPUT L
1015 RETURN
1020 INPUT S
1025 RETURN
1030 INPUT D
1035 RETURN
1040 PRINT " ";L;"..";S;"S..";D;"D";TAB 8; "=";
1045 RETURN
1050 LET D=240*L+12*S+D
1055 RETURN
:    :
:    :

Pierwszy ze swoim zaawansowanym podprogramem oraz drugi ze swoimi licznymi, trywialnymi podprogramami demonstrują zupełnie przeciwne skrajności, lecz z jednakową bezcelowością.

Podprogram może bez problemu wywoływać następny, lub nawet sam siebie (podprogram wywołujący sam siebie nazywamy rekursywnym), zatem nie bój się stosować kilku warstw.

Podsumowanie

Polecenia: GOSUB, RETURN

Ćwiczenia

  1. Przykładowy program jest prawie uniwersalnym kalkulatorem dla funtów, szylingów i pensów. Jak zastosowałbyś go:

    (i) do zamiany funtów i nowych pensów na funty, szylingi i pensy?
    (ii) do zamiany gwinei na funty i szylingi? (1 gwinea = 1£ 1s)
    (iii) do wyznaczania ułamka funta? (np. jednej trzeciej funta)

    Wstaw wiersz zaokrąglający pensy do najbliższego ćwierć pensa (1/4d).
  1. Dodaj dwa polecenia do programu:

    4 LET POPRAW=1000
    7 LET PISZ LSD=2000

    i zmień

    GOSUB
    1000 na GOSUB POPRAW
    GOSUB 2000 na GOSUB PISZ LSD

    Zadziała to dokładnie tak, jak myślisz; w rzeczywistości numery wierszy w poleceniu GOSUB (lub GOTO i RUN) mogą być dowolnymi wyrażeniami liczbowymi (nie myśl sobie, iż takie coś będzie działać na komputerach innych niż ZX81, ponieważ nie jest to standardowym językiem BASIC).

    Tego typu rzeczy mogą zdziałać cuda dla przejrzystości programów.
  1. Przepisz główny program w przykładzie, aby wykonywał coś zupełnie innego, lecz wykorzystywał przy tym te same podprogramy.
  1. W kolejnych wierszach polecenia

    ... GOSUB n
    ... RETURN

    można zastąpić przez

    ... GOTO n

    Dlaczego?
  1. Podprogram może posiadać kilka punktów wejścia. Na przykład ze względu na sposób wykorzystywania podprogramów w naszym programie głównym. gdzie polecenie GOSUB 1000 występuje bezpośrednio przed GOSUB 2000, możemy zastąpić te dwa podprogramy jednym dużym, który koryguje L, S i D i wyświetla je. Posiada on dwa punkty wejścia: Jeden na początku do całego podprogramu oraz drugi nieco dalej do fragmentu dokonującego jedynie wyświetlania.

    Zrób odpowiednie poprawki.
  1. Uruchom program:

    10 GOSUB 20
    20 GOSUB 10

    Adresy powrotne są umieszczane stadnie na stosie GOSUB, lecz nigdy nie są z niego usuwane i w końcu w komputerze zabraknie dla nich miejsca. Wtedy program zatrzyma się z komunikatem błędu 4 (zobacz do dodatku B).

    Mógłbyś mieć kłopoty z usunięciem adresów ze stosu bez kasowania wszystkiego, lecz to powinno ci pomóc:

    (i) Usuń te dwa polecenia GOSUB.
    (ii) Wstaw dwa nowe wiersze:

    11 RETURN
    21 RETURN

    (iii) Wpisz:

    RETURN

    Adresy powrotu będą zdejmowane ze stosu aż otrzymasz błąd 7.

    (iv) Zmień swój program tak, aby to samo się już nie powtórzyło.

    Jak to zadziałało?
Na początek:  podrozdziału   strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2021 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.