Předchozí strana Obsah Další strana

3. DATOVÉ TYPY


  1. Jednoduché datové typy
    1. Datový typ Integer
    2. Datový typ Boolean
    3. Datový typ Char
    4. Datový typ Výčet
    5. Datový typ Interval
    6. Datový typ Real
  2. Strukturované datové typy
    1. Datový typ Pole
    2. Datový typ String
    3. Datový typ Záznam
    4. Datový typ Množina
    5. Datový typ Soubor

3.1. JEDNODUCHÉ DATOVÉ TYPY

Jednoduché datové typy jsou definovány svým identifikátorem a typem v deklarační oblasti. Pro tyto typy jsou definovány relace rovnost a nerovnost dvou hodnot a dále relace větší a menší.

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

3.1.1. DATOVÝ TYP INTEGER

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

3.1.2. DATOVÝ TYP BOOLEAN

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

3.1.3. DATOVÝ TYP CHAR

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)

3.1.4. DATOVÝ TYP VÝČET

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:

succ(podneli) = utery
pred(podzim) = leto
ord(patek) = 4

3.1.5. DATOVÝ TYP INTERVAL

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:

ord(patek) = 4
ord('A') = 65
'A' < 'B' < 'C' < ... < 'Z'

3.1.6. DATOVÝ TYP REAL

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:

integer --> real:
tato konverze je implicitní: pokud proměnná X typu integer má hodnotu 2 a Y je typu real, po přiřazovacím příkazu Y := X bude mít proměnná Y hodnotu 2.0
real --> integer:
tato konverze implicitní není a proto jsou pro ni zavedeny dvě funkce:

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.

 

3.2. STRUKTUROVANÉ DATOVÉ TYPY

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í.

3.2.1. DATOVÝ TYP POLE

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.

3.2.2. DATOVÝ TYP STRING - ŘETĚZEC

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ů

3.2.3. DATOVÝ TYP ZÁZNAM

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:

proměnná_typu_záznam.identifikátor položky

vzhledem k našemu příkladu:

Osoba.jmeno;
Osoba.datum_narozeni.mesic;

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

3.2.4. DATOVÝ TYP MNOŽINA

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

3.2.5. DATOVÝ TYP SOUBOR

Typ soubor tvoří posloupnost položek typu složka. Složky mohou být libovolného datového typu kromě typu soubor a strukturovaného typu se složkou typu soubor. Deklarace v programu vypadá takto:

   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:

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

Předchozí strana Obsah Další strana