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

  1. /* >...< pogrubiê i nie zmieniaê tytuîu!*/
  2.  
  3. siEdem
  4.  
  5. <a>Rafaî Wiosna
  6.  
  7. <txt>Witam wszystkich zwolenników E w siódmym juû wydaniu naszego
  8. cyklu. Rozpocznë bez zbëdnych wstëpów, przypominajâc o tym, ûeby
  9. dla rozluúnienia mózgownicy zapuôciê jakiô dobry muzak w tîo. Tym
  10. razem polecam krâûek Tori Amos "Under The Pink".
  11.  
  12. W dzisiejszym odcinku rozwinë przedstawianie zestawu komend,
  13. rzâdzâcych przebiegiem programu. W poprzednich dwóch odcinkach
  14. wyjaôniîem zasadë obsîugi bîëdów, jak i konstrukcjë SELECT, teraz
  15. przyszîa pora na...
  16.  
  17. <sr>IF
  18.  
  19. <txt>Instrukcje warunkowe sâ jednymi z podstawowych konstrukcji
  20. uûywanych w programowaniu. To wiekopomne stwierdzenie nie wymaga
  21. chyba ûadnego komentarza. Przyjrzyjmy sië, "jak sië to robi w E":
  22.  
  23. <l>IF warunek_1
  24.  
  25.     instrukcje_1
  26.  
  27. ELSEIF warunek_2
  28.  
  29.     instrukcje_2
  30.  
  31. ELSE
  32.  
  33.     instrukcje_3
  34.  
  35. ENDIF
  36.  
  37. <txt>Moûna to przetîumaczyê jako:
  38.  
  39. ^* Jeôli 'warunek_1' jest speîniony (tzn. w wyniku daje TRUE lub
  40. dowolnâ niezerowâ wartoôê), to wykonaj 'instrukcje_1'.
  41.  
  42. ^* Jeôli 'warunek_1' nie jest speîniony (tzn. w wyniku daje FALSE
  43. lub wartoôê zero), NATOMIAST 'warunek_2' jest speîniony, wykonaj
  44. 'instrukcje_2'.
  45.  
  46. ^* Jeôli 'warunek_1' oraz 'warunek_2' nie sâ speînione, to wykonaj
  47. 'instrukcje_3'.
  48.  
  49. Czëôê ELSEIF moûe byê powtarzana wiele razy. Natomiast czëôê ELSE
  50. moûna ominâê (wtedy nie bëdzie ûadnej reakcji na niespeînienie
  51. warunku), ale jeûeli jest, MUSI byê ona umieszczona na samym
  52. koïcu konstrukcji, zaraz przed zamkniëciem bloku IF...ENDIF.
  53. Natomiast czëôci ELSEIF moûe byê dowolna liczba, ale muszâ byê
  54. zawarte w bloku instrukcji IF...ELSE, co znaczy, ûe nie mogâ
  55. wystëpowaê w czëôci ELSE.
  56.  
  57. Innâ formâ zapisu instrukcji warunkowej jest:
  58.  
  59. <l>IF warunek THEN instrukcja_1 ELSE instrukcja_2
  60.  
  61. <txt>Uûywajâc tej konwencji, nie moûna wykorzystywaê ELSEIF oraz
  62. wszystko naleûy umieôciê w jednej linii.
  63.  
  64. Aby przybliûyê konstrukcjë IF...ELSEIF...ELSE...ENDIF, przytoczë
  65. kilka przykîadów jej uûycia:
  66.  
  67. <l>
  68.     IF x>0 THEN x:=x+1 ELSE x:=0
  69.  
  70.  
  71.  
  72.     IF x>0
  73.  
  74.         x:=x+1
  75.  
  76.     ELSE
  77.  
  78.         x:=0
  79.  
  80.     ENDIF
  81.  
  82.  
  83.  
  84.     IF x=0 THEN WriteF('x to zero\n')
  85.  
  86.  
  87.  
  88.     IF x=0
  89.  
  90.         WriteF('x to zero\n')
  91.  
  92.     ENDIF
  93.  
  94.  
  95.  
  96.     IF x<0
  97.  
  98.         Write('x jest ujemne\n')
  99.  
  100.     ELSIF x>2000
  101.  
  102.         Write('x jest za duûe\n')
  103.  
  104.     ELSIF (x=2000) OR (x=0)
  105.  
  106.         Write('Wartoôê graniczna x\n')
  107.  
  108.     ENDIF
  109.  
  110.  
  111.  
  112.     IF x>0
  113.  
  114.         IF x>2000
  115.  
  116.             WriteF('Za duûe x\n')
  117.  
  118.         ELSE
  119.  
  120.             WriteF('Dobre x\n')
  121.  
  122.         ENDIF
  123.  
  124.     ELSE
  125.  
  126.         IF x<-800 THEN WriteF('Za maîe x\n') ELSE Write('Ujemne, ale dobre x')
  127.  
  128.     ENDIF
  129.  
  130. <txt>W ostatnim przykîadzie zastosowano tzw. zagnieûdûone bloki
  131. warunkowe (tzn. IF...ENDIF wewnâtrz innego bloku IF...ENDIF). Dla
  132. lepszego zaznaczenia tej sytuacji, a takûe do podkreôlenia
  133. czytelnoôci warto stosowaê wciëcia. Wtedy nie bëdzie problemów z
  134. rozróûnieniem zagnieûdûonych instrukcji ELSE (tzn. do którego
  135. IF-a sië stosuje).
  136.  
  137. W tym miejscu naleûy zwróciê uwagë, ûe warunki zawarte po
  138. instrukcjach IF i ELSEIF nie powinny sië nakîadaê. Spójrzmy na
  139. przykîad:
  140.  
  141. <l>
  142. IF x>0
  143.  
  144.     WriteF('x jest wiëksze od zera\n')
  145.  
  146. ELSEIF x>200
  147.  
  148.     WriteF('x jest wiëksze niû 200\n')
  149.  
  150. ELSE
  151.  
  152.     WriteF('x jest za maîe\n')
  153.  
  154. ENDIF
  155.  
  156. <txt>Blok instrukcji po ELSEIF nie zostanie NIGDY wykonany, gdyû
  157. warunki x>0 i x>200 wzajemnie sië na siebie nakîadajâ, a
  158. dokîadniej warunek x>200 wynika z warunku x>0. Proszë zwróciê
  159. uwagë, ûe przy zamianie warunków konstrukcja ta bëdzie dobra.
  160.  
  161. Konstrukcjë IF...THEN...ELSE (bez ENDIF!) moûna wykorzystaê nie
  162. tylko w blokach warunkowych, ale takûe przy obliczaniu wartoôci.
  163. Oto przykîad:
  164.  
  165. <l>
  166. IF x>0
  167.  
  168.     y:=x+1
  169.  
  170. ELSE
  171.  
  172.     y:=0
  173.  
  174. ENDIF
  175.  
  176. <txt>Takâ czësto spotykanâ konstrukcjë moûna zastâpiê jednâ liniâ
  177. kodu úródîowego:
  178.  
  179. <l>
  180. y:=(IF x>0 THEN x+1 ELSE 0)
  181.  
  182. <txt>Umieszczenie IF...THEN...ELSE w nawiasie nie jest niezbëdne,
  183. ale poprawia czytelnoôê kodu programu. Taki zapis konstrukcji
  184. warunkowej róûni sië od przedstawionego wczeôniej gîównie jednâ
  185. rzeczâ: tutaj instruckja ELSE jest niezbëdna.
  186.  
  187. Teraz czas na omówienie pëtli.
  188.  
  189. <sr>FOR
  190.  
  191. <txt>Pëtle pozwalajâ na wielokrotne wykonywanie serii instrukcji.
  192. Najprostszâ formâ pëtli jest pëtla FOR, szeroko znana z BASIC-a.
  193.  
  194. Jeôli, nie wiadomo czemu, chcesz wypisaê na ekranie wszystkie
  195. liczby od jednego do stu, moûesz to zrobiê na dwa sposoby: albo
  196. wklepaê je rëcznie, zdzierajâc klawiaturë i palce, albo napisaê
  197. prosty program, który bëdzie uûywaî pëtli FOR:
  198.  
  199. <l>
  200. PROC main()
  201.  
  202.     DEF x
  203.  
  204.     FOR x:=1 TO 100
  205.  
  206.         WriteF('\d ', x)
  207.  
  208.     ENDFOR
  209.  
  210.     WriteF('\n')
  211.  
  212. ENDPROC
  213.  
  214. <txt>Pamiëtaj o wpisaniu spacji po \d w czwartej linii! Po
  215. skompilowaniu zobaczysz na ekranie wielce zajmujâce rzâdki cyfr,
  216. tak jak chciaîeô. Program dziaîa nastëpujâco:
  217.  
  218. ^* Definiowana jest zmienna lokalna o nazwie x (lokalna, gdyû
  219. definicja jest w ôrodku procedury).
  220.  
  221. ^* Nastëpnie instrukcja FOR rozpoczyna pëtle i przyporzâdkowuje
  222. zmiennej x wartoôê poczâtkowâ, czyli 1.
  223.  
  224. ^* Drukowana jest liczba, bëdâca wartoôciâ zmiennej x.
  225.  
  226. ^* Instrukcja ENDFOR koïczy pëtlë, dodaje jeden do zmiennej x i
  227. sprawdza, czy przekroczony zostaî limit wartoôci x, okreôlony na
  228. poczâtku pëtli. Jeûeli nie, wykonywany jest skok do pierwszej
  229. instrukcji po FOR, jeûeli tak -- bieg programu nie zostaje
  230. zmieniony. W BASIC-u ENDFOR nazywa sië NEXT oraz wymaga podania
  231. nazwy zmiennej, która ma byê zwiëkszona i sprawdzona. W E nie
  232. przewiduje tego, tutaj ENDFOR zamyka ostatnâ pëtlë otworzonâ
  233. instrukcjâ FOR.
  234.  
  235. ^* Na samym koïcu, ûeby îadnie zakoïczyê wydruk, drukowany jest
  236. znak nowej linii.
  237.  
  238. Ogólna forma pëtli FOR...ENDFOR jest nastëpujâca:
  239.  
  240. <l>FOR zmienna := wartoôê_1 TO wartoôê_2 STEP liczba
  241.  
  242.     instrukcje
  243.  
  244. ENDFOR
  245.  
  246. <txt>Pamiëtaj, ûe zmiennâ o niezwykle mówiâcej nazwie 'zmienna'
  247. naleûy wczeôniej zdefiniowaê dyrektywâ DEF (to nie BASIC!)
  248. 'wartoôê_1'okreôla poczâtkowâ wartoôê zmiennej 'zmienna',
  249. nadawanâ przez FOR przy rozpoczëciu pëtli. 'wartoôê_2' okreôla
  250. limit, którego przekroczenie (tzn. zmienna>wartoôê_2) koïczy
  251. pëtlë. Czëôê 'instrukcje' bëdzie wykonywana aû do przekroczenia
  252. limitu. Opcjonalnie 'liczba' okreôla, ile ENDFOR ma dodaê do
  253. zmiennej 'zmienna' (przed sprawdzeniem limitu). Jeûeli nie
  254. wpiszemy kawaîka 'STEP coôtam', ENDFOR domyôlnie bëdzie dodawaîo
  255. jeden. 'wartoôê_1' i 'wartoôê_2' mogâ byê wyraûeniami, a nie
  256. tylko liczbami, ale w tym wypadku bëdâ obliczone tylko raz, na
  257. samym poczâtku, a wyniki zostanâ potraktowane jako liczby.
  258. 'liczba' moûe byê tylko i wyîâcznie staîâ, nie moûe byê
  259. obliczana, ale za to moûe byê ujemna, ale naleûy wtedy pamiëtaê,
  260. ûe zmienia sië warunek koïcowy (wtedy ENDFOR oblicza
  261. zmienna<wartoôê_2). Uwaga: nie moûna napisaê 'STEP 0'.
  262.  
  263. Tak samo jak IF pëtlë FOR moûna zapisaê w jednej linii:
  264.  
  265. <l>
  266. FOR zmienna := wartoôê_1 TO wartoôê_2 STEP liczba DO instrukcja
  267.  
  268. <txt>Od tradycyjnego zapisu róûni sië tylko tym, ûe po 'DO' moûna
  269. wpisaê tylko jednâ instrukcjë.
  270.  
  271. <sr>WHILE
  272.  
  273. <txt>Pëtla WHILE róûni sië od FOR zasadniczo. Najwaûniejszâ
  274. róûnicâ jest to, ûe programista sam okreôla warunek koïczâcy
  275. wykonywanie pëtli. Druga waûna rzecz to fakt, ûe warunek jest za
  276. kaûdym razem obliczany i moûe byê okreôlony logicznie -- TRUE
  277. albo FALSE (co zresztâ kompilator zamienia na odpowiednio 1 i 0).
  278. Warunkiem moûe wiëc byê na przykîad wartoôê zwracana przez jakâô
  279. procedurë systemowâ.
  280.  
  281. Na przykîad, pasjonujâcy program wypisujâcy na ekranie liczby od 1 do
  282. 100 moûna napisaê z wykorzystaniem pëtli WHILE:
  283.  
  284. <l>
  285. PROC main()
  286.  
  287.     DEF x
  288.  
  289.     x:=1
  290.  
  291.     WHILE x<=100
  292.  
  293.         WriteF('\d ', x)
  294.  
  295.         x:=x+1
  296.  
  297.     ENDWHILE
  298.  
  299.     WriteF('\n')
  300.  
  301. ENDPROC
  302.  
  303. <txt>Wyglâda to na mniej efektywnâ konstrukcjë niû FOR...ENDFOR,
  304. ale w tym wypadku to prawda -- do prostych pëtli ze
  305. zwiëkszaniem/zmniejszaniem zmiennej o staîâ wartoôê FOR nadaje
  306. sië lepiej.
  307.  
  308. Dziaîanie programu jest proste: zdefiniowana zmienna x przybiera
  309. wartoôê 1. Nastëpnie otwierana jest pëtla WHILE...ENDWHILE,
  310. wykonywana DOPÓKI speîniony jest warunek x<=100. W jej ôrodku
  311. wypisywana jest na ekran liczba okreôlona wartoôciâ zmiennej x, a
  312. potem zmienna ta zwiëkszana jest o jeden.
  313.  
  314. Waûnâ wiadomoôciâ jest fakt, ûe warunek okreôlony w instrukcji
  315. WHILE sprawdzany jest PRZED wykonaniem pëtli. Oznacza to, ûe w
  316. ekstremalnym wypadku pëtla nigdy nie zostanie wykonana! Na
  317. przykîad, gdybyômy w powyûszym programie zmienili warunek na
  318. x>=100, pëtla nie byîaby wykonana, a bieg programu zostaîby
  319. przeniesiony za instrukcjë ENDWHILE.
  320.  
  321. WHILE ma teû, jak inne omawiane konstrukcje, wersjë jednoliniowâ:
  322.  
  323. <l>WHILE warunek DO instrukcja
  324.  
  325. <txt>Waûnym problemem, który pojawia sië przy wykorzystywaniu
  326. pëtli WHILE...ENDWHILE, a jak sië niedîugo okaûe nie tylko wtedy,
  327. jest zagroûenie wejôcia w pëtlë bez wyjôcia. Na przykîad, gdyby
  328. warunkiem WHILE byîo wyraûenie 1<2, instrukcje w ôrodku pëtli
  329. byîyby wykonywane aû do resetu komputera lub zatrzymania programu
  330. w sposób zewnëtrzny (np. poprzez 'zamroûenie' lub 'zabicie'
  331. odpowiedniego tasku programem ARTM). Oczywiôcie przykîad ten jest
  332. bezsensowny, gdyû nikt takiego warunku nie wpisze, ale moûe sië
  333. zdarzyê sytuacja, ûe warunek przybierze takâ postaê po jego
  334. obliczeniu.
  335.  
  336. <sr>REPEAT
  337.  
  338. <txt>Pëtla REPEAT...UNTIL jest bardzo podobna do
  339. WHILE...ENDWHILE. Tutaj jednakûe warunek jest obliczany PO
  340. wykonaniu caîej pëtli, w instrukcji UNTIL, która skacze na
  341. poczâtek pëtli wtedy, gdy warunek NIE JEST speîniony. Posîuûmy
  342. sië znowu nieômiertelnym programem 'Wypisz_Wszysykie_Liczby
  343. v1.0':
  344.  
  345. <l>
  346. PROC main()
  347.  
  348.     DEF x
  349.  
  350.     x:=1
  351.  
  352.     REPEAT
  353.  
  354.         WriteF('\d ', x)
  355.  
  356.         x:=x+1
  357.  
  358.     UNTIL x>100
  359.  
  360.     WriteF('\n')
  361.  
  362. ENDPROC
  363.  
  364. <txt>Przy porównaniu dwóch ostatnich wersji tego programu widaê
  365. subtelnâ róûnicë miëdzy REPEAT...UNTIL a WHILE...ENDWHILE.
  366. Najwaûniejszâ róûnicâ jest fakt, ûe pëtla zostanie wykonana co
  367. najmniej raz.
  368.  
  369. Przykîadem zastosowania WHILE w "prawdziwym" programie,
  370. korzystajâcym z systemu operacyjnego Amigi, moûe byê pëtla
  371. oczekujâca na wiadomoôci IDCMP. Jednoczeônie bardzo îadnie ona
  372. ilustruje wykorzystanie IF i ELSEIF:
  373.  
  374. <l>
  375. REPEAT
  376.  
  377.     mes:=Gt_GetIMsg(wnd.userport)
  378.  
  379.     type:=mes.class
  380.  
  381.     IF type=IDCMP_MENUPICK
  382.  
  383.         info:=mes.code
  384.  
  385.         menupick(info)    /* procedura obsîugujâca sytuacjë, gdy uûytkownik wybraî coô z menu */
  386.  
  387.     ELSEIF (type=IDCMP_GADGETDOWN) OR (type=IDCMP_GADGETUP)
  388.  
  389.         gadget:=mes.iaddress
  390.  
  391.         info:=g.gadgetid
  392.  
  393.         gadetaction(info) /* procedura obsîugujâca sytuacjë, gdy uûytkownik wcisnâî jakiô gadûet */
  394.  
  395.     ELSEIF type=IDCMP_REFRESHWINDOW
  396.  
  397.         Gt_BeginRefresh(wnd)
  398.  
  399.         Gt_EndRefresh(wnd,TRUE)
  400.  
  401.     ENDIF
  402.  
  403.     Gt_ReplyIMsg(mes)
  404.  
  405. UNTIL type<>IDCMP_CLOSEWINDOW
  406.  
  407. <txt>Taka albo podobna pëtla stanowi zwykle najczëôciej
  408. wykonywany fragment programu komunikujâcego sië z uûytkownikiem
  409. za pomocâ GUI (graficznego interfejsu).
  410.  
  411. <sr>*
  412.  
  413. <txt>Ooops, ale sië zapëdziîem. Dobra wiadomoôê! Dotarîa juû do
  414. Polski wersja 3.1a Amiga E, a w niej SOURCE LEVEL DEBUGGER!
  415. Niestety, zmiejszono limit wielkoôci kodu wynikowego,
  416. generowanego przez kompilator w wersji nie zarejestrowanej, z 12
  417. do 8 KB. A widzisz, nie trzeba byîo sië ociâgaê z kupnem
  418. rejestrowanej wersji E, to tylko 40 zielonych papierków (35 --
  419. jeôli masz Internet)...
  420.  
  421. <przyp>Literatura: Jason R. Hulance, plik 'Beginners.guide'
  422. rozprowadzany z Amiga E 3.x.
  423.  
  424.