Delphi でのポインタの理解と使用

コンピューター プログラミングのイラスト

エレナブ/ゲッティイメージズ





ポインターはそれほど重要ではありませんが デルファイ 彼らはCにあるように、または C++ 、それらは非常に「基本的な」ツールであり、ほとんど何でも関係があります プログラミング 何らかの方法でポインターを処理する必要があります。

そのため、文字列やオブジェクトが実際には単なるポインターであることや、OnClick などのイベント ハンドラーが実際にはプロシージャへのポインターであることについて読むことがあります。



データ型へのポインタ

簡単に言えば、ポインターはメモリ内の任意のアドレスを保持する変数です。

この定義を具体化するには、アプリケーションで使用されるすべてのものがコンピュータのメモリのどこかに保存されることに注意してください。ポインターは別の変数のアドレスを保持するため、その変数を指すと言われます。



ほとんどの場合、Delphi のポインタは特定の型を指します。

|_+_|

構文 ポインターデータ型を宣言するには、 キャレット (^) .上記のコードでは、iValue は整数型の変数で、pIntValue は整数型のポインターです。ポインターはメモリ内のアドレスにすぎないため、iValue 整数変数に格納されている値の場所 (アドレス) をポインターに割り当てる必要があります。

@ 演算子 変数 (または以下で説明する関数またはプロシージャ) のアドレスを返します。 @ 演算子に相当するのは アドレス関数 . pIntValue の値は 2001 ではないことに注意してください。

このサンプル コードでは、pIntValue は型付き整数ポインターです。良いプログラミング スタイルは、型付きポインタをできる限り使用することです。 Pointer データ型は汎用ポインター型です。任意のデータへのポインターを表します。



ポインター変数の後に「^」が表示されると、ポインターが逆参照されることに注意してください。つまり、ポインタが保持するメモリアドレスに格納されている値を返します。この例では、変数 j は iValue と同じ値を持ちます。 iValue を j に代入するだけでは意味がないように見えるかもしれませんが、このコードはほとんどの Win API 呼び出しの背後にあります。

NIL ポインタ

割り当てられていないポインターは危険です。ポインターを使用すると、コンピューターのメモリを直接操作できるため、(誤って) メモリ内の保護された場所に書き込もうとすると、アクセス違反エラーが発生する可能性があります。これが、ポインタを常に NIL に初期化する必要がある理由です。



NIL は、任意のポインターに割り当てることができる特別な定数です。 nil がポインターに割り当てられると、ポインターは何も参照しません。たとえば、Delphi は空の

文字ポインター

基本型 PAnsiChar および PWideChar は、AnsiChar および WideChar 値へのポインターを表します。ジェネリック PChar は、Char 変数へのポインターを表します。

これらの文字ポインタは、ヌル終了を操作するために使用されます 文字列. PChar は、null で終わる文字列またはそれを表す配列へのポインターであると考えてください。



レコードへのポインタ

レコードまたはその他のデータ型を定義する場合、その型へのポインターも定義するのが一般的です。これにより、大きなメモリ ブロックをコピーすることなく、型のインスタンスを簡単に操作できます。

レコード (および配列) へのポインターを持つ機能により、リンクされたリストやツリーとして複雑なデータ構造をセットアップすることがはるかに簡単になります。



|_+_|

リンク リストの背後にある考え方は、次のリンク アイテムへのアドレスを NextItem レコード フィールド内のリストに格納できるようにすることです。

レコードへのポインターは、たとえば、すべてのツリー ビュー アイテムのカスタム データを格納するときにも使用できます。

手続き型ポインタとメソッド ポインタ

Delphi におけるもう 1 つの重要なポインタの概念は、プロシージャ ポインタとメソッド ポインタです。

プロシージャまたは関数のアドレスを指すポインターは、手続き型ポインターと呼ばれます。メソッド ポインタは、プロシージャ ポインタに似ています。ただし、スタンドアロン プロシージャを指すのではなく、クラス メソッドを指す必要があります。

メソッド ポインターは、呼び出されている名前とオブジェクトの両方に関する情報を含むポインターです。

ポインターと Windows API

Delphi でのポインタの最も一般的な用途は、Windows API へのアクセスを含む、C および C++ コードへのインターフェースです。

ウィンドウズ API 関数は、Delphi プログラマーにはなじみのない多くのデータ型を使用します。 API 関数を呼び出す際のパラメーターのほとんどは、何らかのデータ型へのポインターです。前述のように、Windows API 関数を呼び出す場合、Delphi では null で終わる文字列を使用します。

多くの場合、API 呼び出しがバッファー内の値またはデータ構造へのポインターを返す場合、これらのバッファーとデータ構造は、API 呼び出しが行われる前にアプリケーションによって割り当てられる必要があります。 SHBrowseForFolder Windows API 関数は 1 つの例です。

ポインタとメモリ割り当て

ポインタの真の力は、プログラムの実行中にメモリを確保できることから生まれます。

このコードは、ポインターの操作が最初に思われるほど難しくないことを証明するのに十分なはずです。提供されたハンドルでコントロールのテキスト (キャプション) を変更するために使用されます。

|_+_|