Pointer Math (Delphi)
Delphi コンパイラ指令のリスト:インデックス への移動
型 |
スイッチ |
構文 |
{$POINTERMATH ON}、{$POINTERMATH OFF} |
デフォルト |
{$POINTERMATH OFF} |
スコープ |
ローカル |
詳細情報
Pointer math を使うと限られた範囲のインスタンスで、指定の型付きポインタが、ポインタ変数に単純代数操作を直接実行できる、サイズのある序数として単に処理されます。このようなポインタ変数を配列 [] 演算子を使用して境界のない配列として処理することもできます。前の例で説明した特定の型に対する配列のインデックスをインクリメントすることは、該当する型へのポインタをインクリメントすることと同じであることに注意してください。1 回のインクリメントは、1 バイトではなく、配列要素のサイズ(バイト単位)分ポインタを移動します。
POINTERMATH 指令のスコープはローカルです。つまり、この指令をオンにして、モジュールでオフにしない場合は、オンの状態がモジュールの最後まで有効です。また、この指令をオンにして型付きポインタを宣言する場合は、該当する型の任意の変数では、指令がオフにされた後でさえもポインタの先のサイズに応じた代数演算と配列のインデックス処理が可能です。同様に、この指令で囲まれたコード ブロックでは、ブロック内で任意の型付きポインタに対して代数操作が可能です。この場合は型付きポインタが POINTERMATH ON で最初に宣言されたかどうかは関係ありません。
この指令の対象は型付きポインタのみです。Pointer 型の変数は pointer math 機能を利用できません。Pointer 型は、サイズが 0 バイトである、void 要素を事実上指しているためです。型のない var または const パラメータは、ポインタではないので影響されません。
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 宣言 } public { Public 宣言 } 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]); // この行は Tiburon 以外ではコンパイルされません。 // ListRect((PRects + Count - 1)^); // この行もコンパイルされません。 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;