Často se nám stává, že v poli záznamů potřebujeme zaznamenávat proměnné, nadeklarované pomocí klíčového slova record. Klasický příklad představuje seznam zaměstnanců, ale vlastně i každá jiná malá databáze, kvůli které by nestálo za to nutit uživatele, aby si spolu s programem instaloval nějaké dll moduly. Například pole pro evidenci 100 zaměstnanců (max.) by pak mohlo vypadat následovně:
type os = record jmeno : string[30]; prijmeni : string[39]; adresa_ulice : string[59]; adresa_mesto : string[59]; psc : string[5]; telefon : string[15]; end; var lide : array[0..99] of os;
Při dnešních cenách pamětí to nehraje velkou roli, ale velký rozsah dat se nám vrátí znovu, pokud budeme potřebovat s daty jakkoli manipulovat (například je setřídit). Proto je někdy výhodnější použít dynamicky alokované paměti a v poli držet jen ukazatele na data. Připravíme si obdobný datový typ (os) a ukazatel na něj (uos). V části deklarace proměnných (kapitola var) pak nadefinujeme pole pouze s ukazateli, nikoli s daty (jeden ukazatel má velikost 4 byty).
type uos = ^os; {vyjímka - zde je použití před deklarací přípustné, protože je předem známa velikost v paměti; později u struktur by to jinak ani nešlo napsat} os = record jmeno : string[30]; prijmeni : string[39]; adresa_ulice : string[59]; adresa_mesto : string[59]; psc : string[5]; telefon : string[15]; end; var lide : array[0..99] of uos;
V následujících příkladech je ukázka programu, který si můžete sami vyzkoušet. Struktura je zde zjednodušena na samotné jméno, a pro vyplnění cvičných dat je pak použita funkce "loadfromfile" - v tomto případě u komponenty Memo, kde je nejsnáze dostupná (také bychom si mohli vytvořit novou proměnnou typu TStrings, což by asi bylo rozumnější). (pro ladění programů je memo výhodnější, protože vidíme, co děláme).
Důležité! Program nejprve načte obsah mema, ale při následném kopírování do struktury (cyklem) buď doplní počet řetězců na 25 řetězcem "zzz" (opakovaně), nebo při delším souboru vezme jen prvních 25 řádek. Projeví se v datech, nikoli v Memu! (Použijte tlačítko Button1).
Tlačítko Button2 strukturu setřídí. Tlačítka lze přejmenovat (Caption).
Bez použití ukazatelů - pole v datové paměti:
unit Unit17; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; te = record name : string[50]; end; var Form1: TForm1; e1,e2 : te; e : array[1..25] of te; i : integer; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); var i: integer; begin if opendialog1.execute then memo1.lines.loadfromfile(opendialog1.filename); if memo1.lines.count <25 then begin for i:=1 to memo1.lines.count do e[i].name:=memo1.lines[i-1]; for i:= memo1.lines.count+1 to 25 do e[i].name:='zzz'; end else for i:=1 to 25 do e[i].name:=memo1.lines[i-1]; form1.caption := 'File has been load'; end; procedure TForm1.Button2Click(Sender: TObject); var i,j:integer; e3:te; begin for j:= 1 to 24 do for i:= 1 to j do if e[i].name > e[i+1].name then begin e3 := e[i]; e[i] := e[i+1]; e[i+1] := e3; end; memo1.lines.clear; for i:= 1 to 25 do memo1.lines.add(e[i].name); end; end.
Následně byl program upraven na použití pointerů (vyznačeno červeně a zeleně):
unit Unit17; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; te = record name : string[50]; end; tep = ^te; var Form1: TForm1; e1,e2 : te; e : array[1..25] of tep; i : integer; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); var i: integer; begin if opendialog1.execute then memo1.lines.loadfromfile(opendialog1.filename); if memo1.lines.count <25 then begin for i:=1 to memo1.lines.count do e[i]^.name:=memo1.lines[i-1]; for i:= memo1.lines.count+1 to 25 do e[i]^.name:='zzz'; end else for i:=1 to 25 do e[i]^.name:=memo1.lines[i-1]; form1.caption := 'File has been load'; end; procedure TForm1.Button2Click(Sender: TObject); var i,j:integer; e3:tep; begin for j:= 1 to 24 do for i:= 1 to j do if e[i]^.name > e[i+1]^.name then begin e3 := e[i]; e[i] := e[i+1]; e[i+1] := e3; end; memo1.lines.clear; for i:= 1 to 25 do memo1.lines.add(e[i]^.name); end; initialization for i:=1 to 25 do new(e[i]); end.
Zeleně označené symboly stříšky nejsou nezbytné, pokud je nenapíšete, Delphi si je domyslí.