II.  

STANDARDNÍ  DATOVÉ  TYPY


Data jsou v programovacích jazycích klasifikována atributem, nazývaným typ. Typ specifikuje jednak množinu přípustných hodnot (a tím i velikost a strukturu proměnných tohoto typu), jednak množinu jazykem definovaných operací, které je možno nad hodnotami a proměnnými tohoto typu provádět.

II.1. 

Jednoduché a strukturované typy

Typy lze podle struktury klasifikovat na jednoduché a strukturované. Proměnné jednoduchých typů obsahují jedinou kompaktní hodnotu — číslo, znak, logickou hodnotu apod. Další společnou vlastností jednoduchých typů je existence relace uspořádání na množinách jejich hodnot. Proměnné strukturovaných typů mají vnitřní strukturu — jsou členěny do komponent. Tyto komponenty už mohou být jednoduchého typu nebo mohou být členěny do dalších komponent. Pro hodnoty strukturovaných typů není uspořádání definováno, nelze je tedy v tomto smyslu porovnávat. Z dále uvedených standardních typů patří všechny mezi typy jednoduché.

II.2. 

Ordinální typy

Mezi jednoduchými typy tvoří speciální skupinu typy ordinální. Ze standardních typů jsou to všechny typy celočíselné, typ BooleanChar. Ordinálními jsou typy, pro něž je definováno vzájemně jednoznačné zobrazení množiny jejich hodnot na množinu ordinálních čísel těchto hodnot. Každé hodnotě ordinálního typu je tedy tímto zobrazením přiřazeno její ordinální číslo.

Přiřazení hodnoty proměnné   Pro proměnné ordinálních typů může, ale nemusí, být testována přípustnost přiřazované hodnoty vzhledem k rozsahu hodnot typu proměnné. Kontrola se nařizuje resp. zakazuje uvedením direktivy kompilátoru {$R+} resp. {$R–} na začátku uvažovaného úseku zdrojového textu a platí až do dalšího výskytu téže direktivy s opačným znaménkem. Při zapnuté kontrole je běh programu pomalejší a překročení rozsahu vede k běhové chybě a ukončení programu. Před vypnutím kontroly je nutno pečlivým odladěním programu vůči možným variantám vstupních dat zajistit, aby k žádnému překročení rozsahu nedošlo, jinak nebudou výsledky výpočtu správné.


POZNÁMKA: Implicitní stav kontroly rozsahu lze definovat v poli Range checking dialogu Compiler Options, který je přístupný příkazem Compiler nabídky Options vývojového prostředí. Při zaškrtnutém poli je kontrola rozsahu implicitně povolena.

Pokud je například B proměnná typu Byte (celočíselný typ o velikosti jeden byte a rozsahu hodnot 0 až 255) a W proměnná typu Word (celočíselný typ o velikosti dva byty a rozsahu hodnot 0 až 65 535) s aktuální hodnotou 300, bude mít proměnná B po provedení přiřazovacího příkazu B := W za vypnuté kontroly rozsahu hodnotu 44, tj. hodnotu nižšího bytu hodnoty přiřazované!

 vyšší byte  nižší byte
300 dec. =  00000001  00101100  bin.

Relační operace   Pro hodnoty všech ordinálních typů je definováno uspořádání matematickým uspořádáním jejich ordinálních čísel. Pro porovnávání operandů tímto způsobem jsou definovány binární relační operace, uvedené v následující tabulce. Operandy musí být vzájemně kompatibilních typů (nelze porovnávat například číselné hodnoty se znakovými), typ výsledku je Boolean (typ logických pravdivostních hodnot).

Tabulka 1: Relační operace pro ordinální typy
relace operátor
býti menší <
býti větší >
býti rovno =
relace operátor
býti menší nebo rovno <=
býti větší nebo rovno >=
býti různo <>

Procedury a funkce   Pro zpracování hodnot ordinálních typů poskytuje jazyk Turbo Pascal několik standardních procedur a funkcí.

function Ord (X: ordinální): LongInt;

Je-li X hodnota nějakého ordinálního typu, vrací funkce Ord (X) její ordinální číslo ve formátu LongInt (celočíselný typ maximálního rozsahu).

function Pred (X: ordinální): ordinální;

Je-li X hodnota nějakého ordinálního typu, hodnotou funkce Pred (X) je předchůdce této hodnoty v daném typu — hodnota stejného typu, s ordinálním číslem o 1 menším než Ord (X). Předchůdce hodnoty s nejmenším ordinálním číslem v daném typu není definován. Není-li X nejmenší hodnotou v typu, platí rovnost

Ord (Pred (X)) = Ord (X) – 1
function Succ (X: ordinální): ordinální;

Je-li X hodnota nějakého ordinálního typu, hodnotou funkce Succ (X) je následník této hodnoty v daném typu — hodnota stejného typu, s ordinálním číslem o 1 větším než Ord (X). Následník hodnoty s největším ordinálním číslem v daném typu není definován. Není-li X největší hodnotou v typu, platí rovnost

Ord (Succ (X)) = Ord (X) + 1
procedure Dec (var X: ordinální);
procedure Dec (var X: ordinální; I: LongInt);

Je-li X proměnná nějakého ordinálního typu, pak příkaz volání procedury Dec (X) má stejný efekt jako příkaz X := Pred (X). Proměnné X je tedy přiřazena hodnota předchůdce její hodnoty aktuální. Je-li navíc I celé číslo (celočíselný výraz), pak je příkazem Dec (X, I) proměnné X přiřazena hodnota I-tého předchůdce (pro I kladné) resp. Abs (I)-tého následníka (pro I záporné) její hodnoty aktuální. Pro I = 0 zůstává hodnota proměnné X nezměněna.

procedure Inc (var X: ordinální);
procedure Inc (var X: ordinální; I: LongInt);

Je-li X proměnná nějakého ordinálního typu, pak příkaz volání procedury Inc (X) má stejný efekt jako příkaz X := Succ (X). Proměnné X je tedy přiřazena hodnota následníka její hodnoty aktuální. Příkaz Inc (X, I), kde I je celočíselný výraz, je ekvivalentní příkazu Dec (X, –I).

II.3. 

Číselné typy

Turbo Pascal definuje dvě třídy číselných typů — typy celočíselné a reálné. V obou třídách je definováno několik podtypů, lišících se vzájemně rozsahem hodnot.

Všechny celočíselné typy jsou typy ordinálními a jejich množiny hodnot jsou souvislými podmnožinami množiny všech celých čísel. Seznam a charakteristiky jednotlivých celočíselných typů jsou uvedeny v tabulce 2.

Tabulka 2: Celočíselné typy
typ velikost rozsah hodnot
Byte 1 byte
0 .. 255
ShortInt 1 byte
–128 .. 127
Word 2 byty
0 .. 65 535
Integer 2 byty
–32 768 .. 32 767
LongInt 4 byty
–231 .. 231 – 1

const MaxInt     = 32767;
      MaxLongInt = 2147483647;

Maximální hodnoty typů IntegerLongInt jsou přístupné jako předdeklarované konstanty MaxIntMaxLongInt. Mezní hodnoty ostatních celočíselných typů lze určit jednoduchou úvahou. Celkový počet různých hodnot jednobytového typu ShortInt je například 28 (256), neboť jeden byte má osm bitů a každý bit může nabývat dvou různých hodnot. Protože se jedná o typ se znaménkem, je polovina z celkového počtu hodnot záporná a polovina nezáporná — meze rozsahu hodnot typu ShortInt tedy jsou –128 a 127.

Reálné typy nejsou sice typy ordinálními, patří však mezi typy jednoduché a pro jejich hodnoty je tudíž definováno uspořádání. Seznam a charakteristiky reálných typů obsahuje tabulka 3.

Tabulka 3: Reálné typy
typ velikost             rozsah  hodnot             přesnost
Real 6 bytů
2,9 . 10–39 .. 1,7 . 1038
11 až 12 cifer
Single 4 byty
1,5 . 10–45 .. 3,4 . 1038
7 až 8 cifer
Double 8 bytů
5,5 . 10–324 .. 1,7 . 10308
15 až 16 cifer
Extended 10 bytů
1,9 . 10–4932 .. 1,1 . 104932
19 až 20 cifer
Comp 8 bytů
–263 .. 263 – 1
19 až 20 cifer

Všechny reálné typy jsou typy se znaménkem, ve třetím sloupci předchozí tabulky jsou proto uvedeny pouze (přibližné) rozsahy absolutních hodnot jejich prvků (až na rozsah typu Comp). Množiny hodnot reálných typů nemohou být vzhledem ke konečné přesnosti reprezentace souvislými podmnožinami množiny všech reálných čísel, obsahují více či méně hustý diskrétní výběr z příslušného intervalu. Přesnost reprezentace je charakterizována počtem platných cifer v dekadickém zápisu mantisy čísla (čtvrtý sloupec). Zvláštní je v tomto ohledu typ Comp, jehož množinu hodnot tvoří všechna celá čísla z uvedeného intervalu.

Všechny celočíselné typy a typ Real lze použít vždy. Ostatní reálné typy lze použít pouze za skutečné nebo emulované přítomnosti aritmetického koprocesoru. Generování kódu pro koprocesor se povoluje resp. zakazuje direktivou kompilátoru {$N+} resp. {$N–}, uvedenou na začátku zdrojového textu. Ve stavu {$N+} pak lze připojit ještě direktivu {$E+} resp. {$E–}, která povoluje resp. zakazuje zahrnutí emulační knihovny koprocesoru do kódu programu (při zakázané emulaci nelze program na počítačích bez koprocesoru spouštět). Ve stavu {$N–} je případný výskyt direktivy {$E+} ignorován.


POZNÁMKA: Implicitní stavy uvedených direktiv lze definovat v polích 8087/80287Emulation dialogu Compiler Options, který je přístupný příkazem Compiler nabídky Options vývojového prostředí. Zaškrtnutím pole se generování kódu pro aritmetický koprocesor resp. zahrnutí emulační knihovny koprocesoru do programu implicitně povoluje.

Unární aritmetické operace   Jsou definovány dvě unární operace — unární plusunární minus. Minus mění znaménko hodnoty operandu vpravo, kdežto plus jej ponechává beze změny. Operand může být kteréhokoliv číselného typu. Výsledek je stejného typu jako operand pro celočíselné typy resp. typu Real nebo Extended (podle nastavení direktivy {$N–} nebo {$N+}) pro reálné typy.

Binární aritmetické operace   V tabulce 4 jsou uvedeny všechny implementované binární aritmetické operace, přípustné typy jejich operandů a typy výsledků.

Tabulka 4: Binární aritmetické operace
operace operátor typ operandů typ výsledku
součet + číselný společný číselný
rozdíl - číselný společný číselný
součin * číselný společný číselný
podíl / číselný společný číselný
celočíselný podíl div celočíselný společný celočíselný
zbytek po dělení mod celočíselný společný celočíselný

Pro určení typu výsledku platí následující pravidla:

Bitové operace   Bitové operace jsou definovány pouze pro celočíselné operandy. Bitová negace je unární operací, ostatní operace jsou binární.

Tabulka 5: Bitové operace
operace operátor typ výsledku
bitová negace not typ operandu
bitové a zároveň and společný celočíselný
bitové nebo or společný celočíselný
bitové vylučovací nebo xor společný celočíselný
bitový posun vlevo shl celočíselný
bitový posun vpravo shr celočíselný

Tabulka 6: Definice bitových operací and, or a xor
bit levého operandu bit pravého operandu bit výsledku operace
and or xor
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

Relační operace   Pro porovnávání číselných hodnot jsou k dispozici obvyklé matematické relační operace. Celočíselné hodnoty jsou porovnávány prostřednictvím svých ordinálních čísel, přičemž pro celočíselnou hodnotu X je ordinalita definována vztahem Ord (X) = X. Operandy reálných nebo smíšených typů jsou porovnávány jako matematická reálná čísla.

Test lichosti   Pro hodnoty celočíselných typů je definována funkce Odd, která poskytuje informaci o lichosti svého argumentu.

function Odd (X: LongInt): Boolean;

Argumentem X je celé číslo, vrácená hodnota je typu Boolean (typ logických pravdivostních hodnot). Pro lichou hodnotu argumentu vrací funkce hodnotu True (logická pravda), jinak False (logická nepravda).

Aritmetické funkce   Pro práci s reálnými čísly je definována řada aritmetických funkcí (viz tabulka 7). Argumentem každé z nich je libovolná číselná hodnota. Výjimkou je funkce Pi, která argument nemá, neboť pouze vrací hodnotu Ludolfova čísla. Hodnota funkcí AbsSqr s celočíselným argumentem je celočíselná (LongInt), hodnota týchž funkcí s reálným argumentem a všech ostatních funcí pak reálná (Real resp. Extended, v závislosti na nastavení direktivy kompilátoru {$N–} resp. {$N+}).

Tabulka 7: Aritmetické funkce
funkce hodnota
Abs absolutní hodnota
ArcTan arkustangens
Cos kosinus
Exp přirozená exponenciela
Frac desetinná část
Int celá část
funkce hodnota
Ln přirozený logaritmus
Pi Ludolfovo číslo
Sin sinus
Sqr druhá mocnina
Sqrt druhá odmocnina

Definiční obory uvedených funkcí souhlasí (až na rozsah) s definičními obory odpovídajících funkcí matematických. Záporná hodnota argumentu odmocniny, stejně jako nekladná hodnota argumentu logaritmu, způsobí chybu a ukončení běhu programu. Hodnotami argumentů goniometrických funkcí SinCos a výslednou hodnotou cyklometrické funkce ArcTan je úhel v radiánech (nikoli ve stupních). Pro případné převody platí následující vzorce (p je Ludolfovo číslo):

urad = udeg . p / 180
udeg = urad . 180 / p
Hodnoty některých dalších matematických funkcí, jejichž protějšky v Turbo Pascalu chybí, je nutno v případě potřeby počítat oklikou. K těmto účelům se nejčastěji hodí následující vzorce (je však nutno ošetřit obory platnosti):
tg x = sin x / cos x
cotg x = cos x / sin x
log y x = ln x / ln y
y x  = e x ln y
arcsin x = arctg (x / (1 – x2)1/2)
arccos x = arctg ((1 – x2)1/2 / x)
Konverze mezi číselnými typy   Konverze celočíselných hodnot na hodnoty reálné je zajištěna automaticky. Všude tam, kde je očekávána reálná hodnota, je dovolen výskyt hodnoty celočíselné. Při vyhodnocování výrazů jsou pak celočíselné hodnoty na místech reálných operandů automaticky konvertovány na hodnoty reálné.

Opačná konverze automaticky zajištěna není (uvedení reálné hodnoty na místě celočíselného operandu je chybou). Pokud je třeba z reálné hodnoty získat odpovídající hodnotu celočíselnou, musí být explicitně použita některá z konverzních funkcí Trunc nebo Round. Pokud je však příslušná celočíselná hodnota mimo rozsah typu LongInt, dojde při jejím výpočtu k chybě a ukončení běhu programu.

function Trunc (X: reálný): LongInt;

Vrací celočíselnou hodnotu, získanou odříznutím desetinné části z reálného argumentu (například pro argument –3.7 vrací Trunc hodnotu –3).

function Round (X: reálný): LongInt;

Vrací celočíselnou hodnotu, získanou zaokrouhlením reálného argumentu k nejbližšímu celému číslu (například pro argument –3.7 vrací Round hodnotu –4). Zaokrouhlení je koncipováno tak, že platí

X ł 0: Round (X) = Trunc (X + 0.5)
X < 0: Round (X) = Trunc (X - 0.5)

II.4. 

Typ Boolean

Typ Boolean implementuje logické pravdivostní hodnoty, reprezentované konstantami False (logická nepravda) a True (logická pravda). Velikost typu je jeden byte.


POZNÁMKA: Pro reprezentaci pouhých dvou různých hodnot by v zásadě stačil jediný bit, ovšem nejmenší samostatně adresovatelnou jednotkou je byte (8 bitů).

Logické operace   Definována je jedna unární logická operace a tři binární logické operace, odpovídající základním logickým operacím matematickým. Hodnoty operandů i výsledků všech logických operací jsou typu Boolean.

Unárním oprátorem logické negace je rezervované slovo not. Váže se k operandu vpravo a pro výsledek platí

not False = Truenot True = False
Výsledky binárních logických operací a zároveň (operátor and), nebo (operátor or) a vylučovací nebo (nonekvivalence, operátor xor) definuje následující tabulka.

Tabulka 8: Definice binárních logických operací
levý operand pravý operand výsledek operace
and or xor
False False False False False
False True False True True
True False False True True
True True True True False

Turbo Pascal podporuje dva režimy vyhodnocování logických operací andor — režim úplného a režim zkráceného vyhodnocování. Volba režimu je dána uvedením direktivy kompilátoru {$B+} (úplné vyhodnocování) resp. {$B–} (zkrácené vyhodnocování) na začátku uvažovaného úseku zdrojového textu a platí až do dalšího výskytu téže direktivy s opačným znaménkem.


POZNÁMKA: Implicitní režim vyhodnocování logických operací lze definovat v poli Complete boolean eval dialogu Compiler Options, který je přístupný příkazem Compiler nabídky Options vývojového prostředí. Při zaškrtnutém poli je implicitním režim úplného vyhodnocování.

V režimu zkráceného vyhodnocování je druhý operand operace and vyhodnocen pouze v případě, kdy první operand má hodnotu True, jinak druhý operand vyhodnocován není a operace má hodnotu False. Podobně, druhý operand operace or je vyhodnocen pouze když první má hodnotu False, jinak vyhodnocován není a operace má hodnotu True. V režimu úplného vyhodnocování jsou vždy vyhodnoceny oba operandy, i když je výsledek operace znám již po vyhodnocení prvního z nich.

Hodnota výsledku operace není na volbě režimu závislá, režim úplného vyhodnocování je proto vhodný pouze v případech, kdy je vyhodnocení druhého operandu provázeno nějaký potřebným vedlejším efektem.

Relační operace   Ordinalita je pro typ Boolean definována předpisem Ord (False) = 0 a Ord (True) = 1. Hodnota False je tedy menší než hodnota True.

II.5. 

Typ Char

Množinu hodnot tohoto typu tvoří 256 znaků — malá i velká písmena anglické abecedy, dekadické číslice a další znaky. Při výpisu na displej nemusí mít některé znaky lexikografickou reprezentaci (obrázek znaku), protože jsou používány jako řídící kódy výpisu.


POZNÁMKA: Lexikografická reprezentace znaků je variabilní — jistým způsobem ji lze modifikovat a nahradit tak například některé málo frekventované znaky chybějícími písmeny české abecedy. Základní konfiguraci definuje norma ASCII (American Standard Code for Information Interchange).

Přímou hodnotu (nepojmenovanou konstantu) typu Char lze ve zdrojovém textu programu zapsat jako jednoznakový řetězcový literál třemi způsoby:

Druhého a třetího způsobu lze využít právě pro zápis znaků bez lexikografické reprezentace. Znaky, které lexikografickou reprezentaci mají, ale neodpovídá jim žádná klávesa na klávesnici (například znak ±), lze generovat zápisem jejich kódu na numerické klávesnici při stisknutém přeřazovači ALT.

Relační operace   Porovnávání znakových hodnot je prováděno porovnáním jejich ordinálních čísel, přičemž ordinálním číslem znaku je jeho ASCII-kód. Všechna písmena anglické abecedy jsou uspořádána abecedně a souvisle, avšak zvlášť verzálky (ordinální čísla 65 až 90) a zvlášť minusky (97 až 122). Dekadické číslice jsou uspořádány numericky a souvisle (48 až 57).

Část normy ASCII je uvedena v tabulce 9. Číslo řádky je první a číslo sloupce druhou číslicí hexadecimálního zápisu kódu příslušného znaku (prázdná buňka odpovídá znaku mezera).

Tabulka 9: Část normy ASCII
0 1 2 3 4 5 6 7 8 9 A B C D E F
2  !"#$%&' ()*+,-./
3 01234567 89:;<=>?
4 @ABCDEFG HIJKLMNO
5 PQRSTUVW XYZ[\]^_
6 `abcdefg hijklmno
7 pqrstuvw xyz{|}~

Znakové funkce   Pro zpracování hodnot typu Char implementuje Turbo Pascal dvojici funkcí ChrUpCase.

function Chr (OrdCis: Byte): Char;

Vrací znak, odpovídající v argumentu zadanému ordinálnímu číslu. Je tedy inverzní funkcí k funkci Ord s argumentem typu Char:

Chr (Ord (X)) = X   pro hodnoty X typu Char
Ord (Chr (X)) = X   pro hodnoty X typu Byte
function UpCase (Znak: Char): Char;

Typem argumentu i vracené hodnoty je Char. Pokud je argumentem malé písmeno anglické abecedy, vrací funkce odpovídající písmeno velké, jinak je vrácená hodnota rovna argumentu.

II.6. 

Výrazy

Výraz je předpisem pro výpočet hodnoty. Typ hodnoty, získané jeho výpočtem, se nazývá typ výrazu. Zápis výrazu obsahuje operandy, unární a binární operátory a kulaté závorky. Vyhodnocení výrazu se řídí následujícími pravidly priority operátorů:

Výraz je tedy vyhodnocen obvyklým způsobem zleva doprava, s akceptováním závorek a priority operátorů. Priorita operátorů je uvedena v tabulce 10.

Tabulka 10: Priorita operátorů
priorita kategorie operátory
nejvyšší unární @ not + -
vyšší multiplikativní * / div mod and shl shr
nižší aditivní + - or xor
nejnižší relační < > = <= >= <> in

Syntax výrazů a pravidla jejich vyhodnocování (prioritu operátorů) vystihují syntaktické diagramy na obrázku 12.

Obrázek 12: Syntax výrazu





Velkou pozornost při zápisu výrazů je třeba věnovat především typům celočíselných výrazů z hlediska rozsahu hodnot jejich operandů. Pokud totiž nebyla provedena pečlivá analýza výrazu vůči možným variantám hodnot jeho operandů, může dojít při výpočtu hodnoty výrazu k tzv. přetečení.

Jsou-li například proměnné SirkaVyska rozměry šachovnice, jejichž hodnoty se mohou pohybovat v rozmezí od nuly do tisíce, pak za platnosti deklarace

var Sirka, Vyska: Word;
nemusí výraz Sirka * Vyska mít vždy hodnotu počtu polí šachovnice. Typem výrazu je totiž Word, jehož velikost je dva byty neboli šestnáct bitů, takže hodnotou výrazu bude vždy šestnáct nejnižších bitů hodnoty součinu. Například pro rozměry šachovnice 500 × 1000 polí je matematickou hodnotou součinu číslo 500 000, kdežto hodnotou výrazu číslo 41 248:

500 000 dec.  =  111 10100001 00100000 bin.
10100001 00100000 bin.  =  41 248 dec.

Aby hodnota výrazu byla vypočtena podle očekávání, musí být jeho typem LongInt. Toho lze dosáhnout například změnou typu v deklaraci některé nebo obou proměnných SirkaVyskaWord na LongInt.

Direktivou kompilátoru {$Q+} resp. {$Q–} lze povolit resp. zakázat kontrolu vzniku přetečení při výpočtu ordinálních výrazů. Direktiva se vkládá na začátek uvažovaného úseku zdrojového textu a platí až do dalšího výskytu téže direktivy s opačným znaménkem. Ve stavu {$Q+} vsune kompilátor do kódu vyhodnocení výrazu kontrolní test, který při vzniku přetečení generuje běhovou chybu programu. Ve stavu {$Q–} se kontrolní kód nevkládá a přetečení je ignorováno — program běží dál, ale výsledek výpočtu výrazu je chybný.


POZNÁMKA: Implicitní stav kontroly přetečení lze definovat v poli Overflow checking dialogu Compiler Options, který je přístupný příkazem Compiler nabídky Options vývojového prostředí. Při zaškrtnutém poli je kontrola přetečení implicitně povolena.

Testy přetečení poněkud zpomalují běh programu a zvětšují rozsah jeho kódu, proto se obvykle používají jen ve fázi ladění. V konečné verzi programu by již měly být všechny chyby, které přetečení způsobují, odstraněny.