Konečně je tu nová lekce. Povíme si o docela užitečné věci. Konkrétně o vlastních datových typech. Možná to zní složitě, když si řeknete, že budete vytvářet datové typy, které jste sami vytvořili, ale věřte mi, je to jednoduché.
Všechny vlastní datové typy se definují za klíčovým slovem type. Poté, co je definujete, se už používají jako normální datové typy, např. integer. Teď si většinu z nich popíšeme.
Výčtový typ
Je typ, který nabývá hodnot, jež si sami zvolíme. Není na tom nic těžkého.
type SvetoveStrany = (sever, jih, vychod, zapad);
var smer: SvetoveStrany;
Proměnná smer je typu SvetoveStrany a může nabývat hodnot: sever, jih, vychod, zapad. Výčtový typ je ordinální, takže hodnoty představují čísla. Sever představuje číslo 0 a zapad představuje číslo 3. Pokud chcete mít v programu víc výčtových typů, tak si musíte dát pozor na to, aby do nich nešli zadávat stejné hodnoty.
type SvetoveStrany = (sever, jih, vychod, zapad);
WC = (zachod, vychod); //je chyba a překladač bude protestovat
Na to, proč tomu tak je, je jednoduchá odpověď. U typu SvetoveStrany představuje vychod číslo 2 a u typu WC číslo 1. S tím má překladač bohužel problém. Než vymýšlet alternativní název, je jednodušší dávat před hodnoty označení jakého jsou typu např.:
type SvetoveStrany = (SVsever, SVjih, SVvychod, SVzapad);
WC = (WCzachod, WCvychod);
Teď už vše funguje, jak má.
Záznamy
Je typ, který obsahuje libovolný počet různých proměnných. Definuje se takto:
type JmenoZaznamu = record
proměnná1: datový typ;
proměnná2: datový typ;
...
end;
Záznam může sloužit třeba jako evidence osob:
type
clovek = record
vek: integer;
jmeno: string;
prijmeni: string;
funkce: string;
nick: string;
end;
Se záznamem se pracuje následovně:
var osoba: clovek;
begin
osoba.vek := 23;
osoba.jmeno := 'Oskar';
osoba.prijmeni := 'Spojitel';
...
end;
Záznamy do sebe můžete kopírovat:
osoba1 := osoba2
Položkou záznamu může být klidně další záznam:
type
PC = record
monitor: string;
procesor: string;
grafarna: string;
RAM: string;
end;
clovek = record
vek: integer;
jmeno: string;
prijmeni: string;
funkce: string;
nick: string;
pocitac: PC;
end;
S takto vnořeným záznamem se pracuje podobně:
var osoba: clovek;
begin
osoba.pocitac.procesor := 'Intel celeron';
...
end;
Delphi nám umožňují si trošku zjednodušit práci se záznamy příkazem with, který zpřístupní všechny položky záznamu najednou:
...
with osoba do
begin
vek := 23;
jmeno := 'Oskar';
prijmeni := 'Spojitel';
...
end;
...
Pole
Proměnné, které jsme si doposud ukázali, obsahovaly vždy jen jednu hodnotu, ale to může být v některých případech omezující. Pole může obsahovat libovolný počet prvků určitého typu. Všechny tyto hodnoty jsou indexovány. A pomocí indexů se k nim přistupuje. Definice vypadá takto:
type pole = array [1..10] of integer;
var cisla: pole;
Toto pole obsahuje 10 prvků, které jsou indexovány od 1 do 10. K prvkům se přistupuje následovně:
begin
cisla[1] := 10;
cisla[2] := 9;
cisla[3] := 8;
end;
Výhodou Pascalu je, že pole nemusíte indexovat od nuly, ale jak se vám to hodí.
To ulehčuje docela dost práce, i když to má jisté nevýhody, které si za chvíli ukážeme.
type pole = array [26..36] of integer;
...
cisla[26] := 10;
...
Pole do sebe můžete kopírovat:
cisla := cisilka //předpokládejme že obě proměnné
// jsou stejného typu
Všechny hodnoty v poli cisla se přepíšou na hodnoty v poli cisilka.
Pro práci s poli se často využívá cyklus s pevným počtem opakování. Jednoduchá ukázka, jak do všech prvků pole uložit stejnou hodnotu:
for i := 26 to 36 do cisla[i] := 10;
Vícerozměrná pole
Pole může být jakéhokoliv typu a tedy i typu pole. Tím vznikají vícerozměrná pole. To znamená že v každém prvku může být libovolný počet prvků. Takto se definuje dvojrozměrné pole:
type pole = array [1..10, 1..10] of integer;
K prvkům se přistupuje pomocí dvou indexů:
var DvojRozP: pole;
i, j: integer;
begin
for i := 1 to 10 do
for j := 1 to 10 do
DvojRozP[i, j] := 10;
...
Do všech prvků pole se uloží hodnota 10. Pole může mít samozřejmě daleko více rozměrů než jen dva. Dvojrozměrný si můžeme představit na tabulce, trojrozměrný na kvádru. U dalších rozměrů už si to moc dobře představit nejde. A taky se ztrácí přehlednost. Navíc zabírají docela dost místa v paměti. S pamětí je to ještě horší o to, že velikost pole nelze měnit. Jedná se totiž o statickou datovou strukturu. U pole, nejen že nelze velikost pole měnit, ale ani ji nelze nastavit. Tento problém částečně řeší Otevřená pole.
Otevřená pole jako parametr
Pokud chceme vytvořit funkci/proceduru, která pracuje s poli a chceme, aby byla univerzální pro libovolné pole, tak použijeme otevřené pole. To znamená, že v parametru vynecháme velikost pole a pro zjištění skutečné velikosti použijeme standardní funkce Low a High.
type pole = array [0..40] of integer;
pole2 = array [0..11] of integer;
var prvni: pole;
druhe: pole2;
procedure NastavHodnotu (var pole:array of integer; i:integer);
var loop: integer;
begin
for loop := low(pole) to high(pole) do
pole[loop] := i;
end;
...
begin
NastavHodnotu(prvni, 10);
NastavHodnotu(druhe, 38);
end;
Procedura NastavHodnotu naplní všechny prvky libovolného pole typu integer libovolnou hodnotou. Otevřená pole mají bohužel i svoji nevýhodu. Jejich indexy by měli začínat od nuly. Jinak se můžete dostat do potíží. Funkce Low vždy vrací hodnotu 0 a High počet prvků -1. Tím můžou nastat nepříjemné chyby nebo problémy s přepočítáváním.
Úkol
Má to vůbec cenu? Vytvořte program, do kterého bude uživatel zadávat seznam zaměstnanců. Stačí, když v programu bude jeden Edit, komponenta do které se zadává text. A tlačítko, kterým se vždy potvrdí zadání údajů. O každém zaměstnanci by měly být min. tři údaje.
Edit se nachází pod záložkou Standart a text se ukládá ve vlastnosti text (nečekaně:)), která je typu string.