Sub, Gosub, Call i Config Submode - różnice

Proste przykłady do częstych pytań.
ODPOWIEDZ
Awatar użytkownika
niveasoft
Posty: 1207
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Sub, Gosub, Call i Config Submode - różnice

Post autor: niveasoft » 19 mar 2017, 8:13

Sprawa nie jest zawiła tylko chyba brak jakiegoś wyczerpującego opisu.

Suby to wydzielone procedury do których program może skoczyć i zazwyczaj z nich wraca.

Pierwszy, prosty typ, to taki sub któremu nie przekazuje się żadnych parametrów. Program tam skacze, działa coś na zmiennych programu i kiedy wszystko ma już zrobione i napotyka Return to wraca w miejsce gdzie został wywołany. Sub taki nie wymaga żadnego deklarowania ponieważ, przestarzałym sposobem umieszcza się go już za linią End programu.
Start takiego Suba czyli jego adres określa etykieta z dwukropkiem czyli Label.
Skok do takiego Suba wykonujemy za pomocą polecenia Gosub
  1. '-------------------------------------
  2. Do
  3. '....
  4.     'Jeśli wciśnięto przycisk to skocz do Suba
  5.   If Switch = 0 Then Gosub Plus_sub
  6. '....
  7. Loop
  8. End
  9. '--------------------------------------------------------------------
  10. Plus_sub: ' <-dwukropek zaraz za etykietą (bez spacji)
  11. ...coś tu zrób
  12. Return ' <- taki Sub kończymy Return, a nie End Sub!
Przypominam, że temu Sub`owi nie przekazujemy parametrów.

Co jeśli chcemy przekazać parametry i do czego się to może przydać.

Subowi możemy przekazać parametry , albo w postaci wartości zmiennej która się Subowi przyda, albo bezpośrednio adres zmiennej którą chcemy w Sub zmienić.

Dla prostego przykładu. Mamy jakąś zmienną i chcielibyśmy ją wysłać do portu COM ale zawsze większą o jeden.
Normalnie musielibyśmy albo stworzyć drugą zmienną, dodać do niej jeden i potem Print
Gdybyśmy chcieli tę zmienną tak wysyłać w kilku miejscach programu to zawsze trzeba by pisać kod dodawający jeden do naszej zmiennej.
Poprzez Sub można to zrobić raz i potem go sobie tylko wywołać.

Tu zaczynają się różnice pomiędzy starszymi wersjami Bascom <2075 a nowszymi.
W starszych wersjach taki Sub trzeba było zadeklarować na początku kodu a Sub umieścić pod linią End

Przykład:
  1. Dim Zmienna As Byte
  2. '----
  3. Declare Sub Zwieksz_i_drukuj(byval Wartosc As byte)
  4. '------------------------------------------
  5. Do
  6.  Zmienna = 2
  7.   Zwieksz_i_drukuj Zmienna ' <-jeśli nie ma z przodu Call to nie dajemy nawiasów
  8.  
  9.  Call Zwieksz_i_drukuj( zmienna ) ' <-jeśli z przodu Call to powinny być nawiasy
  10. Loop
  11. '------------------------------------------
  12. Sub Zwieksz_i_drukuj(byval Wartosc As byte)
  13.  Incr Wartosc  ' zwiększ przekazaną wartośc o jeden (2+1)
  14.   Print Wartosc ' i teraz drukuj do portu COM (wyśle 3)
  15. End Sub '<- taki Sub kończymy przez "End Sub"
Można sobie zbudować taki Sub któremu nie przekazujemy żadnych parametrów. Np. kiedy zawsze będziemy do portu wysyłać tę samą zmienną, ale z jakimś poprzedzającym ją znakiem.
  1. Dim Zmienna As Byte
  2. '----
  3. Declare Sub Wyslij()
  4. '-------------------------------------------
  5. Do
  6.  Zmienna = 2
  7.   Wyslij ' <-jeśli nie ma z przodu Call to nie dajemy nawiasów
  8.  
  9.  Call Wyslij() ' <-jeśli z przodu Call to powinny być nawiasy chociażby puste
  10. Loop
  11. '-------------------------------------------
  12. Sub Wyslij()
  13.   Print "Z="; Zmienna  ' odpada nam wszędzie dopisywanie "Z="
  14. End Sub '<- taki Sub kończymy przez "End Sub"
Teraz różnica kiedy w nowszych Bascom użyjemy Config Submode = New

Plusy tego rozwiązania są następujące:
Umieszczamy cały Sub przed głównym kodem gdzie go wywołamy, ale nie musimy go już deklarować
Drugi bonus jest taki, że kiedy nie użyjemy Suba w kodzie to nie zostanie on skompilowany i kod będzie mniejszy

Może się wydać dziwne, po co pisać Sub i go nie używać.
Otóż pozwala to napisać sobie kilka wersji różnych Subów, albo całej biblioteki Subów a na końcu użyć tylko jednego lub kilku.

W ten sposób można do kodu dodawać całe biblioteki swoich ulubionych procedur a używać wybranych.
  1. Config Submode = New
  2.  
  3. Dim Zmienna As Byte
  4. '----
  5. Sub Zwieksz_o_jeden()
  6.   Incr Zmienna
  7. End Sub
  8. '----
  9. Sub Zwieksz_o_dwa()
  10.  Zmienna = Zmienna + 2
  11. End Sub
  12. '-------------------------------------
  13. Do
  14.  
  15.  Call Zwieksz_o_dwa()
  16.  
  17.          'w tym przykładzie Sub Zwieksz_o_jeden nie zostanie w ogóle skompilowany
  18.          '  --- PONIEWAŻ NIE ZOSTAŁ UŻYTY ---
  19. Loop
  20. End
Jak widać nie deklarowałem żadnego z tych Subów, ale muszą być napisane zanim zostaną wywołane w kodzie.
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Sub, Gosub, Call i Config Submode - różnice

Post autor: Jacek » 03 mar 2018, 23:49

Witam - mam małą zagwostkę jak przekazać parametry (konkretnie temperatury) z jednego suba do drugiego (termostat).
Mogę prosić o wskazówkę.
pozdrawiam Jacek.
Pikczu
Posty: 388
Rejestracja: 17 sie 2015, 13:46
Lokalizacja: Dublin, Ireland
Kontakt:

Re: Sub, Gosub, Call i Config Submode - różnice

Post autor: Pikczu » 04 mar 2018, 9:45

Jacek do pobierania z czegoś danych najlepiej jest użyć funkcji.
Potem przekazać te parametry do suba.

Najlepiej załóż nowy wątek bo tu się zamieszanie zrobi.

Bartek mógł byś to przenieść gdzieś?
Awatar użytkownika
niveasoft
Posty: 1207
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Sub, Gosub, Call i Config Submode - różnice

Post autor: niveasoft » 04 mar 2018, 9:48

Mogę dużo, tylko wolałbym propozycję tematu niż pisać go/wymyślać samemu a potem pod tym umieszczać czyjś post.

W obecnym temacie móże dopowiem że przekazywanie wartości do subów "by val" nie może zmienić głównej wartości którą tylko przekazujemy i mówimy ile wynosi.
Natomiast przekazanie "by ref: umożliwia zmianę głównej wartości.

Można wiec napisać sub "Dodaj_jeden(byref Zmienna) i to będzie miało na nią wpływ jeśli sub bedzie wyglądał tak:
  1. Dim Zmienna As Byte
  2.  
  3. Sub Dodaj_jeden(byref My_variable As Byte)
  4.  Incr My_variable
  5. End Sub
ODPOWIEDZ