31. Bloky pamäte a chyby: Zero, SetBlock, MoveBlock, Error, Break
Na čo to je
Prvá polovica kapitoly: tri rutiny, ktoré spravia naraz to, na čo by si inak písal slučku – vynulujú, vyplnia alebo skopírujú kus pamäte. Sú napísané v strojovom kóde a sú mnohonásobne rýchlejšie ako slučka FOR.
Druhá polovica: čo sa stane, keď za behu programu nastane chyba, a ako ju zachytiť.
Bloky: ako sa to píše
| Rutina | Čo robí |
|---|---|
Zero(adresa, počet) | vynuluje počet bajtov od adresy |
SetBlock(adresa, počet, hodnota) | vyplní počet bajtov hodnotou |
MoveBlock(kam, odkiaľ, počet) | skopíruje počet bajtov |
Adresa je najčastejšie meno poľa (kapitola 20: meno poľa je jeho adresa). Pri MoveBlock je cieľ prvý, ako pri SCopy.
Počet je v bajtoch. Pole CARD ARRAY t(10) má 20 bajtov.
Chyby: ako to funguje
Keď rutina knižnice narazí na problém – súbor neexistuje, bod je mimo obrazovky –, zavolá procedúru Error s číslom chyby. Tá, ktorá je v knižnici, vypíše
Err: 170a program ukončí.
Error sa dá vymeniť za vlastnú:
PROC MyError(BYTE code)
…
RETURN
…
Error=MyErrorPriradenie Error=MyError presmeruje všetky ďalšie chyby do tvojej procedúry. Tá dostane číslo chyby ako parameter. Keď sa vráti, program pokračuje za rutinou, v ktorej chyba nastala.
Break() je rutina, ktorá sama vyvolá chybu 128 – tú istú, ako keď používateľ stlačí kláves BREAK.
Celý program
Súbor examples/blocks.act:
; Blocks of memory, and an error handler of our own
BYTE ARRAY a(10), b(10)
PROC Show(BYTE ARRAY t)
BYTE i
FOR i=0 TO 9
DO
PrintB(t(i)) Put(' )
OD
PutE()
RETURN
PROC MyError(BYTE code)
PutE()
Print("Something went wrong, error ")
PrintBE(code)
IF code=170 THEN
PrintE("The file does not exist.")
FI
RETURN
PROC Main()
Zero(a, 10) ; ten bytes of zeros
Print("Zero: ") Show(a)
SetBlock(a, 10, 7) ; ten bytes with the value 7
Print("SetBlock: ") Show(a)
a(0)=1 a(1)=2 a(2)=3
MoveBlock(b, a, 10) ; copy ten bytes from a to b
Print("MoveBlock: ") Show(b)
Error=MyError ; from now on errors call MyError
Open(1, "D:MISSING.TXT", 4, 0)
Close(1)
PrintE("The program goes on.")
RETURNPreklad a spustenie
action26 blocks.act --simČo uvidíš
Zero: 0 0 0 0 0 0 0 0 0 0
SetBlock: 7 7 7 7 7 7 7 7 7 7
MoveBlock: 1 2 3 7 7 7 7 7 7 7
Something went wrong, error 170
The file does not exist.
The program goes on.Ako to funguje
Zero(a, 10)– desať núl. Hodí sa pred každým použitím poľa počítadiel.SetBlock(a, 10, 7)– desať sedmičiek.MoveBlock(b, a, 10)– polebje kópiou poľaa. Takto sa kopírujú polia; priradenieb=anefunguje (kapitola 18).Error=MyError– od tohto riadka chyby neukončia program.Openneexistujúceho súboru zavoláMyError(170), tá vypíše hlásenie a po jejRETURNprogram ide ďalej.
Vlastná obsluha chýb má jednu povinnosť: program po nej beží ďalej, aj keď sa operácia nepodarila. Tu sa súbor neotvoril, takže čítať z neho nemá zmysel. Skutočný program si preto v obsluhe poznačí, že nastala chyba (do globálnej premennej), a za rizikovou operáciou sa na ňu pozrie:
BYTE failed
PROC MyError(BYTE code)
failed=code
RETURN
…
failed=0
Open(1, "D:DATA.TXT", 4, 0)
IF failed THEN
PrintE("Cannot open the file.")
ELSE
… ; čítaj súbor
Close(1)
FINajčastejšie čísla chýb
| Číslo | Význam |
|---|---|
| 128 | stlačený kláves BREAK |
| 129 | kanál je už otvorený |
| 130 | zariadenie neexistuje (napr. D: bez DOS-u) |
| 133 | kanál nie je otvorený |
| 136 | koniec súboru – nevolá Error, len nastaví EOF(kanál) |
| 137 | riadok je dlhší ako miesto preň |
| 138 | zariadenie neodpovedá (vypnutá disketová jednotka) |
| 141 | kurzor alebo bod mimo obrazovky |
| 162 | disketa je plná |
| 170 | súbor neexistuje |
Úplný zoznam je v prílohe C.
Časté chyby
| Čo sa stalo | Čo sa stane |
|---|---|
počet v prvkoch namiesto v bajtoch pri CARD ARRAY | spracuje sa len polovica poľa |
MoveBlock s prehodeným cieľom a zdrojom | skopíruje sa opačným smerom a zdroj je prepísaný |
| blok dlhší ako pole | prepíše sa pamäť za poľom |
| kopírovanie v rámci toho istého poľa smerom nahor (cieľ je vyššie ako zdroj a prekrývajú sa) | kópia si prepíše vlastný zdroj; MoveBlock kopíruje od začiatku |
vlastná Error sa volá Error | nahradí knižničnú úplne – aj to je dovolený spôsob |
Vyskúšaj si
- Deklaruj
CARD ARRAY t(5), naplň ho a vynuluj cezZero. Koľko bajtov treba? - Doplň do programu premennú
failedpodľa ukážky a vypíšCannot open the file. - Zavolaj v programe
Break()a pozri, aké číslo dostaneMyError.
Zhrnutie
Zero,SetBlockaMoveBlockpracujú s blokom bajtov naraz a rýchlo.- Počet je v bajtoch; pri
MoveBlockje cieľ prvý. - Chyba za behu volá
Error(číslo); predvolená vypíšeErr: čísloa skončí. Error=MojaProcedurachyby presmeruje; program potom pokračuje.- Koniec súboru nie je chyba – hlási ho
EOF(kanál).
Späť: 30. Súbory · Ďalej: 32. Prekladač action26