Programové jednotky System, Turbo3, Strings

V těchto jednotkách se nacházejí nejčastěji používané funkce. Jednotka Turbo3 obsahuje příkazy jednotky System Turbo Pascalu 3.0 a je zde především kvůli zpětné kompatibilitě. Jednotka Strings pak umožňuje práci s dlouhými (Null-terminated) řetězci.

Jednotka System

Tato jednotka se jako jediná neuvádí v uses. Obsahuje natolik běžné příkazy, že její využití se předpokládá v každém Pascalském programu.

Proměnné

Proměnné jednotky System obsahují informace o spuštěném programu a aktivním prostředí.

Standardní inicializované proměnné
Pořadí Proměnná Význam
1 Input, Output : Text; Standardní vstupní / výstupní soubory (klávesnice a obrazovka)
2 InOutRes : integer; Tato proměnná uchovává výsledek I/O operace, než je zavolána funkce IOResult
3 ExitProc : pointer; Ukazatel na ukončovací proceduru, (standardně nil), potřebujeme-li vlastní ukončovací příkazy, vytvoříme proceduru a ukazatel nastavíme na ni
4 ExitCode : integer; Kód ukončení programu
5 ErrorAddr : pointer; Nastavení správné chybové adresy (obsluha dané chyby např. při RunError)
6 FileMode : byte; Přístupový režim ke všem právě otevřeným souborů, viz Konstanty režimu přístupu
7 FreeList : pointer; Ukazatel pro práci s hromadou
8 FreeZero : word; Ukazatel pro práci s hromadou
9 HeapEnd : pointer; Ukazatel na konec (dno) hromady
10 HeapError : pointer; Ukazatel pro práci s hromadou
11 HeapOrg : pointer; Ukazatel na začátek hromady
12 HeapPtr : pointer; Ukazatel na aktuální položku v hromadě
13 StackLimit : word; Offset dna zásobníku = nejnižší hodnota SP, kdy ještě nedojde k přetečení, normálně nulová, v případě {$N+,E+} je nastavena na 224
14 Test8086 : byte; Procesor - 0=I8086, 1=I80286 a 2=I8038 nebo novější
15 Test8087 : byte; Numerický koprocesor - 0=Nenalezen, 1=I8087, 2=I80287, 3=I80387 nebo novější
16 RandSeed : longint; Nastavení generátoru náhodných čísel (stejná hodnota = stejná náhodná čísla)
17 PrefixSeg : word; Adresa segmentu prefixu programu (viz manuál operačního systému)
18 Seg0040 : word; Adresa segmentu proměnných BIOSu
19 SegA000 : word; Adresa segmentu videopaměti
20 SegB000 : word; Adresa segmentu videopaměti
21 SegB800 : word; Adresa segmentu videopaměti
22 SelectorInc : word; Hodnota, kterou je třeba přičíst k ukazateli, aby ukazoval o 64KB dále, může se lišit od $100
23 SaveIntnn: pointer; Původní adresa nahrazených přerušení - Např. SaveInt1B je adresa původní obsluhy přerušení 1B.
Přehled měněných a ukládaných přerušení:
$0 $2 $1B $21 $23
$24 $34 $35 $36 $37
$38 $39 $3A $3B $3C
$3D $3E $3F $75

Procedury a funkce

Pro větší přehlednost dělíme podprogramy podle druhu vykonávané činnosti:

Aritmetické funkce

Přesnost výsledných funkcí se liší podle toho, zda je použit numerický koprocesor (příp. jeho emulace). (Což můžeme ovlivnit direktivami {$N} {$E}, případně přímým nastavením kompilátoru.) Jsou-li instrukce numerického procesoru zapnuty, je výsledným typem Extended, jinak pouze Real.

Aritmetické funkce
Pořadí Funkce Význam
1 Abs(x : TypeOfX) : TypeOfX; Absolutní hodnota X, výsledek je stejného typu jako argument
2 Sqr(x: Real) : Real; Druhá mocnina x
3 Sqrt(x: Real) : Real; Druhá odmocnina z x
4 Pi : Real; Hodnota Ludolfova čísla (Pí) = 3.1415...
5 Sin(x : Real) : Real; Sin x - x je v radiánech
6 Cos(x : Real) : Real; Cos x - x je v radiánech
7 ArcTan(x : Real) : Real; Tan-1 - výsledek je udán v radiánech
8 Exp(x: Real) : Real; ex
9 Ln(x: Real) : Real; ln x - přirozený logaritmus z x
10 Frac(x : Real) : Real; Desetinná část x
11 Int(x : Real) : Real; Celá část x (přesto je výsledkem reálné číslo)

Ordinální funkce a procedury

Přestože mnohé z těchto funkcí lze nahradit (např. pomocí x:=x+1), je výsledný kód získaný použitím zde uvedených procedur a funkcí o trochu rychlejší.

Ordinální funkce a procedury
Pořadí Příkaz Význam
1 Dec(var x); Sníží x o jedna
2 Dec(var x; n : Longint); Sníží x o n
3 Inc(var x); Zvýší x o jedna
4 Inc(var x; n : Longint); Zvýší x o n
5 High(X); Vrátí nejvyšší možnou hodnotu dané proměnné či typu, je-li X řetězec, vrátí jeho maximální délku, u pole jeho maximální index
6 Low(X); Vrátí nejnižší možnou hodnotu dané proměnné či typu, je-li X řetězec, vrátí 0, u pole vrací jeho dolní index
7 Odd(x : longint) : Boolean; Je-číslo liché?
8 Pred(x : ordinal) : ordinal; Vrátí předchůdce dané hodnoty (neprovádí žádné testování mezí). Pred(25) = 24
9 Succ(x: ordinal) : ordinal; Vrátí následovníka dané hodnoty (neprovádí testování mezí) Succ(13) = 14

Procedury pro práci s řetězci

Procedury a funkce pro práci s řetězci
Pořadí Příkaz Význam
1 Concat(s1, s2, s3,...:string):string Spojí několik řetězců do jediného. Maximální délka výstupu je 255 znaků. (Tato funkce lze kupodivu lze použít i na spojení jediného řetězce...)
2 Copy(s:string; index, count : integer) : string Funkce vrátí podřetězec s1, který začíná index-tým znakem a který sám obsahuje count znaků
3 Delete(var x:string; index, count : integer); Procedura vymaže daný úsek z řetězce (označení viz výše)
4 Insert(src:string; var s:string; idx : integer); Procedura vloží na idx-té místo řetězce s řetězec src
5 Length(s:string) : integer; Skutečná délka řetězce s
6 Pos(substr:string;s:string) : integer; Vyhledá první výskyt podřetězce substr v řetězci s, vrací index prvního písmene. Nenajde-li podřetězec, vrací 0
7 Str(x, var s:string); Převede číslo x na řetězec (dovoluje použít i zápis X:m:dm udávající počet míst a počet desetinných míst daného čísla)
8 Val(s:string; var v; code : integer); Převede řetězec (který musí vyhovovat konvenci - tedy žádné mezery, desetinná tečka místo čárky,...) na číslo. code označuje index, u kterého došlo k chybě, při úspěšném provedení je code=0.

Konverzní funkce a procedury

Konverzní funkce a procedury
Pořadí Příkaz Význam
1 Chr(x : Byte) : char; Vrátí x-tý znak v ASCII tabulce
2 Ord(x) : Longint; Vrátí pořadové číslo prvku
3 Round(x:Real) : longint; Zaokrouhlí reálné číslo, výsledkem je číslo celé
4 Trunc(x:Real) : longint; Převede reálné číslo na celé tím, že "usekne" desetinnou část
5 UpCase(c:char) : char; Převede malé písmeno na velké (ostatní znaky nechá beze změny)
6 Str(x, var s:string); Převede číslo x na řetězec (dovoluje použít i zápis X:m:dm udávající počet míst a počet desetinných míst daného čísla)
7 Val(s:string; var v; code : integer); Převede řetězec (který musí vyhovovat konvenci - tedy žádné mezery, desetinná tečka místo čárky,...) na číslo. code označuje index, u kterého došlo k chybě, při úspěšném provedení je code=0.

Procedury řízení běhu výpočtu

Procedury řízení běhu výpočtu
Pořadí Příkaz Význam
1 Break; Procedura okamžitě ukončí právě probíhající cyklus (for, while, či repeat). Jsou-li cykly vnořené, ukončí nejvnořenější
2 Continue; Přejde na konec cyklu (a buď ho vykoná od začátku, nebo skončí)
3 Exit; Ukončí podprogram (=probíhající proceduru)
4 Halt; Okamžitě ukončí program
5 Halt(n); Ukončí program a jako výstupní hodnotu (ERRORLEVEL) udá n
6 RunError; Ukončí program tím, že vyvolá chybu 0.
7 RunError(n); Ukončí program vyvoláním chyby s číslem n (lze tak trápit uživatele např. hláškami typu disk C: nenalezen)

Procedury a funkce pro dynamickou alokaci

Příkazy pro práci s dynamickými proměnnými
Pořadí Příkaz Význam
1 New(var p:pointer); Vytvoří novou dynamickou proměnnou a nastaví na ni ukazatel p
2 Dispose(var p:pointer); Zruší dynamickou proměnnou, na kterou ukazuje ukazatel p, do ukazatele pak vloží hodnotu nil
3 New(var p:pointer,const:constructor); Vytvoří nový dynamický objekt, nastaví naň ukazatel a spustí constructor objektu const (např. New(p,Init) )
4 Dispose(var p:pointer,dest:destructor); Zruší dynamický objekt, zavolá jeho destruktor (dest) a vyniluje ukazatel
5 MaxAvail : longint; Vrací maximální délku souvislé paměti v hromadě (tedy nejvyšší možnou velikost dynamické proměnné)
6 MemAvail : longint; Vrací velikost volné paměti v hromadě (tedy velikost té paměti, které je ještě volná pro dynamické proměnné)
7 GetMem(var p:pointer; size : word); Vytvoří novou dynamickou proměnnou o velikosti Size bytů. Nejčastěji se používá spolu s funkcí SizeOf : GetMem(p,SizeOf(DynamickaPromenna));
8 FreeMem(var p:pointer; size : word); Zruší dynamickou proměnnou vytvořenou pomocí GetMem
9 Mark(P:Ukazatel); uloží stav hromady (volné paměti) do ukazatele (nesmí být použito s GetMem a FreeMem)
10 Release(P:Ukazatel); Obnoví stav hromady podle P (kam byl uložen pomocí Mark...)

Procedury a funkce pro práci se soubory

Procedury a funkce pro práci se soubory
Pořadí Příkaz Význam
1 Assign(f:Soubor,DosovskyNazevExternihoSouboru); Přiřadí proměnné soubor. Prázdný řetězec--> přiřadí soubor Output či Input (Obrazovku či klávesnici)
2 Reset(f:Soubor); Otevře soubor pro čtení (nastaví pomyslný ukazatel na první položku souboru)
3 Rewrite(f:Soubor); Otevře soubor pro zápis (smaže celý soubor a nastaví ukazatel na začátek souboru)
4 Append(f:Text); Otevře textový soubor pro přidání (nastaví ukazatel na konec existujícího textového souboru)
5 Close(f:Soubor); Zavře soubor (a případně také uloží veškeré změny v souboru na disk)
6 Eof(f:soubor) : Boolean; Funkce nabývá hodnoty true, když je dosaženo konce souboru
7 Eof : Boolean; takto použita udává, zda je dosaženo konce souboru Input (data z klávesnice)
8 SeekEof(f:soubor) : Boolean; Jako Eof, přeskakuje však mezery, konce řádků a podobné znaky. Funguje pouze u textových souborů, dokonce je výhodnější.
9 Eoln(f:Text):Boolean; Udává, zda je v textovém souboru dosaženo konce řádky (znaky CR a LF). V textovém souboru je lepší používat SeekEoln;
10 SeekEoln(f:Text):Boolean; Funguje stejně jako Eoln, přeskočí však všechny mezery a tabelátory. Funguje pouze u textových souborů.
11 Flush(f:text); Zapíše dosud nezapsané znaky z Bufferu na disk (normálně se zapisují až při zavolání Close, či je-li jich víc než 128)
12 SetTextBuffer(var f:text, var buff[;size : word]); Změní velikost textového bufferu (zvětšení např. sníží počet přístupů na disk)
13 Write([f:soubor],v1,v2,...); Vypíše do souboru f (či na obrazovku, není-li uveden), hodnoty v1, v2, které jsou typu char, celočíselného, reálného, Boolean nebo string. Délku výpisu hodnoty lze omezit pomocí v1:PocetMist, u reálných typů ještě takto r:PocetMist:PocetDesetinnychMist;
14 Writeln[([f:soubor],v1,v2,...)]; Pracuje stejně jako Write, ale zapíše ještě konec řádky, je-li volána bez parametrů, zapíše pouze konec řádky
15 BlockRead(var f:file;var buf;count:word,[;result:word]); čte hodnoty ze souboru bez udaného typu (přečte Count záznamů a uloží je do buf - což je proměnná libovolného typu, result vrací počet skutečně přečtených záznamů)
16 BlockWrite(var f:file;var buf;count:word,[;result:word]); Procedura zapíše jeden nebo více záznamů do souboru s neudaným typem. Pracuje podobně jako BlockRead.
17 FilePos(f:Soubor) : longint; Vrací současnou pozici v souboru (na začátku nula, na konci FileSize(f);). Nelze použít na soubor typu Text;
18 FileSize(f:Soubor) : longint; Vrací celkový počet komponent v souboru (nesmí být použita na soubor typu Text)
19 Seek(f:Soubor, n : longint); Nastaví pozici v souboru na n (nesmí být použita na soubor typu Text), Číslo první komponenty je 0, poslední FileSize-1
20 Truncate(f:Soubor); Vymaže všechny záznamy od aktuální pozice až do konce. Po jejím provedení nabývá Eof hodnoty true.
21 IOResult : word; Při {I-} vrátí kód poslední I/O operace. Nastala-li chyba, jsou všechny příkazy mezi příkazem a IOResult ignorovány.
22 ChDir(s:string); Změní současný adresář na s
23 GetDir(d:byte;var s:string); Do s uloží cestu na vybraném disku (d=0 aktuální disk, 1 - A:, 2 - B:, 3 - C: ,...);
24 MkDir(s : string); V aktuálním umístění vytvoří adresář se zadaným názvem
25 RmDir(s : string); Smaže prázdný adresář zadaného jména
26 Erase(var f:file); Smaže z disku neotevřený soubor spojený s proměnnou f
27 Rename(var f : file; newname:string); Přejmenuje neotevřený soubor spjatý s f na newname

Funkce pro práci s adresami a ukazateli

Funkce pro práci s adresami a ukazateli
Pořadí Příkaz Význam
1 Assigned(var P) : Boolean; Zjistí, zda daný ukazatel někam ukazuje (stejně jako P<>nil)
2 CSeg : word; Vrátí aktuální hodnotu registru CS (Code Segment) -segment aktuálního kódu (spolu s offsetem nula ukazuje na začátek spustitelného kódu)
3 DSeg : word; Vrátí aktuální hodnotu registru DS (Data Segment) - segment dat
4 SSeg : word; Vrátí aktuální hodnotu registru SS (Stack Segment) -segment zásobníku
5 SPtr : word; Vrátí aktuální hodnotu registru SP (Stack Pointer) - ukazatel na současnou pozici zásobníku
6 Seg(x) : word; Vrátí adresu segmentu daného objektu. Segment udává vzdálenost objektu od počátku paměti měřenou v 16-ti bytových blocích
7 Ofs(x) : word; Vrátí offset adresy dané proměnné. Offset udává vzdálenost objektu od začátku segmentu měřenou v bytech
8 Addr(x) : pointer; Vrátí celou adresu (tedy ukazatel) na daný objekt. Stejné je většinou i @ x.
9 Ptr(sgm, oft : word) : pointer; Vytvoří ze segmentu a ofsetu kompletní adresu (tedy ukazatel na daný objekt)

Ostatní procedury a funkce

Nejprve si krátce řekneme, co je to tabulka virtuálních metod objektu typu object. Každý objekt obsahuje ukazatel na tuto tabulku. Tabulka mimo jiné obsahuje ukazatele na jednotlivé virtuální procedury a funkce. V praxi to znamená, že mají-li dva objekty stejný ukazatel, jsou stejného typu.

Ostatní příkazy
Pořadí Příkaz Význam
1 Exclude(var S:set of T; I:T); Vyjme z množiny prvek I (je-li tam); (Je o něco výhodnější než S:=S+[ I ];
2 Include(var S:set of T; I:T); Přidá do množiny prvek I (není-li tam již přítomný);
3 Randomize; Nastaví generátor náhodných čísel na náhodnou hodnotu
4 Random : Real; Vrátí náhodné reálné číslo z intervalu <0,1) (Pro vyšší rozsah musíme něčím znásobit).
5 Random(range : word):Word; Vrátí náhodné celé číslo z intervalu <0, range)
6 Swap(x : TypeOfX) : TypeOfX; Prohodí dolní a horní byte argumentu (ten musí tedy mít dva byty, že... tedy integer nebo word)
7 Hi(x) : word; Vrátí vyšší byt daného argumentu (který je typu word, nebo integer);
8 Lo(x) : word; Vrátí nižší byt daného argumentu (které je typu word, nebo integer);
9 SizeOf(x) : word; Vrátí počet bytů, které v paměti potřebuje daný objekt
10 FillChar(var X;count :Word;Value:ordinal); Vyplní oblast paměti ordinální hodnotou Value, začne od X a zaplní Count bytů (sami musíme ohlídat, co přepisujeme)
11 Move(var source, dest; count:integer); Přesune Count bytů z oblasti source do oblasti Dest (neprovádí se kontrola přetečení)
12 ParamCount : word; Vrátí počet parametrů, se kterými byl daný program v příkazové řádce spuštěn
13 ParamStr(index:word) : string; Vrátí index-tý parametr, se kterým byl program spuštěn
14 TypeOf(P:objekt) : pointer; Vrátí ukazatel na tabulku virtuálních metod typu object. (Např. if TypeOf(Ja)<>TypeOf(TBlbec) then writeln('Objekt Ja není typu Blbec'));

Jednotka Turbo3

Tato jednotka umožní využívat staré příkazy Turbo Pascalu verze 3.0. Většina příkazů se shoduje se současnými příkazy. Nepředpokládám, že byste ji kdykoliv aktivně využili. Dostanete-li do rukou program verze 3.0, prostě na začátek připište uses Turbo3; (popř. Graph3 viz Graph3). Pokud vás příkazy staré verze 3.0 přesto zajímají, můžete si stáhnout kompletní anglický manuál na http://oldcomputers.dyndns.org/public/pub/rechner/epson/~fjkraan/comp/tp30/doc/ (jednotlivé kapitoly jsou ve formátu PDF, doporučuji nejprve stáhnou obsah)

Jednotka Strings

Tato jednotka zavádí tzv. Null-terminated řetězce. Jedná se o řetězce jejichž délka je omezena jen délkou spojitě volné paměti. Takovýto řetězec je ukončen znakem konce řetězce (#0) z čehož vyplývá jediné omezení tohoto typu řetězců - nesmí obsahovat znak #0. Další nevýhodou takovéhoto přístupu je poměrně špatná manipulace s daným řetězcem (např. pro zjištění délky řetězce se musí projít veškeré znaky řetězce,...)

Tento typ řetězců je např. vyžadován všemi windowsáckými programy (Windowsácké rozhraní API uznává jen tento typ řetězců).

Aby jednotka Strings mohla fungovat, je třeba zapnout rozšířenou syntaxi (buď v menu nebo pomocí {$X+}). Většina příkazů této jednotky jsou funkce, jelikož však většinou nepotřebujeme znát výstupní hodnotu, můžeme je volat i jako procedury (volání funkce jako samostatného příkazu je umožňuje právě rozšířená syntaxe - ale se standardním Pascalem to mnoho společného nemá).

Jednotka strings zavádí nový typ řetězce : PChar. Jedná se vlastně o ukazatel na znak. Všechny další znaky v paměti až do prvního výskytu #0 se berou jako součást daného řetězce. Rozšířená syntaxe umožní do PCharu přiřadit i obyčejný řetězec, či samotný znak. PChar si také můžeme představit jako array[1..X] of Char; (problém ovšem je, že to X neznáme, nicméně v paměti se tyto reprezentace shodují a s rozšířenou syntaxí můžeme využívat obě dvě.)

Procedury a funkce pro práci s řetězci typu PChar (z jednotky Strings)

Procedury a funkce pro práci s řetězci typu PChar (z jednotky Strings)
Pořadí Příkaz Význam
1 StrCopy(Dest,Source:PChar) :PChar; Zkopíruje Source do Dest (a vrací Dest)
2 StrPCopy(Dest:PChar, Source : string) :PChar; Zkopíruje Source do Dest (a vrací Dest)
3 StrLCopy(Dest,Source:PChar,L) :PChar; Zkopíruje Source do Dest (kopíruje maximálně L znaků)
4 StrCat(Dest,Source:PChar) :PChar; Připojí Source k Dest
5 StrLCat(Dest,Source:PChar,L) :PChar; Připojí Source k Dest, ale připojí max. L znaků
6 StrLen(S:PChar):Word; Udává počet znaků v daném řetězci
7 StrLower(S:PChar):PChar; Mění všechna velká písmena na malá.
8 StrUpper(S:PChar):PChar; Mění všechna malá písmena na velká.
9 StrPas(S:PChar) : string; Mění ASCIIZ (PChar) řetězec na obyčejný string (maximálně prvních 255 znaků)
10 StrComp(s1,s2:PChar) : Integer; Porovná dva řetězce. Výsledek je 0, jsou-li stejné. Záporné číslo, je-li s1 < s2 a číslo kladné znamená, že s1 > s2
11 StrIComp(s1,s2:PChar) : Integer; Pracuje stejně, ale nerozlišuje velká a malá písmena
12 StrLComp(s1,s2:PChar,L) : Integer; Pracuje stejně jako StrComp, ale porovná pouze prvních L znaků.
13 StrLIComp(s1,s2:PChar,L) : Integer; Stejně jako StrLComp porovná první L znaků dvou řetězců. Nerozlišuje velká a malá písmena.
14 StrECopy(Dest,Source:PChar):PChar; Zkopíruje Source do Dest, ukazatel (typu PChar) nastaví na konec řetězce
15 StrEnd(s1:PChar):PChar; ukazatel (typu PChar) na konec řetězce
16 StrMove(Dest,Source:PChar,Count:Word):PChar; Zkopíruje Count znaků ze Source do Dest a vrací Dest
17 StrPos(s1,s2:PChar):PChar; vrací ukazatel (typu PChar) na první výskyt s2 v řetězci s1. V případě, že se s2 v s1 nevyskytuje vrací nil.
18 StrScan(s:PChar,ch:Char):PChar; vrací ukazatel (typu PChar) na první výskyt znaku ch v řetězci s popř. nil. (Ukončovací znak je součástí s)
19 StrRScan(s:PChar,ch:Char):PChar; vrací ukazatel (typu PChar) na poslední výskyt znaku ch v řetězci s popř. nil.
20 StrNew(s:PChar):PChar; Zkopíruje s na nové místo v paměti a vrátí na něj ukazatel (v případě, že je s = nil, nedělá nic)
21 StrDispose(s:PChar); Odstraní z paměti řetězec vytvořený pomocí StrNew;

Vyzkoušejte si např. StrECopy(StrECopy(StrECopy(s1,s2),s3),s4)); writeln(S1); ať pochopíte, co přesně znamená, že řetězce PChar jsou ve skutečnosti ukazatele (StrECopy nastaví výsledný ukazatel na konec řetězce).