Strona 1 z 1

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

: 19 mar 2017, 8:13
autor: niveasoft
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.

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

: 03 mar 2018, 23:49
autor: Jacek
Witam - mam małą zagwostkę jak przekazać parametry (konkretnie temperatury) z jednego suba do drugiego (termostat).
Mogę prosić o wskazówkę.
pozdrawiam Jacek.

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

: 04 mar 2018, 9:45
autor: Pikczu
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ś?

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

: 04 mar 2018, 9:48
autor: niveasoft
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