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: 170

a program ukončí.

Error sa dá vymeniť za vlastnú:

Action!
PROC MyError(BYTE code)
  …
RETURN

…
Error=MyError

Priradenie 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:

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

Preklad 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

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:

Action!
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)
FI

Najčastejšie čísla chýb

ČísloVýznam
128stlačený kláves BREAK
129kanál je už otvorený
130zariadenie neexistuje (napr. D: bez DOS-u)
133kanál nie je otvorený
136koniec súboru – nevolá Error, len nastaví EOF(kanál)
137riadok je dlhší ako miesto preň
138zariadenie neodpovedá (vypnutá disketová jednotka)
141kurzor alebo bod mimo obrazovky
162disketa je plná
170sú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 ARRAYspracuje sa len polovica poľa
MoveBlock s prehodeným cieľom a zdrojomskopíruje sa opačným smerom a zdroj je prepísaný
blok dlhší ako poleprepíš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á Errornahradí knižničnú úplne – aj to je dovolený spôsob

Vyskúšaj si

  1. Deklaruj CARD ARRAY t(5), naplň ho a vynuluj cez Zero. Koľko bajtov treba?
  2. Doplň do programu premennú failed podľa ukážky a vypíš Cannot open the file.
  3. Zavolaj v programe Break() a pozri, aké číslo dostane MyError.

Zhrnutie

Späť: 30. Súbory · Ďalej: 32. Prekladač action26