21. Záznamy: TYPE
Na čo to je
Hráč má polohu, počet životov a skóre. Sú to štyri premenné, ktoré patria k sebe. Záznam (record) ich spojí do jedného celku s vlastným menom, takže sa dajú odovzdať rutine naraz.
Ako sa to píše
Najprv sa opíše typ záznamu – aké položky má:
TYPE Player=[BYTE x, y, lives
CARD score]TYPE Meno=[ … ]– v hranatých zátvorkách sú položky, zapísané ako deklarácie premenných.- Položky toho istého typu oddeľuje čiarka. Medzi skupinami typov sa čiarka nepíše – za
livesnasleduje rovnoCARD. - Položky môžu byť len základných typov:
BYTE,CHAR,CARD,INT. TYPEsa píše mimo rutín, na začiatok súboru.
Potom sa meno typu používa ako každý iný typ:
Player hero, enemy ; dve premenné typu Player
Player POINTER who ; ukazovateľ na záznam
hero.x=10 ; položka sa píše za bodku
who.score==+100 ; cez ukazovateľ rovnako, bez ^
Celý program
Súbor examples/records.act:
; Records: several values that belong together
TYPE Player=[BYTE x, y, lives
CARD score]
PROC Show(Player POINTER who)
Print("at ") PrintB(who.x)
Put(',) PrintB(who.y)
Print(" lives ") PrintB(who.lives)
Print(" score ") PrintCE(who.score)
RETURN
PROC Hit(Player POINTER who, CARD points)
who.score==+points
RETURN
PROC Main()
Player hero, enemy
hero.x=10
hero.y=5
hero.lives=3
hero.score=0
enemy.x=30
enemy.y=12
enemy.lives=1
enemy.score=500
Print("Hero: ") Show(hero)
Print("Enemy: ") Show(enemy)
Hit(hero, 250)
hero.x==+1
Print("Hero: ") Show(hero)
RETURNPreklad a spustenie
action26 records.act --simČo uvidíš
Hero: at 10,5 lives 3 score 0
Enemy: at 30,12 lives 1 score 500
Hero: at 11,5 lives 3 score 250Ako to funguje
Player hero, enemyvytvorí dva záznamy. Každý má vlastnéx,y,livesascore.hero.x=10zapíše do položkyxzáznamuhero.- Záznam sa rutine odovzdáva cez ukazovateľ. Parameter je
Player POINTER who. Pri volaní stačí napísať meno záznamu:Show(hero)– meno záznamu bez bodky je, podobne ako meno poľa, jeho adresa. - Vnútri rutiny sa položky píšu rovnako:
who.x. Znak^tu netreba. Hit(hero, 250)záznam mení. Keďže rutina dostala adresu, mení priamoherovMain.
Jedna rutina Show obslúži hrdinu aj nepriateľa. To je hlavný zmysel záznamov: rutiny sa píšu pre typ, nie pre jednu konkrétnu premennú.
Pole záznamov
Action! nemá Player ARRAY. Viac záznamov za sebou sa robí poľom bajtov a ukazovateľom, ktorý sa posúva o veľkosť záznamu. Meno typu vo výraze je veľkosť záznamu v bajtoch.
Súbor examples/records-array.act:
; An array of records: a block of bytes and a pointer that walks through it
TYPE Star=[BYTE x, y
CARD points]
DEFINE COUNT="3"
PROC Main()
BYTE ARRAY room(12) ; room for COUNT records of 4 bytes
Star POINTER s
BYTE i
FOR i=0 TO COUNT-1
DO
s=room+i*Star ; the address of record number i
s.x=i*10
s.y=i+1
s.points=(i+1)*100
OD
FOR i=0 TO COUNT-1
DO
s=room+i*Star
Print("Star ") PrintB(i)
Print(": x=") PrintB(s.x)
Print(" y=") PrintB(s.y)
Print(" points=") PrintCE(s.points)
OD
Print("One record takes ")
PrintB(Star)
PrintE(" bytes")
RETURNaction26 records-array.act --simStar 0: x=0 y=1 points=100
Star 1: x=10 y=2 points=200
Star 2: x=20 y=3 points=300
One record takes 4 bytess=room+i*Star vypočíta adresu záznamu číslo i: začiatok poľa plus i-krát veľkosť záznamu. Záznam Star má dva BYTE a jeden CARD, teda 4 bajty; tri záznamy potrebujú 12 bajtov.
Časté chyby
| Čo sa stalo | Čo povie prekladač alebo program |
|---|---|
položka, ktorá v zázname nie je (hero.speed) | error ACT008: undeclared name 'speed' |
priradenie celého záznamu (enemy=hero) | error ACT010: illegal assignment: cannot assign to Player 'enemy' – kopíruj položku po položke |
| ukazovateľ na záznam bez priradenej adresy | zápis na náhodné miesto v pamäti |
meno typu a meno premennej sa líšia len veľkosťou písmen (TYPE P, premenná p) | je to to isté meno – veľké a malé písmená sa nerozlišujú |
| pole pre záznamy je malé | záznamy za koncom poľa prepíšu inú pamäť |
Mená položiek sú mená ako každé iné. Dva typy záznamov v jednom programe preto nemôžu mať položku s rovnakým menom – prekladač ohlási error ACT006: 'x' is already declared. Pomáha predpona: px, py pre hráča, sx, sy pre hviezdu.
Vyskúšaj si
- Pridaj do
PlayerpoložkuCHAR symbola vypisuj ju vShow. - Napíš
PROC Move(Player POINTER who, BYTE dx, dy), ktorá posunie hráča. - V druhom programe zmeň
COUNTna 5. Čo ešte treba zmeniť?
Zhrnutie
TYPE Meno=[položky]opíše záznam; potom jeMenotyp.- Položka sa píše
záznam.položka. - Rutine sa záznam odovzdáva ako
Meno POINTER; pri volaní stačí meno záznamu. - Meno typu vo výraze je veľkosť záznamu.
- Pole záznamov = pole bajtov + ukazovateľ posúvaný o veľkosť záznamu.
Späť: 20. Ukazovatele · Ďalej: 22. Bity