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 |
II.2. |
Ordinální typy |
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é.
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
|
|
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 |
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 |
|
|||
ShortInt | 1 byte |
|
|||
Word | 2 byty |
|
|||
Integer | 2 byty |
|
|||
LongInt | 4 byty |
|
const MaxInt = 32767;
MaxLongInt = 2147483647;
Maximální hodnoty typů Integer a LongInt jsou přístupné jako předdeklarované konstanty MaxInt a MaxLongInt. 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ů |
|
11 až 12 cifer | |||
Single | 4 byty |
|
7 až 8 cifer | |||
Double | 8 bytů |
|
15 až 16 cifer | |||
Extended | 10 bytů |
|
19 až 20 cifer | |||
Comp | 8 bytů |
|
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.
Unární aritmetické operace Jsou definovány dvě unární operace — unární plus a uná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:
*
(I div J). Znaménko výsledku je tedy dáno znaménkem operandu I.
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ý |
not 49 { 00110001 } = 207 { 11001110 }
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 |
67 { 0000000001000011 } shl 3 = 536 { 0000001000011000 }
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í Abs a Sqr 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
|
|
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í Sin a Cos 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):
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):urad = udeg . p / 180
udeg = urad . 180 / p
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é.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)
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 |
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 = True, not True = FalseVý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í and a or — 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.
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 |
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 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
4 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
5 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
6 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
7 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | |
Znakové funkce Pro zpracování hodnot typu Char implementuje Turbo Pascal dvojici funkcí Chr a UpCase.
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 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é Sirka a Vyska rozměry šachovnice, jejichž hodnoty se mohou pohybovat v rozmezí od nuly do tisíce, pak za platnosti deklarace
nemusí výraz Sirkavar Sirka, Vyska: Word;
*
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 Sirka a Vyska z Word 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ý.
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.