home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1997 #3 / amigamamagazinepolishissue03-1 / ma_1995 / 06 / ami071.txt < prev    next >
Text File  |  1997-04-07  |  13KB  |  434 lines

  1. /* wyraûenia zawarte w >...< proszë pogrubiê */
  2.  
  3. 10 RAZY E
  4.  
  5. <a>Rafaî Wiosna
  6.  
  7. <txt>Tym razem bez zbëdnych wstëpów przystâpimy do omawiania
  8. nowego typu danej:
  9.  
  10. <sr>Listy
  11.  
  12. <txt>Stanowiâ podstawë jëzyka LISP. Moûna je traktowaê jako
  13. ciâgi, których elementami sâ nie znaki (CHAR), ale wskaúniki
  14. (LONG, czyli liczby 4-bajtowe -- longi). Zupeînie jak ARRAY OF
  15. LONG, tablica wskaúników. Listy majâ jednak të przewagë nad
  16. tablicami, ûe ich rozmiar moûe byê zmieniony. Mówiâc dokîadniej,
  17. rozmiar E-list moûe byê zmieniony, gdyû podobnie jak przy
  18. ciâgach, Amiga E dba o definiowane przez uûytkownika listy, a co
  19. za tym idzie, musi gdzieô skîadowaê pewne nadmiarowe informacje
  20. (nie sâ one dostëpne dla uûytkownika). Normalne listy sâ podobne
  21. do, wspomnianych dwa odcinki temu, zwykîych ciâgów -- nie moûna
  22. na nich prowadziê ûadnych operacji, posîugujâc sië specjalnymi
  23. funkcjami, chyba ûe jej opis na to pozwala. W przeciwieïstwie do
  24. ciâgów, lista nie musi zawieraê staîych (ciâg zawsze zawiera
  25. okreôlony napis), jej elementami mogâ byê zmienne.
  26.  
  27. Listy zapisujemy uûywajâc nawiasów kwadratowych. Wewnâtrz nich,
  28. porozdzielane przecinkami, powinny sië znajdowaê elementy listy.
  29. Po jej zdefiniowaniu zwracany jest wskaúnik, oznaczajâcy
  30. poîoûenie w pamiëci.
  31.  
  32. Oto pierwszy przykîad z uûyciem listy:
  33.  
  34. <l>DEF lista:PTR TO LONG, liczba
  35.  
  36. liczba:=22
  37.  
  38. lista:=[1,2,3,liczba]
  39.  
  40. <txt>Jak juû wspomniaîem, lista jest rozszerzonâ wersjâ tablicy
  41. wskaúników.  Tak wiëc moûna by byîo napisaê tak:
  42.  
  43. <l>DEF lista[4]:ARRAY OF LONG, liczba
  44.  
  45. liczba:=22
  46.  
  47. lista[0]:=1
  48.  
  49. lista[0]:=2
  50.  
  51. lista[0]:=3
  52.  
  53. lista[0]:=liczba
  54.  
  55. <txt>Którâ wersjë wybierzesz, zaleûy tylko od Ciebie. Jednak, jak
  56. sië okaûe, korzystanie z list moûe uczyniê Twój program
  57. îatwiejszym do napisania i odczytania (pamiëtaj teû o
  58. komentarzach, bez nich po miesiâcu zupeînie niepotrzebnie
  59. bëdziesz sië zastanawiaî, "co ja chciaîem tu napisaê?"). Poza tym
  60. listy dajâ o wiele wiëcej niû tablice, ale o tym póúniej.
  61.  
  62. Róûnicë miëdzy zwykîymi listami a E-listami moûna ujâê jednym
  63. zdaniem.  E-listy definiujesz w DEF-ach procedury, okreôlajâc jej
  64. elementy potem, zwykîâ listë definiujesz w dowolnym miejscu i od
  65. razu okreôlasz jej elementy. E-listë, jak juû zauwaûyîeô,
  66. definiuje sië w nastëpujâcy sposób:
  67.  
  68. <l>DEF lista[30]:LIST
  69.  
  70. <txt>Powyûszy przykîad zdefiniowaî listë o zaskasujâco
  71. oryginalnej nazwie "lista". Moûe ona liczyê maksymalnie 30
  72. elementów (zupeînie jak przy E-ciâgach, tylko pamiëtaj, ûe tu
  73. jeden element to wskaúnik-LONG, a nie bajt-CHAR). Przy okazji
  74. zmienna o nazwie "lista" wskazuje na obszar pamiëci zarezerwowany
  75. przez definicjë.
  76.  
  77. Listy sâ bardzo pomocne przy tworzeniu tzw. tagów, czyli wîaônie
  78. list. Odsyîam do czwartego odcinka kursu E, gdzie ta kwestia
  79. byîa szeroko omówiona.
  80.  
  81. Amiga E oferuje programiôcie zestaw funkcji operujâcych na
  82. listach.  Podobieïstwo do ciâgów jest znaczne, zarówno w nazwach
  83. funkcji, jak i ich przeznaczeniu. Takûe caîy mëtlik ze zwykîymi
  84. listami i E-listami jest niemalûe taki sam, jak w wypadku ciâgów
  85. i E-ciâgów. Dla przypomnienia: dîugoôê E-ciâgu moûe byê dowolnie
  86. zmieniana przez odpowiednie funkcje, a takûe E-ciâg jest zgodny
  87. "w dóî" z ciâgiem, co oznacza tyle, ûe wszëdzie tam, gdzie
  88. funkcja oczekuje podania zwykîego ciâgu, moûna wpisaê E-ciâg.
  89. Dokîadnie tak samo jest z listami. Wîaôciwie mógîbym przepisaê
  90. poczâtek tego akapitu, zastëpujâc sîowo "ciâg" sîowem "lista"...
  91.  
  92. Pierwszâ funkcjâ, zwiâzanâ z listami, jest >List(MAX)<. Funkcja
  93. ta (tu kompletne zaskoczenie) rezerwuje w pamiëci miejsce na
  94. E-listë o MAX elementach.
  95.  
  96. <l>DEF lista[30]:LIST
  97.  
  98. <txt>to to samo co:
  99.  
  100. <l>DEF lista:PTR TO LONG
  101.  
  102. lista:=List(30)
  103.  
  104. <txt>Funkcja zwraca wskaúnik do obszaru pamiëci, zarezerwowanego
  105. na nowo tworzonâ listë. Moûe teû zwróciê zero (NIL), co bëdzie
  106. oznaczaê, ûe system nie przydzieliî pamiëci ("I'm very sorry, out
  107. of memory"). Pamiëtaj, ûe zawsze naleûy sprawdzaê, czy funkcje
  108. podobne do List(), które rezerwujâ jakiô element w pamiëci, nie
  109. zwracajâ NIL. Inaczej, Twój program moûe spektakularnie zawiesiê
  110. czyjô komputer, chyba ûe stosujesz narzëdzia opracy, czyli
  111. opisane w numerach 12/94 i 1/95 MA programiki do testowania
  112. software (w tym wypadku chodzi o Memoration). Przy okazji:
  113. pamiëê zarezerwowana przez List() jest automatycznie zwalniana
  114. przy wyjôciu z programu.
  115.  
  116. Nastëpnâ funkcjâ jest >ListCmp(LISTA1,LISTA2,DÎUGOÔÊ=ALL)<, która
  117. porównuje zawartoôê dwóch list lub E-list (lub E-listy i listy).
  118. Trzecim parametrem jest liczba porównywanych elementów list.
  119. Jeûeli go opuôcimy lub wpiszemy "ALL" (co jest wymagane w Amiga E
  120. 2.x, dopiero od trójki moûna uûywaê parametrów domyôlnych),
  121. porównane zostanâ wszstkie elementy list. Oto przykîady, dla
  122. których funkcja ListCmp() zwraca TRUE:
  123.  
  124. <l>ListCmp([1,2,3,4],[1,2,3,4])
  125.  
  126. ListCmp([1,2,3,4],[1,2,3,7],3)
  127.  
  128. ListCmp([1,2,3,4,5],[1,2,3],3)
  129.  
  130. <txt>Zauwaû, ûe w przykîadach uûyîem samych list, nie E-list, ale
  131. w tym wypadku nie ma to wiëkszego znaczenia. Waûny natomiast jest
  132. fakt, ûe ListCmp() porównuje elementy listy jako WARTOÔCI. Tak
  133. wiëc listy zawierajâce wskaúnik do ciâgów, które tak samo
  134. wyglâdajâ:
  135.  
  136. <l>['blablabla',2,3] i ['blablabla',2,3]
  137.  
  138. <txt>bëdâ dla ListCmp() RÓÛNE, gdyû pokazane tu ciâgi sâ
  139. reprezentowane przez róûne wskaúniki do nich.
  140.  
  141. Typowâ funkcjâ jest >ListCopy(E-LISTA,LISTA,DÎUGOÔÊ=ALL)<. Jak
  142. moûna sië domyôliê, dziaîa ona tak samo jak StrCopy() z ciâgami
  143. -- kopiuje (E-)listë okreôlonâ przez drugi parametr do E-listy
  144. okreôlonej pierwszym. Przy okazji, moûna okreôliê teû liczbë
  145. kopiowanych elementów listy (parametr trzeci, domyôlnie --
  146. wszystkie). Oto przykîad pokazujâcy, jak naleûy stworzyê E-listë:
  147.  
  148. <l>DEF li[7]:LIST, blabla
  149.  
  150. blabla:=4
  151.  
  152. ListCopy(li, [1,2,3,blabla])
  153.  
  154. <txt>W wyniku wykonania powyûszego przykîadu powstanie nowa,
  155. uômiechniëta, czteroelementowa E-lista. Gdyby próbowaê funckcjâ
  156. ListCopy() skopiowaê do E-listy "li" (E-)listë o liczbie
  157. elementów wiëkszej niû siedem, to kompilator sam zadba o to, aby
  158. rozmiar "li", zdefiniowany w DEF-ach, nie zostaî przekroczony.
  159. (No i co na to zaparci zwolennicy asemblera?).
  160.  
  161. Funkcja >ListAdd(E-LISTA,LISTA,DÎUGOÔÊ=ALL)< dodaje do
  162. istniejâcej E-listy wszystkie (albo i nie) elementy listy,
  163. bëdâcej drugim argumentem funkcji.  Tak jak w poprzednim
  164. przykîadzie, trzeci argument oznacza liczbë elementów (w tym
  165. wypadku) dodawanych do E-listy (domyôlnie -- wszystkie).
  166. Kompilator zadba o to, aby zadeklarowany rozmiar E-listy nie
  167. zostaî przekroczony.
  168.  
  169. Kolejne trzy funkcje nie wymagajâ przykîadów, gdyû sâ niemal
  170. identyczne z fukcjami operujâcymi na (E-)ciâgach.
  171. >ListLen(LISTA)< podaje liczbë elementów (E-)listy, bëdâcej
  172. argumentem funkcji. Podobna do niej jest inna funkcja,
  173. >ListMax(E-LISTA)<, która zwraca maksymalny rozmiar podanej
  174. E-listy. Przydatna jest jeszcze funkcja
  175. >SetList(E-LISTA,DÎUGOÔÊ)<, która okreôla dîugoôê E-listy,
  176. obcinajâc nadmiarowe elementy z tyîu.  Zadeklarowana w drugim
  177. argumencie nowa dîugoôê E-listy nie moûe przekraczaê dîugoôci
  178. zadeklarowanej w DEF-ach.
  179.  
  180. Bardzo przydatnâ funkcjâ jest >ListItem(LISTA,ELEMENT)<. Zwraca
  181. ona wskaúnik do danego elementu (E-)listy. Porównujâc do tablic
  182. moûna stwierdziê, ûe jeûeli "li" jest listâ, to "ListItem(li,3)"
  183. jest odpowiednikiem wyraûenia "li[3]". Oto przykîad
  184. podrëcznikowy:
  185.  
  186. <l>WriteF(ListItem(['pc-zîom','szmatari','Amiga','jabol'],2))
  187.  
  188. <txt>wypisze na ekranie nazwë naszego ulubionego komputera. (Przy
  189. okazji wychodzi na jaw, ûe elementy listy numerowane sâ od 0, a
  190. nie od 1). A oto przykîad z ûycia wziëty:
  191.  
  192. <l>ENUM OKAY,RTOPEN,SCROPEN,WINOPEN,FONTOPEN
  193.  
  194. PROC main() HANDLE
  195. ...
  196.  
  197.  
  198. EXCEPT
  199.  
  200. WriteF('Wystâpiî bîâd \d: \s\n',ListItem(
  201.     ['nie moûna otworzyê reqtools.library',
  202.     'nie moûna otworzyê ekranu',
  203.     'nie moûna otworzyê okna',
  204.     'nie moûna otworzyê czcionki'],exception))
  205.  
  206. <sr>Nie tylko LONG
  207.  
  208. <txt>Jednâ z zalet list jest fakt, ûe nie muszâ one zawieraê
  209. tylko danych typu LONG. Programista moûe w dowolny wîaôciwie
  210. sposób ksztaîtowaê pojedynczy element listy. Moûe to byê dana
  211. typu CHAR, INT, LONG lub typu definiowanego przez uûytkownika.
  212. Najpierw jednak krótkie wyjaônienie tego terminu.
  213.  
  214. Typ definiowany przez uûytkownika jest okreôlany w Amiga E jako
  215. obiekt (OBJECT). Jest to odpowiednik struktury w C/C++, klasy w
  216. C++ lub rekordu w Pascalu. Nie bëdziemy sië zagîëbiaê w dokîadne
  217. omówienie obiektów, wystarczy krótki przykîad:
  218.  
  219. <l>OBJECT osoba
  220.  
  221.     imie:PTR TO CHAR
  222.  
  223.     nazwisko:PTR TO CHAR
  224.  
  225.     wiek:BYTE
  226.  
  227.     funkcja:PTR TO CHAR
  228.  
  229. ENDOBJECT
  230.  
  231. <txt>Na razie przyjmij bez tîumaczenia fakt, ûe zdefiniowaliômy
  232. nowy typ danej -- "osoba". Skîada sië on z trzech pól,
  233. "osoba.imië" (wzkaúnik), "osoba.nazwisko" (wskaúnik),
  234. "osoba.wiek" (bajt) i "osoba.funkcja" (wzkaúnik). Podobnie jak
  235. zmienne, obiekty moûna definiowaê globalnie (przed "PROC main()"
  236. jak i lokalnie). Wszystkie struktury systemowe sâ obiektami.
  237.  
  238. No dobra, powróêmy do list. Otóû listë z okreôlonym typem danej
  239. (z angielska -- typed list) definiuje sië przez dodanie ":TYP" do
  240. jej definicji, np.:
  241.  
  242. <l>[1,2,3,4]:INT
  243.  
  244. <txt>Oznacza listë o danych typu INT. No i tu sië drogi
  245. rozwidlajâ, gdyû definiujâc takâ listë odcinamy sië od
  246. wymienionych wczeôniej funkcji, operujâcych na (E-)listach. Po
  247. prostu na tym typie list nie bëdâ one dziaîaîy. Ûeby byîo
  248. ômieszniej, dwie listy:
  249.  
  250. <l>[1,2,3,4] oraz [1,2,3,4]:LONG
  251.  
  252. <txt>mimo tego, ûe uûywajâ tego samego typu danej, nie sâ ze sobâ zgodne!
  253.  
  254. Czas na przykîad uûywania "typed lists".
  255.  
  256. <txt>OBJECT osoba
  257.  
  258.     imie:PTR TO CHAR
  259.  
  260.     nazwisko:PTR TO CHAR
  261.  
  262.     wiek:CHAR
  263.  
  264.     funkcja:PTR TO CHAR
  265.  
  266. ENDOBJECT
  267.  
  268.  
  269. DEF bajty:PTR TO CHAR, mag_amiga:PTR TO osoba, los
  270.  
  271.  
  272. PROC main()
  273.  
  274.  
  275. bajty:=[1,2,3,4]:INT
  276.  
  277.  
  278. mag_amiga:=['Marek','Pampuch',98,'red nacz',
  279.  
  280.     'Rafal','Wiosna',56,'z-ca red nacz',
  281.  
  282.     'Elzbieta','Kozakiewicz',19,'sekr red',
  283.  
  284.     'Roman','Sadowski',73,'gry']:osoba
  285.  
  286.  
  287. los:=Rnd(4)
  288.  
  289.  
  290. WriteF('Gîodówka Rotacyjna V3.59 (c) 1995 Dyrekcja\n')
  291.  
  292.  
  293. WriteF('Dziô gîoduje: \s \s, nasz \s (wiek \d)\n',
  294.  
  295.     mag_amiga[los].imie,
  296.  
  297.     mag_amiga[los].nazwisko,
  298.  
  299.     mag_amiga[los].funkcja,
  300.  
  301.     mag_amiga[los].wiek)
  302.  
  303.  
  304. ENDPROC
  305.  
  306. <sr>Dane statyczne
  307.  
  308. <txt>Ciâgi i listy (nie myliê z E-ciâgami i E-listami) sâ danymi
  309. statycznymi. Znaczy to, ûe adres w pamiëci jednego z wymienionych
  310. typów danych jest zawsze na poczâtku programu okreôlony. Zwykle
  311. nie musisz sië tym przejmowaê, ale gdy zachce Ci sië stworzyê
  312. tablicë skîadajâcâ sië z list o elementach obliczanych przez
  313. program, zapewne napisaîyô coô takiego:
  314.  
  315. <l>PROC main()
  316.  
  317. DEF i, a[10]:ARRAY OF LONG, p:PTR TO LONG
  318.  
  319. FOR i:=0 TO 9
  320.  
  321.     a[i]:=[1, i, i*i] -> BÎÂD!
  322.  
  323. ENDFOR
  324.  
  325. FOR i:=0 TO 9
  326.  
  327.     p:=a[i]
  328.  
  329.     WriteF('a[\d] zawiera listë o adresie \d\n', i, p)
  330.  
  331.     WriteF('Drugim elementem tej listy jest \d\n', p[1])
  332.  
  333. ENDFOR
  334.  
  335. ENDPROC
  336.  
  337.  
  338. Amiga E Compiler/Assembler/Linker/PP v3.1a (c) '91-95 Wouter
  339.  
  340. lexical analysing ...
  341.  
  342. parsing and compiling ...
  343.  
  344. no errors
  345.  
  346. a[0] zawiera listë o adresie 19748938
  347.  
  348. Drugim elementem tej listy jest 9
  349.  
  350. a[1] zawiera listë o adresie 19748938
  351.  
  352. Drugim elementem tej listy jest 9
  353.  
  354. a[2] zawiera listë o adresie 19748938
  355.  
  356. Drugim elementem tej listy jest 9
  357.  
  358. a[3] zawiera listë o adresie 19748938
  359.  
  360. Drugim elementem tej listy jest 9
  361.  
  362. <txt>No i jesteô ugotowany. Tablica "a" zawiera wskaúniki do
  363. trzyelementowej STATYCZNEJ listy! Znaczy to, ûe jej adres jest z
  364. góry okreôlony przez kompilator i sië nie zmienia.
  365.  
  366. Zaradziê temu problemowi moûna na kilka sposobów, jednak
  367. najproôciej jest uûyê funkcji List(), która dynamicznie
  368. zarezerwuje E-listë. Oto "dobra" wersja programu:
  369.  
  370. <l>PROC main()
  371.  
  372. DEF i, a[10]:ARRAY OF LONG, p:PTR TO LONG
  373.  
  374. FOR i:=0 TO 9
  375.  
  376.     a[i]:=List(3)
  377.  
  378.     ListCopy(a[i],[1, i, i*i])
  379.  
  380. ENDFOR
  381.  
  382. FOR i:=0 TO 9
  383.  
  384.     p:=a[i]
  385.  
  386.     WriteF('a[\d] zawiera listë o adresie \d\n', i, p)
  387.  
  388.     WriteF('Drugim elementem tej listy jest \d\n', p[1])
  389.  
  390. ENDFOR
  391.  
  392. ENDPROC
  393.  
  394.  
  395. Amiga E Compiler/Assembler/Linker/PP v3.1a demo (c) '91-95 Wouter
  396.  
  397. lexical analysing ...
  398.  
  399. parsing and compiling ...
  400.  
  401. no errors
  402.  
  403. a[0] zawiera listë o adresie 19200232
  404.  
  405. Drugim elementem tej listy jest 0
  406.  
  407. a[1] zawiera listë o adresie 19200696
  408.  
  409. Drugim elementem tej listy jest 1
  410.  
  411. a[2] zawiera listë o adresie 19200728
  412.  
  413. Drugim elementem tej listy jest 2
  414.  
  415. <txt>No i o to chodziîo!
  416.  
  417. <sr>*
  418.  
  419. <txt>Na nastëpny odcinek zostawiîem gwóúdú wykîadu z list --
  420. listy îâczone. Tymczasem proponujë poszukaê archiwów CAPUS.LHA i
  421. CAPUS2.LHA. Sâ to zestawy przeróûnych uûytków, utorstwa Capus
  422. André (francuz, "dziëki" czemu niektóre opisy sâ w tym
  423. niezrozumiaîym jëzyku), kaûdy napisany w E, z peînym kodem
  424. úródîowym. Wspaniale nadajâ sië jako materiaî dydaktyczny do
  425. nauki Amiga E. Oprócz tego w archiwum znajdujâ sië gotowe moduîy
  426. (.m) do przeróûnych bibliotek (np. lh.library, nofrag.library,
  427. xpk.library)!!!
  428.  
  429. Archiwa te moûna znaleúê w Aminecie, w katalogu dev/e, oraz w
  430. naszym redakcyjnym BBS-ie.
  431.  
  432. <przyp>Literatura: Jason R. Hulance, plik "Beginners.guide"
  433. rozprowadzany z Amiga E 3.x.
  434.