Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Niezrozumiała zmiana wartości zmiennych

adam220 10 Kwi 2012 16:39 1322 7
  • #1 10 Kwi 2012 16:39
    adam220
    Poziom 14  

    Witam,
    prosze o wyjasnienie dlaczego zmieniaja się wartości zmiennych, które uzywam do wywołania podprogramu FUNCTION.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Daje on taki wynik:
    wartości na zewnatrz f=5 g=6
    wartości wewnatrz f=0 g=5


    Dlaczego wartości zmiennych f i g sie zmieniły?
    Dlaczego wewnatrz widzę inne wartości niż przekazałem do funkcji?

    Dodam że kompilacja jest w BASCOM AVR IDE firmy MSELEC.

    0 7
  • #2 10 Kwi 2012 16:55
    gaskoin
    Poziom 38  

    A w BASCOMIE rozmiar liter ma znaczenie ? Bo jeśli tak to przejrzyj swój program.

    Poza tym widzę, że deklaracja nieco się różni od definicji, parametry są na odwrót.

    0
  • #3 10 Kwi 2012 17:22
    adam220
    Poziom 14  

    W Bascomie którego uzywam czyli Bascom AVR IDE, edytor sam zmienia nazwy zmiennych na wielkie litery, np z->Z.
    W przypadku wołania funkcji (w moim przykładzie T=x,y) z niezrozumiałych przeze mnie względów zmienia pierwszy argument na małą literę a drugi na wielką, niezależnie jak je użytkownik wpisze. Nie wiem czy to ma jakieś znaczenie, ale może właśnie tu jest pies pogrzebany?

    Dodano po 5 [minuty]:

    Uporządkowałem argumenty i nic to nie dało:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Wynik:
    wartości na zewnatrz g=5 f=6
    wartości wewnatrz g=5 f=0


    Dodano po 16 [minuty]:

    Chciałbym jeszcze dodać, że obserwuję zmianę tylko zmiennej podanej jako drugi argument.
    Zmienna podana jako pierwszy argument się nie zmienia.
    Sprawdzałem na kilku innych przykładach.
    Czyżby jakiś błąd kompilatora?

    0
  • #5 10 Kwi 2012 19:10
    adam220
    Poziom 14  

    Dzięki RS07.
    No rzeczywiście. Trzeba podać BYVAL jeden raz.
    a więc

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    skompiluje się źle,


    natomiast
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    skompiluje się dobrze.
    Znana książka Piotr Górecki "Mikrokontrolery dla początkujących" na s.404 podaje tę źle kompilujacą się (niewłaściwą?)- składnię.
    Jest to chyba niezamierzone przez autora kompilatora, tymbardziej że
    -podobno (ww książka) można mieszać BYREF i BYVAL w jednej deklaracji.
    -byref jest domyślny i mozna go nie podawać, a więc skoro nie podaje to powinien byc BYREF a jest BYVAL.

    A więc do zapamietania: BYVAL w deklaracji podajemy tylko 1 raz
    Komentarz mile widziany.

    0
  • #6 10 Kwi 2012 20:53
    Mundi1970
    Poziom 24  

    adam220 napisał:
    A więc do zapamietania: BYVAL w deklaracji podajemy tylko 1 raz

    Nie. :)
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    W tym wypadku pierwsza zmienna jest przekazana jako byval, a druga jako byref. Ty masz inny błąd, nazwy przekazywanych zmiennych w deklaracji funkcji są takie same jak nazwy zmiennych globalnych. I tak naprawdę w funkcji operujesz na zmiennych globalnych, a nie na zmiennych przekazanych przy wywołaniu funkcji. Zrób sobie test, zmienną G przekazujesz jako wartość. Dopisz w funkcji np. Incr G, a po wyjściu z funkcji wyświetl zmienną G :).

    Prawidłowo powinno wyglądać to tak:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #7 12 Kwi 2012 16:44
    adam220
    Poziom 14  

    Tak rzeczywiście nazwy zmiennych pokrywają się.
    Może byc to niewłaściwe ale nie musi.
    Czy jednak czy rzeczywiście to jest przyczyną zmiany wartości zmiennych?
    Nie.
    Żadna instrukcja przypisania nie zmienia zmiennych które sa przekazywane do podprogramu. Instrukcji zmieniajacych nie ma ani wewnątrz funkcji ani w programie głównym. A jednak ich wartości się zmieniają.
    Dlaczego tak jest odpowiedzi udzielił twórca kompilatora Mark Alberts.
    Zalecił dopisać

    Cytat:
    you need to add :
    $swstack=16
    $framesize=30

    I kod zaczął działać...:)
    I dlatego właśnie kod Mundi1970 działa a mój nie.

    Przy okzaji chialbym dopytać Mundi1970 czy skoro w deklaracji funkcji użyłeś
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    to czy w definicji jescze raz trzeba podawać typy danych
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Bo ja tego nie zrobiłem i działa w postaci

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    ?

    0
  • #8 12 Kwi 2012 20:04
    Mundi1970
    Poziom 24  

    adam220 napisał:
    Przy okzaji chialbym dopytać Mundi1970 czy skoro w deklaracji funkcji użyłeś ........

    We wszystkich przykładach z katalogu SAMPLES i w helpie, na początku funkcji jest podawany typ danych. Teraz działa nawet i tak :):
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    ale wyjdą kolejne dwie wersje BASCOMA i może już przestać działać ;)
    adam220 napisał:
    Zalecił dopisać
    Cytat:
    you need to add :
    $swstack=16
    $framesize=30


    I kod zaczął działać...:)

    Należy też pamiętać że te wartości mogą być większe. Wszystko zależy od ilości przerwań, podprogramów, funkcji, sposobie ich wywoływania i ilości przekazywanych zmiennych do funkcji. Przydatny artykuł na temat BASCOM'owych 2 stosów i ramki :) Reveal the secret of Stack BASCOM-AVR - Part 1 . Działanie stosu hardwarowego i softwarowego ($hwstack, $swstack) były dla mnie zrozumiałe, ale w ramce ($frame) mi coś zawsze nie pasowało :), artykuł ładnie to wyjaśnił.

    adam220 napisał:
    Tak rzeczywiście nazwy zmiennych pokrywają się.
    Może byc to niewłaściwe ale nie musi.

    Rzeczywiście mój błąd. Jeżeli zmienną globalną przekaże do funkcji przez referencje (byref), i np. w funkcji zwiększę ją o jeden, będzie to miało wpływ na przekazaną zmienną globalną :). Jest to jak najbardziej prawidłowe działanie.

    0