Zeigermathematik (Delphi)
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;