FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgFromPtrToRef

目次→教本→プログラマーのための案内From Pointers to References←オリジナル・サイト

ポインターから参照へ 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

Reference は、Pointer と完全には同じ機能を提供しませんが、代わりに参照を使うとコーディングを簡素化できます。

序文:
参照とポインターは、密接に関連しています。
実際、変数とその異なる参照は、同じオブジェクトにアクセスできるため、同じアドレスを保持します。

参照は、オブジェクトのアドレスの操作をカプセル化し、逆参照ポインターとして使われます。
ここでの違いは、逆参照を実行する必要がない、という事実にあります。

参照は、ポインタよりもはるかに簡単に処理できるため、コードは、より安全になります。

ポインターに関する注意
アドレスは値です。
ユーザーは、この値を変数に保存できます。
ポインターは、他のオブジェクトのアドレス、たとえば別の変数のアドレス、を含む正確な変数です。
ポインターの値は、変更できます。
これは通常、ポイントされた変数が、メモリに移動されることを意味するのではなく、ポインターが他の何かを指すことを意味します。
ポインターが指しているものを正確にするために、ポインターには型があります。
この型は通常、ポイントされたオブジェクトの型から、構築されます。
これにより、コンパイラーは、ポインターを介してメモリー内で行われた操作が、有効であることを検証できます。

ポインターの最も一般的な用途は、手続きのパラメーターに送る場合です。
重要なデータを、簡単な方法で操作することができます(非常に大きなデータ・ブロックを、手続きに渡す代わりに、たとえばこのブロックへのポインタを渡すことができます)。
別の用途は、割り当てられたメモリのアドレスを返す '[C]Allocate' および 'New' キーワードを使って、メモリ内で動的割り当てを行う場合です。
このアドレスは、どこかに保存され、使用方法を知っている必要があります。
最後に、ポインターを使ってテーブルを操作することもできます。しかし、FBでは、ユーザーは静的配列や動的配列を宣言し、専用の '()' (配列インデックス)演算子を使って要素にアクセスできるため、関心が低くなります。

また、手続きへのポインタを作成し、これらのポインタを使ってアルゴリズムをパラメータ化することもできます。
アルゴリズムの動作は、このように指定された手続きに依存します。

ユーザーが操作しているポインターのすべてが、初期化されていることを確認することは非常に重要です(つまり、ポインターは、有効なオブジェクトのアドレスを含むもので、それ以外の何ものでもないのです)。
実際、初期化されていないポインターを使って変数にアクセスすると、完全にランダムな場所で(作成時のポインターの初期値に応じて)メモリーを読み取るか、またはより深刻に書き込むことになります。
一般に、ポインターは、作成されるとすぐに初期化されます。後で使う場合は、ヌル値で初期化されます。
これにより、今後ポインタの有効性に関するテストを行ったり、少なくともエラーを検出できます。
実際、変数にアクセスするために NULL 値を持つポインターを使うと、多くの場合、プログラム保護違反が生成されます。しかし、プログラムがオプション '-exx' でコンパイルされた場合、実行時に常にエラーメッセージが生成されます。

逆参照演算子 '*' と '[]' を使って、ポインターから変数にアクセスできます。
'Any Ptr' ポインターは、特殊な型のポインターで、任意の型の変数を指すことができます。'Any Ptr' ポインターで '*' と '[]' 参照演算子を使うことはできません。 最初に、指定された型のポインターに変換する必要があります。
同様に、型付きポインターも、他の型のポインターに変換できます(必要な場合は、最初に 'Any Ptr' ポインターを使って変換します)。
オブジェクト・ポインター('po')の場合、オブジェクト・メンバーにアクセスするには、 "*" と "." を組み合わせるよりも、単一の '->' 演算子を使う方が便利です。 ('(*po).member' の代わりに 'po->member' を使います)。

ポインターは、異なる型で宣言することもできますが、ポイントされるオブジェクトのアドレス型と互換性があります(簡単な例として、'Zstring Ptr' と 'Ubyte Ptr' は、両方向で互換性のある 2つのポインター型です)。
継承構造の場合のより進化した方法では、派生型オブジェクトは、それらの共通ベースの1つの型から構築されたポインターで参照できます(このようなポインターで仮想メソッドおよび上書きされたメソッドが呼び出されると、ポリモーフィズムをアクティブ化できます)。

ポインターには、独自の算術があります。
この型では、インクリメント(1増やす)/デクリメント(1減らす)が特別です。
これは、ポインターの型のサイズに、追加または削除したい値を掛けることによって行われます。
これにより、指定された要素の数から、ポインタを適切に前後に移動できます。
ポインターが同じ型の場合、ポインター間で許可される唯一の操作は、減算です。
この操作は、ポインターが、(ポインターの型の)要素の同じ種類の構造を指す場合にのみ、意味があります。結果が、要素数の違いに対応するためです。

参照の概念
高水準言語では、ポインターの使用は抑制される傾向があり、コンパイラーによって管理される参照および動的配列が、優先されます。
参照は、メモリへの、明示的なユーザー・アクセスを排除することにより、いくつかのポインター機能を実現します。
これにより、多くの問題が回避されますが、代わりに、いくつかの使用法と最適化が、できなくなります。

メモリに表されたデータにアクセスする、2つの古典的な方法:その名前(変数または定数の場合)を使うか、アドレスを含むポインターを逆参照する、に加えて、
3番目の方法、参照の使用があります。
参照は、場合によっては絶対に不可欠であり、さらに、ポインターの使用に代わるものを提供します。

参照は、既存のオブジェクトに、新しい名前を関連付ける方法です。
参照は、参照変数を作成する構文が、初期化された変数の定義に、妙に似た式につながる場合でも、新しいオブジェクトを作成する手段ではありません。
この新しい名前の割り当ては、オブジェクトに元の名前がある場合、そのオブジェクトから元の名前を取り上げません。
新しい名前は、単に古い名前の同義語になります。 つまり、両方が同じオブジェクトを参照します。

値で行うのではなく、参照で変数を 渡す/返す ことにより、送信されたオブジェクトのコピーを作成することを避けます。
問題のオブジェクトが非常に大きい場合、コピー操作は、実行時およびメモリが、高くつく可能性があります。

ポインターのように、参照には独自の型があります。 これは、参照されるオブジェクトの型と同一であるか、そうでなければ、少なくとも互換性がある必要があります。

この最後のケース(タイプ互換だが、同じではない)に限っては、参照(ポインターのような)は、元のオブジェクトと同じ操作をすべて実行できるわけではありません。

オブジェクトへの参照を使うと、"pointer to object" の使用に関連する利点(速度とメモリの節約)を得ながら、オブジェクトポインターの使用によって暗示される書き込みの重さを回避できます( '@' 演算子、'*' や '[]' 演算子)。

注:
- FB では、参照の配列は、まだサポートされていません。
- FB では、UDT の非静的参照項目は、まだサポートされていません。
- FB では、手続きへの参照はサポートされていません(手続きへのポインタへの参照のみ)。

参照を使う
"References" セクションの次のページを参照ください:
- '参照を使う' ページ

参照
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2019-10-11 03:38:07
日本語翻訳:WATANABE Makoto、原文著作者:fxm

ホームページのトップに戻る

表示-非営利-継承