atarionline.pl pytanie o stringi - Forum Atarum

    Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

    • :
    • :

    Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

      • 1: CommentAuthorMaciek
      • CommentTime10 Jul 2010 16:07
       
      Chodzi oczywiście o tekst, a nie o majtki.
      Zauważyłem dzisiaj taką prawidłowość podmieniając litery w ciągu znaków:
      mogę zmienić pojedynczą literkę komendą POKE ADR(A$),[kod literki] natomiast nie mogę tego zrobić przez POKE [adres początku stringa odczytany przez ?ADR(a$)],[kod literki].

      kiedy sprawdzam początek stringa komendą ?ADR(A$) i próbuję ręcznie coś tam "wPOKEować" np.poke 8189,11 nie daje to żadnego efektu, ale poke ADR(a$),11 już działa, o co chodzi?
      • 2: CommentAuthormono
      • CommentTime10 Jul 2010 17:07 zmieniony
       
      Zakładam, że robisz to w BASICu.
      I zakładam, że robisz to w trybie bezpośrednim:
      DIM A$(100)
      A$="tekst"
      A=ADR(A$)
      POKE A,ASC("T")
      ? A$

      i że wykonujesz kolejne polecenia pojedynczo zatwierdzając każde RETURNem. Dla próby zrób to samo ale w jednej linii:
      DIM A$(100):A$="tekst":A=ADR(A$):POKE A,ASC("T"):? A$

      Teraz wyjaśnienie:
      1. BASIC rozmieszcza w pamięci kolejno: a) kod programu, b) linię w trybie bezpośrednim (o wewnętrznym nrze 32768), c) zawartość wszystkich używanych tablic i stringów.
      2. Ponieważ linia w trybie bezpośrednim znajduje się między kodem programu, a tablicami i stringami, to po wprowadzeniu nowej linii w trybie bezpośrednim zawartość tablic i stringów przesuwana jest w pamięci - dlatego w pierwszej metodzie adres A wskazuje miejsce w pamięci, które nie jest już początkiem stringa.
      3. Jeśli wprowadzisz wszystkie zlecenia w jednej linii w trybie bezpośrednim wtedy pamięć tablic i stringów pomiędzy kolejnymi instrukcjami (znajdującymi się w przecież jednej linii) nie jest przesuwana w pamięci - dlatego w drugiej metodzie adres A jest poprawny.

      Edit:
      ADR zwraca aktualny adres stringa, który może zmieniać się zależnie do aktualnej długości linii w trybie bezpośrednim (w postaci stokenizowanej - max 255 bajtów).
      BASIC przesuwa dane w pamięci tylko przy wprowadzaniu/usuwaniu linii a podczas wykonywania programu tylko przy deklarowaniu nowych zmiennych (przesuwany jest wtedy tylko stos BASICa, który znajduje się za tablicami - a więc ten przypadek w zasadzie nas nie interesuje; wspominam o nim tylko dla ścisłości). Tak więc jeśli wykonujesz program możesz być raczej spokojny o adresy zmiennych. Zmieniają się tylko w trybie bezpośrednim i są związane z modyfikacją linii (o nrze 32768 - linii do wykonania w trybie bezpośrednim).
      • 3: CommentAuthorMaciek
      • CommentTime11 Jul 2010 12:07
       
      Dzięki za wyjaśnienie. Bawiłem się jeszcze wczoraj troszkę stringami i trafiłem na kolejny nurtujący mnie problem.
      Otóż chciałem zapisać na dyskietce plik ze zrzuconymi bajtami stringa i potem go wczytać w nowym programie do innego stringa. Nie wiem co robię źle, czy możecie na to rzucić okiem?

      ZAPIS:

      10 DIM TEKST$(11)
      20 TEKST$="Ala ma kota"
      30 OPEN #1,8,0,"D:PLIK.TXT"
      40 BPUT #1,ADR(TEKST$),11
      50 CLOSE #1

      ODCZYT:

      10 DIM TEKST2$(11)
      20 OPEN #1,4,0,"D:PLIK.TXT"
      30 BGET #1,ADR(TEKST2$),11
      40 CLOSE #1

      Niestety nie działa. Próbowałem też odczytać zapisany plik i wrzucić go w obszar obrazu, ale zamiast tekstu pokazały się jakieś krzaki. Zrobiłem to tak:

      10 ?CHR$(125)
      20 OPEN #1,4,0,"D:PLIK.TXT"
      30 BGET #1,DPEEK(88),11
      40 CLOSE 1
      Nie za bardzo wiem czemu te programy nie chcą działać poprawnie.
      • 4:
         
        CommentAuthorlarek
      • CommentTime11 Jul 2010 15:07 zmieniony
       
      W programie "ODCZYT" dopisz linię:

      15 TEKST2$="..........."

      zamiast kropek możesz wpisać 11 dowolnych znaków.
      Jak nie dojdziesz dlaczego tak jest, to daj znać ;)

      Program numer 3 ładuje dane bezpośrednio do pamięci obrazu. ANTIC jednak nie wyświetla znaków w kodzie ATASCII, tylko tzw. INTERNAL (w książce p.Miguta "Atari Basic" określone są jako kody PEEK/POKE, a w instrukcji do QA jako kody ekranowe) i dlatego pokazują się znaczki-dziwaczki :)
      • 5: CommentAuthormono
      • CommentTime11 Jul 2010 17:07 zmieniony
       
      Tak jest, ponieważ zawartość stringa jest gdzie indziej w pamięci, niż struktura z informacją o zmiennej przechowującej string (stringi w basicu nie są terminowane zerem jak w c, lecz ich długość jest zapisana w strukturze informacyjnej).
      Jeśli wiesz ile bajtów ma mieć string zrób po prostu
      A$(długość)=""

      co ustawi aktualną długość stringa w strukturze a nie zmieni zawartości pamięci.
      Każda zmienna w basicu jest opisywana 8-bajtową strukturą, w której zapisane są: jej typ, wartość (w przypadku zmiennej numerycznej), adres (w przypadku zmiennej tablicowej oraz stringów), jej zadeklarowany rozmiar (w przypadku tablic i stringów) i jej aktualny rozmiar (w przypadku stringów). Ta tablica znajduje się w pamięci przed kodem programu...

      Edit: ...i jest tworzona (co wiąże się z przesuwaniem pamięci programu i obszaru tablic/ciągów) podczas wprowadzania wierszy programu.