Rekordy
Adam Boduch
Rekordy są zorganizowaną strukturą danych, połączona w jedną całość. Jest to jakby zestaw zawierający określone elementy.
1 Rekordy jako parametry funkcji i procedur
2 Deklarowanie rekordu jako zmiennej
3 Metody w rekordach
Rekordy również można przekazywać ? jako zestaw elementów ? do funkcji czy procedur w formie parametru.
Nowe rekordy można deklarować jako nowy typ danych lub jako zmienną przy użyciu słowa kluczowego Record.
type
TMyRecord = record
X : Integer;
Y : Integer;
end;
Budowa deklaracji rekordu, jak widać, jest specyficzna ? najpierw należy wpisać jego nazwę, a potem po znaku równości słowo kluczowe record
(uwaga, brak średnika na końcu!). Następnie wypisujemy elementy, z których ma się składać nasz rekord.
Jako że powyżej zadeklarowaliśmy rekord jako nowy typ danych, należy utworzyć dodatkowo zmienną wskazującą na ten typ. Przy tej okazji przedstawię nowy operator Delphi ? kropkę (.). Do poszczególnych pól rekordu odwołujemy się następująco:
MyRecord.X := 1;
po uprzednim utworzeniu zmiennej wskazującej na rekord.
Po co stosować rekordy? Czasem trzeba przekazać określoną strukturę jako parametr funkcji bądź procedury. Można by oczywiście przekazywać pojedynczo kolejne elementy do procedury, jednak często wygodniej przekazać jeden parametr ? w formie rekordu. Usprawnia to pracę i jest dość często stosowanym elementem programów.
Rekordy jako parametry funkcji i procedur
Napiszmy prosty program, który pobierze dwie liczby wpisane przez użytkownika i przekaże do procedury cały rekord.
Samo przekazanie rekordu do funkcji przebiega w sposób dość prosty:
type
TMyRecord = record
X : Integer;
Y : Integer;
end;
function Dzielenie(MyRecord : TMyRecord) : Integer;
begin
Result := MyRecord.X div MyRecord.Y;
end;
Delphi wymaga, aby do funkcji Dzielenie
został przekazany rekord TMyRecord
. Kolejno następuje podzielenie elementu X przez element Y rekordu i zwrócenie wartości dzielenia. Cały program wygląda tak jak na listingu poniżej.
program Recordapp;
{$APPTYPE CONSOLE}
type
TMyRecord = record
X : Integer;
Y : Integer;
end;
function Dzielenie(MyRecord : TMyRecord) : Integer;
begin
Result := MyRecord.X div MyRecord.Y;
end;
var
MyRecord : TMyRecord;
Result : Integer;
begin
Writeln('Podaj pierwszą liczbę');
Readln(MyRecord.X);
Writeln('Podaj drugą liczbę');
Readln(MyRecord.Y);
Result := Dzielenie(MyRecord);
Writeln('Rezultat dzielenia');
Writeln(Result);
Readln;
end.
Na samym początku tego programu zadeklarowano nowy typ ? TMyRecord
, który jest rekordem. Teraz, żeby takiego rekordu użyć, należy zadeklarować zmienną, która wskazuje na ten typ.
Dalsza część programu powinna być oczywista ? pobieramy tutaj dwie wartości od użytkownika i przypisujemy je do elementów rekordów, tak jak robimy to ze zwykłą zmienną. Następnie cały rekord przekazujemy do funkcji, która dokonuje dzielenia.
Deklarowanie rekordu jako zmiennej
Nie jest konieczne tworzenie nowego typu dla rekordu. Oznacza to, że zamiast deklarować kolejny rekord jako nowy typ (Type), można zadeklarować go jako zmienną:
var
Rec : record
X, Y : Integer;
end;
Wówczas nie jest też konieczne tworzenie nowej zmiennej ? od razu można zabrać się za przypisywanie danych do elementów rekordu.
Metody w rekordach
Delphi 8 wprowadza pewne innowacje w zapisie rekordów. Dotychczas rekord mógł zawierać jedynie Pola (ang. fields), czyli zmienne rekordowe. Teraz jest możliwe także dodawanie metod, co bardziej upodobnia rekordy do klas. Oczywiście, rekordy są prostszą strukturą niż klasy i nie mogą zwierać metod wirtualnych czy dynamicznych. Nie można dziedziczyć rekordów oraz przedefiniowywać metod.
Metody w rekordach deklaruje się identycznie jak w klasach:
type
TRecord = record
X, Y : Integer;
procedure Main;
end;
Należy zwrócić uwagę, że jawne wywołanie konstruktora w rekordzie nie jest możliwe. Oczywiście, istnieje możliwość jego deklaracji, ale jego wywołanie następuje automatycznie w momencie skorzystania z metody w rekordzie.
Deklaracja konstruktora musi nastąpić z użyciem słowa kluczowego Class, tak jak poniżej:
type
TRecord = record
X, Y : Integer;
procedure Main;
class constructor Create;
end;
W razie zaniechania użycia słowa kluczowego Class, Delphi wyświetli komunikat o błędzie: [Error] Uni1.pas(110): Parameterless constructors not allowed on record types.
Należy również pamiętać o specyficznej budowie nagłówka metody, tak jak w przypadku klas, czyli:
procedure/function Klasa.Nazwa [parametry]
Spójrzmy na poniższy fragment kodu:
procedure TWinForm2.Button1_Click(sender: System.Object; e: System.EventArgs);
var
R : TRecord;
begin
R.X := 57; // przydzielenie wartości
R.Main; // wywołanie metody
end;
{ TRecord }
class constructor TRecord.Create;
begin
MessageBox.Show('Rozpoczynam używanie rekordu TRecord...');
end;
procedure TRecord.Main;
begin
MessageBox.Show('Mój wiek: ' + Convert.ToString(X));
end;
Powyższy przykład jest oczywiście niezbyt praktyczny i użyteczny, ale pozwala na zaprezentowanie działania rekordów i wywoływania konstruktora. Można wkleić taki kod do swojego programu i zaobserwować jego działanie.
Po naciśnięciu przycisku najpierw w okienku informacyjnym pojawi się tekst: Rozpoczynam używanie rekordu TRecord...
, a dopiero później: Mój wiek: 57
.
W rekordach nie można używać destruktora. Przy próbie jego wykorzystania Delphi wyświetli komunikat o błędzie: [Error] Uni1.pas(111): PROCEDURE, FUNCTION, PROPERTY, or VAR expected lub [Error] Uni1.pas(111): Unsupported language feature: 'destructor'.
Metody deklarowane w rekordach są domeną języka Delphi dla .NET ? kompilator Delphi dla Win32 nie dopuści do kompilacji takiego kodu.
Zobacz też:
Nie będę się wcinał w dzieło mistrza dorzucę to tylko w komentarzu.
Istnieje możliwość deklarowania tablic w rekordach, wygląda to następująco:
type //Deklaracja rekordu z 2 tablicami 16 elementowymi
TDane = record
X : array[1..16] of integer;
Y : array[1..16] of integer;
end;
var
Dane : TDane; //rzutowanie
Begin
Dane.X[1]:=10; //przykład odwołania
End;