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?
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).
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.
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 :)
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.