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:

Action!
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:

Action!
scores(0)=100        ; zápis do prvého prvku
x=scores(3)          ; čítanie štvrtého prvku
scores(i)=scores(i)+1

Celý program

Súbor examples/arrays.act:

Action!
; 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")
RETURN

Preklad 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 days

Ako to funguje

Pole a slučka FOR patria k sebe: počítadlo slučky je index.

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:

Action!
PROC Fill(BYTE ARRAY a, BYTE count)
  BYTE i

  FOR i=0 TO count-1
  DO
    a(i)=i*2
  OD
RETURN

Volanie: 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é:

Action!
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ľaprepíše sa cudzia pamäť; bez hlásenia
slučka FOR i=1 TO 10 nad poľom s 10 prvkamiprvok (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

  1. Vypíš mesiace, ktoré majú 30 dní – ich čísla od 1 do 12, nie indexy.
  2. Načítaj päť čísel do poľa a vypíš ich v opačnom poradí. (Odpočítavať treba cez WHILE, kapitola 13.)
  3. Vypočítaj priemer prvkov poľa squares.

Zhrnutie

Späť: 17. Mená pre čísla · Ďalej: 19. Reťazce