Jednoduché datové typy se dále ještě dělí na ordinální a neordinální typy. To, že některé typy mají vlastnost být ordinální znamená, že hodnota, náležící do tohoto typu, má svého předchůdce, svého následovníka a její pozici lze číselně ohodnotit. Ordinálních typů je pět: integer, boolean, char a uživatelem definované typy interval a výčtový typ. Neordinální typ je pouze jeden a jmenuje se real.
Pro ordinální typy platí:
Tento datový typ specifikuje konečnou souvislou podmnožinu celých čísel. Umožňuje uživateli využít pět datových typů, které se od sebe liší rozsahem hodnot a tím i použitou velikostí paměti. Přehled je v následující tabulce:
Typ | Rozsah | byte/bitů |
---|---|---|
shortint | -128 .. 127 | 1/8 |
integer | -32 768 .. 32 767 | 2/16 |
longint | -2 147 483 648 .. 2 147 483 647 | 4/32 |
byte | 0 .. 255 | 1/8 |
word | 0 .. 65 535 | 2/16 |
comp | -263 + 1 .. 263 - 1 | 8/64 |
Pro hlavního zástupce tohoto typu integer jsou hodnoty definovány v rozsahu -Maxint <= 0 <= Maxint, kde -Maxint = -32 768 a Maxint = 32 767. Všechny typy integer jsou použitelné i bez přítomnosti matematického koprocesoru. (I když v dnešní době asi tato poznámka ztrácí na významu.)
Pro hodnoty tohoto typu jsou definovány operace s výsledky rovněž typu integer:
+ | sčítání |
- | odčítání nebo unární operace změny znaménka |
* | násobení |
div | celočíselné dělení (celá část po dělení) |
mod | zbytek po celočíselném dělení (Tato operace pro dva argumenty i mod j je definována takto: je-li j <= 0, nastane při výpočtu chyba. Jinak se i mod j rovná hodnotě i - (k * j) pro takové celé k, pro které je 0 <= i mod j < j |
Operace +, - ,* jsou definovány pro všechny dvojice celých čísel, pokud výsledek leží v intervalu <-Maxint, Maxint>
Další operace, definované nad tímto typem, jsou relační:
= | rovnost |
<> | nerovnost |
< | menší než |
> | větší než |
<= | menší nebo rovno |
>= | větší nebo rovno |
Pokud hodnoty operandů splňují relaci, výsledkem je logická hodnota true (pravda), v opačné případě false (nepravda).
Standardní funkce, definované nad tímto typem (první dvě dávají výsledek typu integer, třetí typu boolean):
abs(i) | zjistí absolutní hodnotu čísla i |
sqr(i) | vypočte druhou mocninu čísla i |
odd(i) | vrátí logickou hodnotu true, pokud je i liché číslo, jinak vrátí logickou hodnotu false |
Tento datový typ je reprezentován dvěma hodnotami true (pravda) a false (nepravda), které slouží k vyjádření logických hodnot. Pro hodnoty typu boolean jsou definovány všechny relační operace (=, <>, <, >, <=, >=). Z toho, že v tomto typu platí uspořádání false < true vyplývá, že i nad tímto typem jsou definovány standardní funkce succ(x), pred(x) a ord(x). Hodnota ord(false) = 0, hodnota ord(true) = 1. A dále jsou zde definovány binární operace konjunkce a disjunkce a unární operace negace:
and | konjunkce (logický součin) |
or | disjunkce (logický součet) |
not | negace |
Jejich definice jsou uvedeny v tabulce:
x | y | x and y | x or y | not x |
---|---|---|---|---|
false | false | false | false | true |
false | true | false | true | true |
true | false | false | true | false |
true | true | true | true | false |
Z důvodů kompatibility jsou v Pascalu definovány čtyři logické datové typy:
Boolean | 1 byte |
ByteBool | 1 byte |
WordBool | 2 byte |
LongBool | 4 byte |
Je to takový datový typ, jehož hodnotami jsou znaky. Množina hodnot však není definována tímto typem, ale kódem znaků, který je v počítači implementován. Nejčastěji se používá kód ASCII (American Standard Code for Information Interchange), jeho evropská verze ISO a kód EBCDIC (Extended Binary Coded Decimal Information Code).Každý kód však musí splňovat čtyři základní body:
Znaky zapisujeme mezi apostrofy ('A', '5' - POZOR, tento zápis označuje znak 5, nikoliv číslo 5). Pokud chceme zapsat apostrof, musíme jeho zápis zdvojit (vypadá takto: '''').
Také na tomto datovém typu jsou definovány standardní funkce:
ord(x) | vrací ordinální hodnotu znaku x v dané množině znaků (ASCII tabulka, atd.) |
chr(x) | je inverzní funkce k funkci ord, x je hodnota typu integer, výsledkem je příslušný znak |
succ(x) | succ(x) = chr(ord(x) + 1) |
pred(x) | pred(x) = chr(ord(x) - 1) |
Výčet je jednoduchý datový typ, který si uživatel může definovat podle svých požadavků. jednotlivé hodnoty mají svá ordinální čísla podle pořadí v zápisu a jejich počítání začíná nulou. Myslím, že příklad bude jasnější:
type |
tyden = (pondeli, utery, streda, ctvrtek, patek, sobota, nedele); |
obdobi = (jaro, leto, podzim, zima); |
var |
den: tyden; |
doba: obdobi; |
Potom platí následující vztahy:
Tento datový typ specifikuje souvislou neprázdnou podmnožinu hodnot nějakého ordinálního typu. Dolní a horní mez této podmnožiny udávají dvě konstanty daného ordinálního typu. Např.: zápis 1 .. 100 definuje interval, specifikující množinu celočíselných hodnot. Typ interval však nemusí být definován pouze nad číselnými typy, může být definován i nad typy výčet či char, jak ukazuje následující příklad:
type |
pracovni_dny = pondeli .. patek; |
velke_pismeno = 'A' .. 'Z'; |
Potom opět platí následující vztahy:
Tento datový typ specifikuje konečnou podmnožinu reálných čísel. Používá se pro vyjádření hodnot s pohyblivou desetinnou čárkou. V paměti počítače se hodnoty vyjadřují jako dvojice (M,N), kde M je mantisa a N je exponent. Rozsahy hodnot jsou uvedeny v následující tabulce:
Typ | Rozsah | byte/bitů |
---|---|---|
real | 2.9*10-39 .. 1.7*10+38 | 6/48 |
single | 1.5*10-45 .. 3.4*10+38 | 4/28 |
double | 5.0*10-324 .. 1.7*10+308 | 8/64 |
extended | 3.4*10-4932 .. 1.1*10+4932 | 10/80 |
Tento typ, i když má největší rozsah, co se týče numerických hodnot, má také jedno omezení, a tím je tzv. strojová nula. Tato hodnota je určena intervalem (0, minreal), kde minreal je v absolutní hodnotě minimální zobrazitelná hodnota na daném počítači. Protože reálné číslo není možné zobrazit v počítači s libovolnou přesností, s konečnou přesností se vykonávají i operace a funkce, definované nad tímto typem. Toto je nutno brát v úvahu při tvorbě i ověřování správnosti programu.
Pro hodnoty typu real jsou definovány operace s výsledky rovněž typu real:
+ | sčítání |
- | odčítání nebo unární operace změny znaménka |
= | násobení |
/ | dělení |
Dále jsou zde definovány relační operace stejně jako u typu integer a tyto standardní funkce:
abs(x) | absolutní hodnota |
sqr(x) | druhá mocnina |
sqrt(x) | druhá odmocnina |
sin(x) | vypočte sin(x) - argument x je v radiánech |
cos(x) | vypočte cos(x) - argument x je v radiánech |
arctan(x) | vypočte arctan(x) - výsledek je v radiánech |
ln(x) | přirozený logaritmus |
exp(x) | funkce ex |
Konverze mezi datovými typy integer a real:
Následující tabulky uvádějí povolené kombinace argumentů a odpovídající typy výsledků relačních operátorů, aritmetických a standardních funkcí:
a | b | a +, -, * b | a /b | a div, mod b | a =, <>, <, >, <=, >= b |
---|---|---|---|---|---|
integer | integer | integer | real | integer | boolean |
integer | real | real | real | -- | boolean |
real | integer | real | real | -- | boolean |
real | real | real | real | -- | boolean |
a | abs(a), sqr(a) | sin(a), cos(a), arctan(a), ln(a), exp(a), sqrt(a) | odd(a) |
---|---|---|---|
integer | integer | real | boolean |
real | real | real | -- |
Reálná čísla v Pascalu se zapisují ne s desetinnou čárkou, ale s desetinnou tečkou. Také pro exponent se používá neobvyklý zápis: místo 10-13 se používá e-13 nebo E-13. Pak tedy číslo 3,5478*10-14 se zapíše 3.5478E-14.
Běžně se používá k programování typ real. Rozšířené
reálné typy single, double a extended se mohou používat pouze se
zabudovaným matematickým koprocesorem, nebo musíme jeho činnost emulovat. To se
provádí pomocí direktiv. {$N+}
je direktiva oznamující využití
matematického koprocesoru, direktiva {$E+}
zajistí emulaci matematického
koprocesoru 80x86.
Strukturovaný datový typ je v podstatě skupina jednodušších typů a proměnná strukturovaného datového typu je skupina proměnných nějakého jednoduššího typu (Nepíši záměrně "jednoduchého typu" místo "jednoduššího typu", sami dále uvidíme proč.) Každý strukturovaný datový typ poskytuje prostředky pro práci s prvky dat, tj. pro jejich zpřístupnění.
Tento datový typ se skládá z pevného počtu položek stejného typu. Položky se vzájemně rozlišují pomocí indexu. Mezi položkami dat a hodnotami indexů existuje jednoznačné přiřazení. Při definici pole se určuje jeho rozměr a datový typ složek. Rozměr pole určuje počet prvků, které se do pole mohou vložit. Index pole je většinou typu integer. Může jím však být i jiný ordinální typ. Velikost pole je vždy omezena paměťovými nároky. Deklarace pole vypadá následovně:
type |
pole1 = array[1..15]of integer; |
pole2 = array[1..50]of char; |
var |
telefonni_cislo, ICO, DIC: pole1; |
jmeno, prijmeni: pole2; |
Tímto způsobem jsou definovány nové datové typy pole1 a pole2, na které se pak lze odvolávat v části deklarace proměnných (část, začínající slovem var), jak bylo ukázáno výše. Někdy se však stává, že uvedený datový typ pole definujeme pouze pro jedinou proměnnou, potom je správný i zápis:
var |
telefonni_cislo: array[1..15]of integer; |
prijmeni: array[1..50]of char; |
Tímto způsobem pak definujeme pole patnácti číslic pro uložení jednoho telefonního čísla a pole padesáti znaků pro uložení jednoho příjmení.
Jedinou operací, která je pro proměnné typu pole definována, je označování složek - selektor pole. Výsledkem této operace je odkaz na příslušnou složku pole.
Přiřazovací příkaz, kterým se proměnné přiřadí její hodnota, můžeme u typu pole rozšířit jak na jeho složky, tak i na celé pole. Pro jednotlivé složky vypadá přiřazovací příkaz takto:
ICO[3] := 5; |
DIC[8] := 1; . |
A pro přiřazení proměnných celého pole vypadá přiřazovací příkaz takto:
DIC := ICO; , |
což odpovídá tomuto zápisu:
DIC[1] := ICO[1]; DIC[2] := ICO[2]; DIC[3] := ICO[3]; ... DIC[15] := ICO[15]; . |
Pozor však na přiřazování proměnných celého pole mezi dvěma na první pohled stejnými poli. Pokud si nadefinujete pole tímto způsobem:
type |
telefon = array[1..15]of integer; |
var |
telefonni_cislo1: telefon; |
telefonni_cislo2: array[1..15]of integer; |
a potom provedete přiřazovací příkaz:
telefonni_cislo2 := telefonni_cislo1; , |
jako výsledek obdržíte chybové hlášení jazyka Pascal, neboť obě proměnné jsou různého typu, i když jsou pole. Proměnná telefonni_cislo1 je námi nadefinovaného nového typu telefon, zatímco proměnná telefonni_cislo2 je standardního typu pole.
V Pascalu je typ řetězec posloupností znaků s počitadlem délky na začátku. Každý řetězec má pevnou velikost (implicitně 255 znaků), i když většinou obsahuje znaků méně. Příklad je zde:
var |
Jmeno: string; |
Titul: string[50]; |
Proměnná Jmeno je řetězcem 255 znaků, proměnná Titul může obsahovat maximálně 50 znaků, může však obsahovat i méně než 50 znaků. Řetězce tohoto typu se zapisují v apostrofech, např.:
'To je vse.' |
'That''s all.' |
Jak je vidět z předcházejícího příkladu, pokud chceme uložit apostrof jakožto znak, musí se tento apostrof zdvojit.
Tento datový typ můžeme také chápat jako pole znaků a s ním jako s datovým typem pole také takto pracovat. K jednotlivým znakům přistupujeme pomocí indexů 1 až 255. V paměti počítače je však řetězec určité délky o jeden znak delší, a to o první znak s indexem 0. Ten totiž (respektive jeho ASCII kód) udává délku řetězce.
Nad tímto typem existuje několik standardních operací a funkcí, které uvedeme v tabulce:
lenght (ret) | vrací dynamickou délku řetězce ret, výsledek je typu word |
copy (ret, poz, poc) | vrací podřetězec o délce poc, obsažený v řetězci ret, od stanovené pozice poz |
concat (ret1, ret2, ... , retn) | vrací spojení uvedených řetězců (obvykle se ale používá +) |
pos (podret, ret) | vrací pozici prvního výskytu podřetězce podret v řetězci ret, výsledek je typu word; při neúspěšném hledání vrací hodnotu 0 |
delete (ret, poz, del) | vymaže podřetězec ret délky del, začínající na pozici poz |
insert (podret, ret, poz) | vloží podřetězec podret do řetězce ret od pozice poz |
str (cis, ret) | převede číselnou hodnotu cis do řetězcové proměnné ret |
val (ret, prom, typ) | převede řetězcovou proměnnou ret na číselnou proměnnou prom, ppřeváděný řetězec může obsahovat pouze číslice, desetinnou tečku, znaménka a písmena e, E (inverzní procedura k str) |
+ | zřetězení dvou řetězců, výsledkem je opět řetězec; pokud je výsledný řetězec delší než 255 znaků, je zkrácen na délku 255 znaků |
Tento datový typ se skládá z určitého počtu položek, které mohou být různého typu. každá položka má přiděleno jméno, neboli identifikátor položky, pomocí něhož se provádí výběr položky. Na příkladu si ukážeme, jak taková deklarace typu záznam v programu vypadá:
type |
Datum = record |
den: 1.31; |
mesic: 1..12; |
rok: 1..2000 |
end; |
Informace = record |
jmeno, prijmeni: array[1..15]of charů |
datum_narozeni: datum; |
pohlavi: (muz, zena); |
stav: (svobodny, zenaty, rozvedeny, vdovec) |
end; |
var |
Osoba: Informace; |
Výše uvedený příklad nám ukazuje, že položky nemusí být jen pevných předdefinovaných typů, ale mohou být i námi definovaných typů. Příkladem je položka datum_narození, která je sama datový typ záznam, který jsme definovali výše.
Zpřístupnění položky proměnné typu záznam má na starosti tzv. selektor záznamu a má tvar:
vzhledem k našemu příkladu:
atd.
V případech, kdy v určité části programu pracujeme s položkami téhož záznamu, přichází nám vhod příkaz with, který nám usnadňuje přístup k jednotlivým položkám. V praxi tento příkaz pracuje takto:
with Osoba do |
begin |
jmeno := 'David'; |
prijmeni := 'Padrta'; |
with datum_narozeni do |
begin |
den := 11; |
mesic := 2; |
rok := 1975 |
end; |
pohlavi := muz; |
stav := svobodny |
end; |
Tak, to byly záznamy. Pokud navíc provedeme malou obměnu této datové struktury, získáme tzv. VARIANTNÍ ZÁZNAMY. Jsou to takové záznamy, které mají ve své struktuře navíc ještě variantní část. Někdy se totiž stane, že definujeme takové typy, které jsou pouze různé varianty téhož typu, a proto je lze napsat do variantní části. Typy, specifikující několik variant záznamu, se nazývají typy variantních záznamů. Samozřejmě nesmí chybět příklad:
type Informace = record |
jmeno, prijmeni: array[1..15]of char; |
datum_narozeni: datum; |
case pohlavi: (muz, zena) of |
muz: (vaha: real; |
vousy: boolean); |
zena: (miry: array[1..3]of integer) |
end; |
Tento datový typ je složen z ordinálních typů. Každý takový typ určuje typ prvků dané množiny a nazývá se bázový typ. Deklarace vypadá takto:
type |
mnozina_znaku = set of char; |
Jestliže datový typ char označuje celkem n různých znaků, pak typ mnozina_znaku označuje množinu znaků, kterou tvoří všechny podmnožiny množiny znaků typu char. Bázový typ nesmí mít více než 256 možných hodnot a ordinální hodnoty nejnižšího a nejvyššího prvku musí být v rozsahu 0..255. Každý množinový typ zahrnuje také prázdnou množinu. Množinové a relační operace jsou:
+ | sjednocení dvou množin |
- | rozdíl jedné množiny od druhé |
* | průnik dvou množin |
= | rovnost dvou množin |
<> | nerovnost dvou množin |
<= | "je podmnožinou" |
>= | "obsahuje" |
Operandy mohou být pouze množiny s kompatibilními bázovými prvky. Typ výsledku operací +, *, a - je dán typem operandů, typ výsledků relačních operátorů je Boolean.
Příklad:
type |
barva = (cervena, zelena, modra, zluta, hneda); |
odstin = set of barva; |
var |
odstin1, odstin2: odstin; |
Dále u tohoto typu můžeme testovat přítomnost určitého prvku v množině, a to pomocí operátoru in. Tento operátor vrací hodnotu TRUE, pokud hledaný prvek se v množině nachází, jinak vrací operátor hodnotu FALSE. A opět příklad:
cervena in odstin1 + odstin2; |
type |
soubor = file of složka; |
Soubor je v programu definován jako proměnná, u které se musí určit typ. U souborů rozlišujeme tři typy:
var |
soubor_cisel : file of integer; |
var |
soubor_znaku : text; |
var |
netypovy_soubor : file; |
Soubory bez udaného typu se používají ve vstupně/výstupních operacích pro přístup k diskovému souboru bez ohledu na jeho vnitřní formát.
Následující tabulka uvádí přehled procedur a funkcí, používaných se soubory:
Procedura / Funkce | Význam | textové | typové | netypové |
---|---|---|---|---|
fce IOResult | test úspěšnosti operace vstupu/výstupu | ANO | ANO | ANO |
proc. Assign | přiřazení proměnné souboru | ANO | ANO | ANO |
proc. Append | otevření souboru pro vkládání na konec | ANO | NE | NE |
proc. Reset | otevření existujícího souboru | ANO | ANO | ANO |
proc. Rewrite | vytvoření a otevření nového souboru | ANO | ANO | ANO |
proc Close | uzavření otevřeného souboru | ANO | ANO | ANO |
proc. Blockread | čtení z netypového souboru | NE | NE | ANO |
proc. Blockwrite | zápis do netypového souboru | NE | NE | ANO |
fce Eof | zjištění stavu konce souboru | ANO | ANO | ANO |
fce Eoln | zjištění stavu konce řádky | ANO | NE | NE |
proc. Flush | vyprázdní vyrovnávací paměť text. souboru | ANO | NE | NE |
proc. SetTextBuf | nastaví vyrovnávací paměť text. souboru | ANO | NE | NE |
fce FilePos | zjistí pozici ukazatele v souboru | NE | ANO | ANO |
fce FileSize | zjistí počet položek v souboru | NE | ANO | ANO |
proc. Seek | nastaví ukazatel souboru | NE | ANO | ANO |
fce SeekEof | zjistí stav konce textového souboru | ANO | NE | NE |
fce SeekEoln | zjistí stav konce řádky | ANO | NE | NE |
proc. Truncate | omezení velikosti souboru | NE | ANO | ANO |