C++ 例付きのポインタ
ポインタとは何ですか?
In C++ポインターは、別の変数のアドレスを保持する変数を指します。通常の変数と同様に、ポインターにはデータ型があります。たとえば、整数型のポインターは、整数型の変数のアドレスを保持できます。文字型のポインターは、文字型の変数のアドレスを保持できます。
ポインタはメモリアドレスのシンボル表現として考えてください。ポインタを使用すると、プログラムは参照呼び出しをシミュレートできます。また、動的なデータ構造を作成および操作することもできます。 C++ポインタ変数は、別の変数によって指し示されるメモリ内の特定のアドレスを指す変数を指します。
の住所 C++
理解する C++ ポインターを使用するには、コンピューターがデータを保存する方法を理解する必要があります。
変数を作成すると、 C++ プログラムには、コンピュータのメモリの一部の領域が割り当てられます。この変数の値は、割り当てられた場所に保存されます。
コンピュータのメモリ内のデータが保存されている場所を知るには、 C++ 提供する & (参照) 演算子。この演算子は変数が占めるアドレスを返します。
たとえば、x が変数の場合、&x は変数のアドレスを返します。
ポインタ宣言の構文
の宣言 C++ 構文は次のようになります。
datatype *variable_name;
- データ型はポインタの基本型であり、有効なものでなければならない。 C++ データ・タイプ。
- variable_name はポインター変数の名前である必要があります。
- 上でポインタ宣言に使用されているアスタリスクは、乗算演算を実行するために使用されるアスタリスクに似ています。変数をポインタとしてマークするのはアスタリスクです。
以下は有効なポインタ宣言の例です。 C++:
int *x; // a pointer to integer double *x; // a pointer to double float *x; // a pointer to float char *ch // a pointer to a character
参照演算子 (&) と参照演算子 (*)
参照演算子 (&) は変数のアドレスを返します。
逆参照演算子 (*) は、メモリ アドレスに格納されている値を取得するのに役立ちます。
例:
num という名前の変数があり、アドレス 0x234 に格納され、値 28 が格納されているとします。
参照演算子 (&) は 0x234 を返します。
逆参照演算子 (*) は 5 を返します。
例1:
#include <iostream> using namespace std; int main() { int x = 27; int *ip; ip = &x; cout << "Value of x is : "; cout << x << endl; cout << "Value of ip is : "; cout << ip<< endl; cout << "Value of *ip is : "; cout << *ip << endl; return 0; }
出力:
仕組み:
コードのスクリーンショットは次のとおりです。
コードの説明:
- iostream ヘッダー ファイルをインポートします。 これにより、ヘッダー ファイルで定義された関数をエラーを発生させることなく使用できるようになります。
- std 名前空間を含めると、呼び出さずにそのクラスを使用できます。
- main() 関数を呼び出します。 プログラム ロジックは、この関数の本体内に追加する必要があります。 { は関数本体の始まりを示します。
- 整変数 x を宣言し、値 27 を割り当てます。
- ポインタ変数*ipを宣言します。
- 変数xのアドレスをポインタ変数に格納します。
- コンソールにテキストを出力します。
- 変数 x の値を画面に表示します。
- コンソールにテキストを出力します。
- 変数 x のアドレスを出力します。 アドレスの値は変数 ip に格納されました。
- コンソールにテキストを出力します。
- ポインタのアドレスに格納されている の値を出力します。
- プログラムは、実行が成功すると値を返す必要があります。
- main() 関数の本体の終わり。
ポインタと配列
配列とポインターは、関連する概念に基づいて機能します。 ポインターを持つ配列を操作する場合は、注意すべき点がいくつかあります。 配列名自体は配列のベース アドレスを示します。 これは、配列のアドレスをポインターに割り当てる場合、アンパサンド (&) を使用すべきではないことを意味します。
例:
p = arr;
arr は配列のアドレスを表すため、上記は正しいです。 別の例を次に示します。
p = &arr;
上記は誤りです。
配列を暗黙的にポインタに変換できます。 例えば:
int arr [20]; int * ip;
以下は有効な操作です:
ip = arr;
上記の宣言の後、ip と arr は等価になり、プロパティを共有します。 ただし、ip には別のアドレスを割り当てることができますが、arr には何も割り当てることができません。
例2:
この例は、ポインターを使用して配列を走査する方法を示しています。
#include <iostream> using namespace std; int main() { int *ip; int arr[] = { 10, 34, 13, 76, 5, 46 }; ip = arr; for (int x = 0; x < 6; x++) { cout << *ip << endl; ip++; } return 0; }
出力:
コードのスクリーンショットは次のとおりです。
コードの説明:
- 整数ポインタ変数 ip を宣言します。
- arr という名前の配列を宣言し、そこに 6 つの整数を格納します。
- arr を IP に割り当てます。 ip と arr は等価になります。
- for ループを作成します。 ループ変数 x は、インデックス 0 から 5 までの配列要素を反復処理するために作成されました。
- ポインタIPのアドレスに格納されている値を出力します。反復ごとに6つの値が返され、合計XNUMX回の繰り返しが行われます。endlは C++ 終了行を意味するキーワード。このアクションにより、各値が印刷された後にカーソルを次の行に移動できます。各値は個別の行に印刷されます。
- 反復ごとにポインタを次の int 位置に移動します。
- for ループの終わり。
- プログラムは実行が成功したときに何かを返さなければなりません。
- main() 関数本体の終わり。
NULLポインタ
割り当てられる正確なアドレスがない場合は、ポインター変数に NULL を割り当てることができます。 それは宣言中に行う必要があります。 このようなポインターは、ヌル ポインターとして知られています。 その値はゼロで、iostream などの多くの標準ライブラリで定義されています。
例3:
#include <iostream> using namespace std; int main() { int *ip = NULL; cout << "Value of ip is: " << ip; return 0; }
出力:
コードのスクリーンショットは次のとおりです。
コードの説明:
- ポインタ変数 ip を宣言し、それに NULL 値を割り当てます。
- ポインタ変数 ip の値をテキストとともにコンソールに表示します。
- プログラムは正常に完了すると値を返す必要があります。
- main() 関数の本体の終わり。
変数のポインタ
連絡先 C++、コンピュータのメモリから直接データを操作できます。
メモリ空間は、必要に応じて割り当てたり、再割り当てしたりできます。 これはポインター変数によって可能になります。
ポインタ変数は、別の変数が指すコンピュータのメモリ内の特定のアドレスを指します。
次のように宣言できます。
int *p;
または、
int* p;
この例では、ポインター変数 p を宣言しました。
メモリアドレスを保持します。
アスタリスクは、ポインターを意味する逆参照演算子です。
ポインタ p はメモリ アドレス内の整数値を指します。
例4:
#include <iostream> using namespace std; int main() { int *p, x = 30; p = &x; cout << "Value of x is: " << *p; return 0; }
出力:
コードのスクリーンショットは次のとおりです。
コードの説明:
- ポインター変数 p と変数 x を値 30 で宣言します。
- 変数 x のアドレスを p に代入します。
- ポインタ変数 p の値をテキストとともにコンソールに表示します。
- プログラムは正常に完了すると値を返す必要があります。
- main() 関数の本体の終わり。
ポインタの適用
の機能 C++ 関数は 1 つの値のみを返すことができます。さらに、関数内で宣言されたすべての変数は関数呼び出しスタックに割り当てられます。関数が戻るとすぐに、スタック変数はすべて破棄されます。
関数への引数は値で渡され、変数に変更を加えても渡される実際の変数の値は変わりません。次の例はこの概念を説明するのに役立ちます:-
例5:
#include <iostream> using namespace std; void test(int*, int*); int main() { int a = 5, b = 5; cout << "Before changing:" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; test(&a, &b); cout << "\nAfter changing" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; return 0; } void test(int* n1, int* n2) { *n1 = 10; *n2 = 11; }
出力:
コードのスクリーンショットは次のとおりです。
コードの説明:
- XNUMX つの整数パラメータを取る test という名前の関数のプロトタイプを作成します。
- main() 関数を呼び出します。 本体内にプログラムロジックを追加します。
- それぞれの値が 5 である XNUMX つの整数変数 a と b を宣言します。
- コンソールにテキストを出力します。 endl (終了行) はカーソルを移動して、次の行の印刷を開始します。
- 変数 a の値を他のテキストと一緒にコンソールに出力します。 endl (終了行) はカーソルを移動して、次の行の印刷を開始します。
- 変数 b の値を他のテキストと一緒にコンソールに出力します。 endl (終了行) はカーソルを移動して、次の行の印刷を開始します。
- 変数 a と b のアドレスをパラメーターとして受け取る test() という名前の関数を作成します。
- コンソールにテキストを出力します。 \n は、テキストが印刷される前に新しい空白行を作成します。 endl (終了行) は、テキストの印刷後にカーソルを移動して次の行の印刷を開始します。
- 変数 a の値を他のテキストと一緒にコンソールに出力します。 endl (終了行) はカーソルを移動して、次の行の印刷を開始します。
- 変数 b の値を他のテキストと一緒にコンソールに出力します。 endl (終了行) はカーソルを移動して、次の行の印刷を開始します。
- プログラムは正常に完了すると値を返す必要があります。
- main() 関数の本体の終わり。
- 関数 test() を定義します。 この関数は 1 つの整数ポインター変数 *n2 と *nXNUMX を取る必要があります。
- ポインター変数 *n1 に値 10 を割り当てます。
- ポインター変数 *n2 に値 11 を割り当てます。
- 関数 test() の本体の終わり。
関数 test 内で変数 a と変数 b に新しい値が代入されても、関数呼び出しが完了すると、外側の関数 main には反映されません。
ポインタを関数の引数として使用すると、関数内で変数の実際のアドレスを渡すことが容易になり、変数に対して実行されたすべての変更が外側の関数に反映されます。
上記の場合、関数 'test' は変数 'a' と 'b' のアドレスを持ちます。 これら XNUMX つの変数は関数「test」から直接アクセスできるため、これらの変数に加えられた変更は呼び出し側関数「main」に反映されます。
ポインターを使用する利点
ポインターを使用する利点と利点は次のとおりです。
- ポインタは、他のアドレスを格納する変数です。 変数 C++.
- ポインタを使用して、関数によって複数の変数を変更したり返したりすることができます。
- メモリは、ポインタを使用して動的に割り当てたり割り当て解除したりできます。
- ポインタはプログラムの複雑さを簡素化するのに役立ちます。
- ポインタを使用することでプログラムの実行速度が向上します。
まとめ
- ポインタとは、別の変数のアドレスを保持する変数を指します。
- 各ポインターには有効なデータ型があります。
- ポインタはメモリ アドレスを記号的に表現したものです。
- ポインターを使用すると、プログラムは参照による呼び出しをシミュレートし、動的データ構造を作成および操作できます。
- 配列 ポインターは関連する概念を使用します。
- 配列名は配列のベースを示します。
- 配列のアドレスをポインターに割り当てる場合は、アンパサンド (&) を使用しないでください。
- ポインター変数を割り当てる特定のアドレスがない場合は、それに NULL を割り当てます。