18. Polia: ARRAY
Na čo to je
Dvanásť mesiacov, sto nepriateľov, tisíc bodov obrazovky – na to nechceš dvanásť, sto ani tisíc premenných. Pole je rad hodnôt rovnakého typu pod jedným menom. Jednotlivé hodnoty (prvky) sa rozlišujú číslom – indexom.
Ako sa to píše
Deklarácia:
BYTE ARRAY scores(10) ; 10 prvkov typu BYTE
CARD ARRAY squares(10) ; 10 prvkov typu CARD
INT ARRAY heights(50) ; 50 prvkov typu INT
BYTE ARRAY days=[31 28 31 30] ; pole s hodnotami; veľkosť sa spočíta sama
Použitie prvku:
scores(0)=100 ; zápis do prvého prvku
x=scores(3) ; čítanie štvrtého prvku
scores(i)=scores(i)+1- Číslo v zátvorke pri deklarácii je počet prvkov.
- Indexy idú od 0. Pole s 10 prvkami má prvky
(0)až(9). Prvok(10)neexistuje. - Index môže byť číslo, premenná aj výraz.
- Počiatočné hodnoty sa píšu do hranatých zátvoriek a oddeľujú sa medzerami (čiarky medzi nimi prekladač tiež prijme).
Celý program
Súbor examples/arrays.act:
; Arrays: many values under one name
PROC Main()
BYTE ARRAY days=[31 28 31 30 31 30 31 31 30 31 30 31]
CARD ARRAY squares(10) ; 10 elements: squares(0) to squares(9)
BYTE i, biggest
CARD total
FOR i=0 TO 9 ; fill the array in a loop
DO
squares(i)=i*i
OD
Print("Squares: ")
FOR i=0 TO 9
DO
PrintC(squares(i)) Put(' )
OD
PutE()
Print("Days in March: ")
PrintBE(days(2)) ; January is days(0)
total=0
FOR i=0 TO 11
DO
total==+days(i)
OD
Print("Days in a year: ")
PrintCE(total)
days(1)=29 ; an element can be changed
Print("February in a leap year: ")
PrintBE(days(1))
biggest=0
FOR i=0 TO 11
DO
IF days(i)>biggest THEN
biggest=days(i)
FI
OD
Print("The longest month has ")
PrintB(biggest)
PrintE(" days")
RETURNPreklad a spustenie
action26 arrays.act --simČo uvidíš
Squares: 0 1 4 9 16 25 36 49 64 81
Days in March: 31
Days in a year: 365
February in a leap year: 29
The longest month has 31 daysAko to funguje
Pole a slučka FOR patria k sebe: počítadlo slučky je index.
- Naplnenie:
squares(i)=i*ipreiod 0 do 9. - Výpis: tá istá slučka, len sa prvok číta.
- Súčet: pred slučkou
total=0, v slučketotal==+days(i). - Hľadanie najväčšieho:
biggestzačne na 0 a každý prvok, ktorý je väčší, ho nahradí.
days(2) je marec, nie február – január má index 0. Posun o jednotku je najčastejší zdroj chýb pri poliach.
Pole ako parameter
Rutina môže dostať pole. V parametri sa píše bez veľkosti:
PROC Fill(BYTE ARRAY a, BYTE count)
BYTE i
FOR i=0 TO count-1
DO
a(i)=i*2
OD
RETURNVolanie: Fill(scores, 10). Na rozdiel od obyčajnej premennej (kapitola 14) sa pole nekopíruje – rutina pracuje priamo s poľom volajúceho a zmeny v ňom ostanú. Veľkosť poľa rutina nepozná, preto sa odovzdáva zvlášť.
Najväčšie nebezpečenstvo: index mimo poľa
Action! nekontroluje, či je index v rozsahu poľa. Zápis za koniec poľa prepíše to, čo leží v pamäti za ním – zvyčajne iné premenné:
BYTE ARRAY a(3)
BYTE x
x=7
a(3)=9 ; a má len prvky 0, 1, 2
PrintBE(x) ; vypíše 9
Prekladač nič nehlási, program beží a chyba sa prejaví inde a neskôr. Keď sa premenná „sama“ mení, hľadaj pole pred ňou a slučku, ktorá ide o jeden prvok ďalej (TO 10 namiesto TO 9).
Časté chyby
| Čo sa stalo | Čo sa stane |
|---|---|
| index mimo poľa | prepíše sa cudzia pamäť; bez hlásenia |
slučka FOR i=1 TO 10 nad poľom s 10 prvkami | prvok (0) sa vynechá a (10) je mimo poľa |
priradenie do celého poľa (a=5) | error ACT010: illegal assignment: cannot assign to BYTE ARRAY 'a' |
pole bez hodnôt a bez veľkosti (BYTE ARRAY a) | nie je to pole s pamäťou, len ukazovateľ – kapitola 20 |
Prvky poľa bez počiatočných hodnôt nemusia byť nulové. Pred použitím ich naplň.
Vyskúšaj si
- Vypíš mesiace, ktoré majú 30 dní – ich čísla od 1 do 12, nie indexy.
- Načítaj päť čísel do poľa a vypíš ich v opačnom poradí. (Odpočítavať treba cez
WHILE, kapitola 13.) - Vypočítaj priemer prvkov poľa
squares.
Zhrnutie
TYP ARRAY meno(počet)deklaruje pole; prvky súmeno(0)ažmeno(počet−1).TYP ARRAY meno=[h1 h2 h3]deklaruje pole s hodnotami.- Pole sa spracúva slučkou
FOR. - Pole ako parameter sa nekopíruje.
- Index mimo poľa sa nekontroluje a prepíše inú pamäť.
Späť: 17. Mená pre čísla · Ďalej: 19. Reťazce