Joachim Mohr   Mathematik Musik Delphi

16. Lektion: Recordtypen

Dazu: with

Siehe auch in der Onlinehilfe unter:
  Delphi-Hilfe
    Inhalt
      Object-Pascalreferenz
        Datentypen...
          Strukturierte Typen
            Record-Typen
In der folgenden unit wird gezeigt, wie mit dem durch einen Record definierten Typ Tperson Variabeln deklariert und verwendet werden. Zum Beispiel:

var Nachbar: Tperson; //Definition Tperson siehe unten unit1

Dann enthält Nachbar 3 Felder, nämlich name, vorname und Geburtsjahr, die ihm auf folgende Weise zugeordnet werden können:
       nachbar.name        := 'Maier';  //string
       nachbar.vorname     := 'Hans';   //string
       nachbar.Geburtsjahr := 1982;     //integer

oder kürzer

      with nachbar do Begin
        name        := 'Maier';
        vorname     := 'Hans';
        Geburtsjahr := '1982'
      End;
Diese Konstruktion gilt auch für die später zu behandelnden Klassen.
(Und wurden bereits zum Beispiel bei button1.left := 0 verwendet.)

Beispiel 20.1: Schreibe in drei Editfelder die Namen, Vornamen und Geburtsjahre von Deinen Bekannten und klicke jeweils auf den Button. Die Daten werden dann angezeigt und in ein Memo geschrieben.

Hinweis: Platziere drei Editfelder, einen Button und ein Memo auf Dein Formular. Lösche dann den Inhalt Deiner Unit1 und kopiere die folgende Unit1 bis end. (mit Punkt) in die leere Seite ...Schon hast du ein laufffähiges Programm.

Versuche jedoch auch mit einer Neuen Anwendung zu starten. Schreibe dann nach Platzieren der drei Editfelder, des Buttons und des Memofeldes an die richtige Stelle type Tperson = record ..., die Funktionen und den Inhalt von procedure TForm1.Button1Click(Sender: TObject);.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Memo1: TMemo;

    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type Tperson = record name:         string;
                     vorname:       string;
                     Geburtsjahr:   integer;
              End;
//Neu!
//Ein record mit 3 Feldern

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure Showperson(person: Tperson);
begin
  showmessage(person.name+ ',' + person.vorname +
    ' ' + IntToStr(person.geburtsjahr));
end;

function liesperson:Tperson;
begin
  result.name := form1.edit1.Text;
  result.vorname := form1.edit2.Text;
  result.Geburtsjahr := StrToInt(form1.edit3.text);
end;

procedure schreibperson(person:Tperson);
begin
 form1.Memo1.lines.add(person.name);
 form1.Memo1.lines.add(person.vorname);
 form1.Memo1.lines.add(intToStr(person.Geburtsjahr));
end;

procedure TForm1.Button1Click(Sender: TObject);
  var person: TPerson;
begin
  person := liesperson;
  showperson(person);
  schreibperson(Person);
end;

end.
Die folgenden Funktionen verwenden with und tun genau dasselbe wie oben:

procedure Showperson(person: Tperson);
begin
  with person do
  showmessage(name+ ',' + vorname +
    ' ' + IntToStr(geburtsjahr));
end;

function liesperson:Tperson;
begin
  with result do Begin
    name := form1.edit1.Text;
    vorname := form1.edit2.Text;
    Geburtsjahr := StrToInt(form1.edit3.text);
  End;
end;

procedure schreibperson(person:Tperson);
begin
  with form1.memo1.lines do Begin
    add(person.name);
    add(person.vorname);
    add(intToStr(person.Geburtsjahr));
  End;
end;

Aufgabe 20.1.
                                                  -»
In der Vektorrechnung ergibt sich für die Gerade (x  Ortsvektor)

           -»     2        0              -»     2
        g: x  = (-1)  + t·(1)   für t = 4  x  =( 3)
                  5        4                    21
Dies wird in einem Programm (siehe Anhang am Ende der Aufgabe) algorithmisch mit Hilfe des Typs "Tvektor" berechnet. Das Programm ist noch verbesserungswürdig.
a) Schreibe eine Funktion für die Addition von Vektoren.

function vektoraddition(a,b:Tvektor):Tvektor;
begin
  //Hier sind ca. 3 Zeilen einzufügen
end;

b) Schreibe eine Funktion für die S-Multiplikation von Vektoren

function SMultiplikation(t:real; a:Tvektor):Tvektor;
begin
   //Hier sind ca. 3 Zeilen einzufügen
end;

c) Mit den Funktionen von Teil a) und b) läßt sich die
   Funktion "BerechnePunkt" vereinfachen.
   Wie sieht die Funktion aus ?

function BerechnePunkt(stuetzvektor,Richtungsvektor: Tvektor; t:real):TVektor;
begin
  //Eine Zeile genügt
end;


d) Die Funktion für die Wertzuweisung wird vorgeben:

function vektor(x1,x2,x3:real): Tvektor;
begin
  result.x1 := x1;
  result.x2 := x2;
  result.x3 := x3;
end;
Mit einer Prozedur "Zeige" kann man noch "showmessage(...)" auslagern. Wie lässt sich damit das Hauptprogramm vereinfachen?
procedure TForm1.Button1Click(Sender: TObject);
  var stuetzvektor,Richtungsvektor,Ortsvektor:Tvektor;
      t: real;
begin
  //Zwei Zeilen für Zuweisung Stuetzvektor und Richtungsvektor
  t := 4;
  Ortsvektor := BerechnePunkt(stuetzvektor,Richtungsvektor,t);
  Zeige(Ortsvektor);
end;
——————————————————————— Anhang Unit1 ———————————————————————
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
type Tvektor = record
              x1: real;
              x2: real;
              x3: real;
     End;
var
  Form1: TForm1;
implementation
{$R *.DFM}

function BerechnePunkt(stuetzvektor,Richtungsvektor: Tvektor; t:real):TVektor;
begin
 result.x1 := stuetzvektor.x1 + t*Richtungsvektor.x1;
 result.x2 := stuetzvektor.x2 + t*Richtungsvektor.x2;
 result.x3 := stuetzvektor.x3 + t*Richtungsvektor.x3;
end;


procedure TForm1.Button1Click(Sender: TObject);
  var stuetzvektor,Richtungsvektor,Ortsvektor:Tvektor;
      t: real;
begin
  stuetzvektor.x1 := 2;
  stuetzvektor.x2 := -1;
  stuetzvektor.x3 := 5;
  Richtungsvektor.x1 := 0;
  Richtungsvektor.x2 := 1;
  Richtungsvektor.x3 := 4;
  t := 4;
  Ortsvektor := BerechnePunkt(stuetzvektor,Richtungsvektor,t);
  Showmessage('Der Vektor hat die Koordinaten x1= '
            + FloatToStr(Ortsvektor.x1)
            + ' x2= ' + FloatToStr(Ortsvektor.x2)
            + ' x3= ' + FloatToStr(Ortsvektor.x3));
end;
Lösung

In Delphi sind schon zahlreiche Record vordefiniert. Zum Beispiel:
type TPoint = record
     X: Integer;
     Y: Integer;
end;
Im folgenden Beispiel verwenden wir einen sehr nützlichen Record, um Eigenschaften von Dateien auszulesen.

Beispiel 20.2: Um wichtige Daten einer Datei erfassen zu können hat Delphi den folgenden Recordtyp definiert:
TSearchRec = record
      Time: Integer;
      Size: Integer;
      Attr: Integer;
      Name: TFileName;
      //...
end;
Im folgenden Beispiel kann man dann alle Dateinamen im Verzeichnis "C:\" mit Zusatzangaben auslesen. (Es genügt Findfirst/Findnext/Findclose/DatetToStr nur oberflächlich zu studieren.)
procedure VerzeichnisEinlesen(dir:string);
    var SR: TSearchRec;
begin
  if dir[length(dir)]<>'\' then
    dir:=dir+'\';
  with Form1 do begin
    memo1.lines.Clear;
    memo1.WordWrap := false;
    memo1.Font.name := 'Courier New';
    if FindFirst(dir+'*.*',faAnyFile,SR)=0 then Begin
      repeat
          memo1.lines.add(sr.name+ ' ' + IntToStr(sr.size)+ ' ' +
             DateToStr(sr.Time));
      until FindNext(SR)<>0;
      FindClose(SR); //Nach jedem findfirst nötig, um sr freizugeben!
    End;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject); //benötigt uses FileCtrl
  var dir: string;
begin
   VerzeichnisEinlesen('c:\');
   {oder mit einer nützlichen Prozedur (mit uses FileCtrl);
   if SelectDirectory('Ordner wählen, dann OK klicken','',dir) then
     VerzeichnisEinlesen(dir);}
end;