Zeigermathematik (Delphi)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Liste der Delphi-Compiler-Direktiven - Index


Typ

Option

Syntax

{$POINTERMATH ON} oder {$POINTERMATH OFF}

Vorgabe

{$POINTERMATH OFF}

Bereich

Lokal

Anmerkungen

Zeigermathematik bedeutet, dass ein gegebener typisierter Zeiger in einigen Fällen als eine skalierte Ordinalzahl behandelt wird. Somit können einfache arithmetische Operationen direkt mit der Zeigervariable durchgeführt werden. Sie können eine solche Zeigervariable auch unter Verwendung des Array-Operators [] als unbegrenztes Array behandeln. Beachten Sie bitte, dass in dem obigen Beispiel die Erhöhung des Index eines Array eines Typs gleichbedeutend der Erhöhung eines Zeigers auf diesen Typ ist. Die Erhöhung um eins vergrößert den Zeiger um die Größe eines Array-Elements in Byte, nicht um ein Byte.

Der Gültigkeitsbereich der Direktive POINTERMATH ist lokal. Das heißt: Wenn Sie die Direktive auf ON setzen und im Modul nicht wieder deaktivieren, bleibt sie nur bis zum Modulende aktiviert. Ebenso gilt: Wenn Sie einen typisierten Zeiger mit dieser Direktive auf ON deklarieren, lässt jede Variable dieses Typs skalierte Zeigerarithmetik und Array-Indizierung zu, auch nachdem die Direktive auf OFF gesetzt wurde. Außerdem gilt: Jeder Codeblock, der in diese Direktive eingeschlossen ist, lässt arithmetische Operationen für ALLE typisierten Zeiger in diesem Block zu, unabhängig davon, ob der typisierte Zeiger ursprünglich mit POINTERMATH ON deklariert wurde.

Diese Direktive wirkt sich nur auf typisierte Zeiger aus. Variablen des Typs Pointer lassen keine Zeigermathematik zu, weil der Typ Pointer eigentlich auf ein void-Element mit der Größe 0 Byte zeigt. Untypisierte var- oder const-Parameter sind nicht betroffen, weil sie keine echten Zeiger darstellen.

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    CheckBox1: TCheckBox;
    ListBox1: TListBox;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  Rects = ^TRect;
  RectList = array[0..10] of TRect;
var
  Form1: TForm1;
  myRects: Rects;
  myRectList : RectList;
  procedure ListRect(Rect: TRect);
  procedure ListRects(PRects: Rects; Count: Integer);
  procedure ReadRects;
  procedure WriteRects;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ListRects(myRects, Form1.ComponentCount);
end;

procedure ListRect(Rect: TRect);
begin
  Form1.ListBox1.Items.Add(
    'BoundsRect: Left: ' + IntToStr(Rect.Left) +
    ' Right: ' + IntToStr(Rect.Right) +
    ' Top: ' + IntToStr(Rect.Top) +
    ' Bottom: ' + IntToStr(Rect.Bottom));
end;

{$POINTERMATH ON}
procedure ListRects(PRects: Rects; Count: Integer);
begin
  while Count > 0 do
  begin
    ListRect(PRects[Count - 1]); // Diese Zeile wird ohne Tiburon nicht compiliert.
//    ListRect((PRects + Count - 1)^); // Diese Zeile auch nicht.
    Dec(Count);
  end;
end;

procedure ReadRects;
var
  I, index : Integer;
  Temp: TWinControl;
begin
{$T-}
  index := 0;
  for I := Form1.ComponentCount - 1 downto 0 do
  begin
    if (Form1.Components[I] is TWinControl) then
    begin
      Temp := TWinControl(Form1.Components[I]);
      myRectList[index] := Temp.BoundsRect;
      index := index + 1;
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  myRects := Addr(myRectList);
  ReadRects;
end;