Dプログラミング-ポインター
Dプログラミングポインターは簡単で楽しく学ぶことができます。 一部のDプログラミングタスクはポインターを使用してより簡単に実行でき、動的メモリ割り当てなどの他のDプログラミングタスクはそれらなしでは実行できません。 簡単なポインターを以下に示します。
ポインターは変数を直接指すのではなく、変数のアドレスを指します。 ご存じのように、すべての変数はメモリロケーションであり、すべてのメモリロケーションには、メモリ内のアドレスを示すアンパサンド(&)演算子を使用してアクセスできるアドレスが定義されています。 定義された変数のアドレスを出力する以下を考慮してください-
上記のコードをコンパイルして実行すると、次の結果が生成されます-
ポインターとは
- ポインタ*は、値が別の変数のアドレスである変数です。 他の変数や定数と同様に、操作する前にポインターを宣言する必要があります。 ポインタ変数宣言の一般的な形式は-
ここで、 type はポインターの基本型です。有効なプログラミングタイプである必要があり、 var-name はポインター変数の名前です。 ポインターの宣言に使用したアスタリスクは、乗算に使用したものと同じアスタリスクです。 しかしながら;このステートメントでは、変数をポインターとして指定するためにアスタリスクが使用されています。 有効なポインター宣言は次のとおりです-
すべてのポインターの値の実際のデータ型は、整数、浮動小数点、文字、またはその他のいずれであっても同じで、メモリアドレスを表す長い16進数です。 異なるデータ型のポインターの唯一の違いは、ポインターが指す変数または定数のデータ型です。
Dプログラミングでのポインターの使用
ポインターを非常に頻繁に使用する場合、重要な操作はほとんどありません。
- ポインター変数を定義します
- 変数のアドレスをポインターに割り当てます
- 最後に、ポインター変数で使用可能なアドレスの値にアクセスします。
これは、オペランドで指定されたアドレスにある変数の値を返す単項演算子***を使用して行われます。 次の例では、これらの操作を利用しています-
上記のコードをコンパイルして実行すると、次の結果が生成されます-
NULLポインタ
割り当てられる正確なアドレスがない場合に備えて、ポインターNULLをポインター変数に割り当てることは常に良い習慣です。 これは、変数宣言時に行われます。 nullが割り当てられたポインターは、 null ポインターと呼ばれます。
nullポインターは、iostreamを含むいくつかの標準ライブラリで定義されたゼロの値を持つ定数です。 次のプログラムを検討してください-
上記のコードをコンパイルして実行すると、次の結果が生成されます-
ほとんどのオペレーティングシステムでは、アドレス0のメモリにアクセスすることは許可されていません。これは、メモリがオペレーティングシステムによって予約されているためです。 しかしながら;メモリアドレス0には特別な意味があります。ポインタがアクセス可能なメモリ位置を指すことを意図していないことを示します。
慣例により、ポインターにヌル(ゼロ)値が含まれている場合、何も指していないと見なされます。 ヌルポインタを確認するには、次のようにif文を使用できます-
したがって、すべての未使用のポインターにnull値が与えられ、nullポインターの使用を避ければ、初期化されていないポインターの誤った誤用を避けることができます。 多くの場合、初期化されていない変数はいくつかのジャンク値を保持し、プログラムのデバッグが困難になります。
ポインタ演算
ポインターで使用できる4つの算術演算子があります:+、-、、および-
ポインター演算を理解するために、アドレス1000を指す ptr という名前の整数ポインターを考えてみましょう。 32ビット整数を想定して、ポインタで次の算術演算を実行してみましょう-
次に、ptrがインクリメントされるたびに次の整数を指すため、 ptr は位置1004を指します。 この操作は、メモリ位置の実際の値に影響を与えることなく、ポインタを次のメモリ位置に移動します。
ポインターをインクリメントする
定数ポインターであるため増分できない配列名とは異なり、変数ポインターは増分できるため、プログラムでは配列の代わりにポインターを使用することをお勧めします。 次のプログラムは、配列の後続の各要素にアクセスするために変数ポインタをインクリメントします-
上記のコードをコンパイルして実行すると、次の結果が生成されます-
ポインターと配列
ポインターと配列は強く関連しています。 ただし、ポインターと配列は完全に互換性があるわけではありません。 たとえば、次のプログラムを検討してください-
上記のプログラムでは、2番目の要素を設定するためのvar.ptr [2]と、0番目の要素を設定するために使用されるptr [0]を見ることができます。 インクリメント演算子はptrで使用できますが、varでは使用できません。
上記のコードをコンパイルして実行すると、次の結果が生成されます-
ポインターへのポインター
ポインターへのポインターは、複数の間接指定またはポインターのチェーンの形式です。 通常、ポインターには変数のアドレスが含まれます。 ポインターへのポインターを定義すると、最初のポインターには2番目のポインターのアドレスが含まれます。これは、以下に示すように、実際の値を含む場所を指します。
ポインターへのポインターである変数は、そのように宣言する必要があります。 これは、名前の前に追加のアスタリスクを配置することにより行われます。 たとえば、次は、int型のポインタへのポインタを宣言する構文です-
ターゲット値がポインタへのポインタによって間接的に指し示されている場合、その値にアクセスするには、次の例に示すように、アスタリスク演算子を2回適用する必要があります-
上記のコードをコンパイルして実行すると、次の結果が生成されます-
ポインターを関数に渡す
Dを使用すると、ポインターを関数に渡すことができます。 そのためには、関数パラメーターをポインター型として宣言するだけです。
次の簡単な例では、ポインターを関数に渡します。
上記のコードを一緒にコンパイルして実行すると、次の結果が生成されます-
関数からポインターを返す
ポインターを使用して10個の数値を返す次の関数を考えてみましょう。これは、最初の配列要素のアドレスを意味します。
上記のコードをコンパイルして実行すると、次の結果が生成されます-
配列へのポインター
配列名は、配列の最初の要素への定数ポインターです。 したがって、宣言で-
配列名を定数ポインターとして使用すること、およびその逆も有効です。 したがって、*(balance + 4)は、balance [4]でデータにアクセスするための正当な方法です。
最初の要素のアドレスをpに保存すると、* p、(p + 1)、(p + 2)などを使用して配列要素にアクセスできます。 次の例は、上記のすべての概念を示しています-
上記のコードをコンパイルして実行すると、次の結果が生成されます-