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
     
    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 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
     
    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 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 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.