C++の基礎:ポインタと変数のメモリアドレスの使い方を学ぶ
変数のメモリアドレス
RAM(Random Access Memory)は、任意の順序で読み書き可能なコンピュータのメモリで、一般的には作業データやマシンコードを格納するのに使用されます。また一部の操作では、ROM(Read Only Memory)を使用します。アプリケーションには多くの変数があり、その変数はすべてRAMに格納され、メモリ内の領域を占めています。これらの変数はメモリ位置を持ち、各メモリの場所にはアドレスが定義されており、アンパサンド(&)演算子を使ってアクセスすることができます。
ここでは、C++で最もよく使用される3つのデータ型のアドレスの例を示します。
int i=100;
float f=9.81;
char s[]="this text is in the memory";
std::cout << "adress of integer variable :" << &i << '\n';
std::cout << "adress of floating variable :" << &f << '\n';
std::cout << "adress of string :" << &s << '\n';
ポインタ
ポインタとは、アドレスを保持する変数のことで、ポインタを定義するには、変数名の前にアスタリスク文字 「* 」を使用します。ポインタは、CおよびC++プログラミング言語の最も強力な側面の1つです。これにより、データ全体をコピーすることなく、あらゆる種類のデータ(非常に長いサイズのビットマップやビデオ、その他のデータなどを含む)にアクセスすることができます。
例えば、整数型変数へのポインタは、以下のように定義することができます。
int *p;
ポインタ宣言には、3つの構文があります。
int* p; // Preferred
int *p;
int * p;
また浮動小数点数変数へのポインタは、以下のように定義できます。
float *f;
double *d;
またASCII文字列に対しては、char配列を定義することができます。
char *s;
ポインターの使い方
変数のアドレスへアクセスするためにアンパサンド「&」演算子を使用しますが、基本的にはこの&演算子を使用して変数のアドレスをポインタに設定します。簡単な整数値を使って説明しましょう。
int i;
pointer *p;
p = &i;
以下の例で、ポインタの使い方を理解してみましょう。
int i = 100; // declaring & initializing integer
int *p; // pointer declaration
p = &i; // address of i is copied to pointer variable
cout << "Value of i:" << i << '\n';
cout << "Adress of i:" << &i << '\n';
cout << "Address stored in pointer p: " << p << '\n';
cout << "Value of pointer variable: " << *p << '\n';
ここでは、整数変数iを宣言して初期化し、ポインタpも宣言します。次にp =&i;を使用して、i変数のアドレスをポインタ変数にコピーしています。次に、&iを使用してiの値とiのアドレスを出力します。最後に,pのアドレス(iのアドレスと同じでなければならない)を表示し,*pを使ってそのアドレスの値を表示します。
最初のうちは、これらの&*記号とポインタの使用は理解しにくいかもしれません。ただ、使用していくにつれて、これらの記号や意味を覚えて、使い分けができるようになります。
Nullポインタの使い方
通常、ポインタは最初は自動的にNULLになりますが、コンパイラによっては値を持つ場合があるので、以下のように先頭でNULLにする必要があります。
pointer *p = NULL;
NULLポインタとは、NULLが割り当てられたポインタのことで、アドレス値を持たないポインタであることを意味します。ポインタに関するほとんどの操作では、ポインタがNULLかどうかを必ずチェックします。チェックしない場合は、どのような状態であってもその行でNULLでないことを確認する必要があります。 例えば、ポインタのアドレスがNULLの状態で何かをコピーしようとすると、アプリケーションでエラーが発生し、アプリの停止、あるいはアプリのリセットなどの危険な動作をする可能性があります。
多くの標準ライブラリ(iostreamを含む)では、NULLポインタは0(ゼロ)の定数として定義されています。
pointer *p = NULL;
if ( !p ) // do not use p or break or start with declaring p address in the memory
if ( p ) // operate on pointer