各型と双対してその型の変数のアドレスを格納するポインタ型があり、 例えば int 型については int* 型のポインタ型が存在する (ポインタ変数の宣言はC言語では int *p とし、 C++言語では int* p とする。しかし、 C++で int* p1, p2 とすると p2 は普通の変数となる。) 。 構造体やクラスの型についても同様にポインタ型が存在する。
変数のアドレスは変数に & (ampersand)を冠することで 得られ、それをポインタ変数に代入する。 逆にポインタ変数が格納するアドレスにある変数の値は、その ポインタ変数に * (asterisk)を冠することで得られる。 またこの時、そのポインタ変数が格納するアドレスにある変数に値を 書き込むこともできる。
以下の例で int 型変数 b に a の値 1 が代入され、 さらに a には 2が代入されることを汲み取ってほしい。
int a, b; int* p; a = 1; p = &a; b = *p; *p = 2;
確保したてのメモリ領域のアドレスがポインタ変数 a に 格納される。 *a がこの確保された変数として振舞うのである。int* a; a = new int;
他の型や構造体型の変数も動的確保することができる。指定の長さの 配列変数も動的確保することができる。
ただし2次元以上の多次元配列では1次元目の要素数だけが動的に調整できる。 すべての次元の要素数を動的に調整するには、次のようにする。 まず必要な全要素を1次元配列として確保し、これを細分した各々の 先頭アドレスを動的確保したポインタ配列に格納する。double* x = new double; Particle* p = new Particle; char* str = new char [32]; Complex (*phi)[256] = new Complex [128][256];
構造体型のポインタ変数でpropertyやmethodを表すには次の様にする。Complex *phi, **phi2; phi = new Complex [128*256]; phi2 = new Complex* [128]; for( int i=0 ; i<128 ; i++ ) phi2[i] = &phi[i*256];
動的変数の寿命はプログラム終了までである。意図的に早く動的変数を 解体するには次の様にする。p->q; p->Evolve(0.001);
動的変数は次に紹介するリンクリストでその価値がわかるが、 固定長の巨大な配列を用意する目的にも使われる。delete x; delete p; delete [] str; delete [] phi;
リンクリストは下図の様に、各要素がその要素の型のポインタ変数を含み、 列の次の要素のアドレスを格納する。
リンクリストの概念図
リンクリストの途中に新たな要素を追加するには下図の様に ポインタの鎖を組み変えるだけである。
リンクリストに新たな要素が追加した概念図
#include <stdio.h> class List { int data; // data List* next; // a pointer to next list public: List( List* _next=NULL, int _data=0 ){ // constructor next = _next; data = _data; } void Add( int _data ){ // adds list after this list next = new List( next, _data ); } void Show( void ){ // shows data recursively printf("%d\n", data ); if( next ) next->Show(); } ~List(){ // destructor if( next ) delete next; } }; int main( void ) { List* start = new List; // prepares starting list for( int i=0 ; i<8 ; i++ ){ start->Add(i); // adds new data } start->Show(); // shows all data delete start; // deletes all data return(0); }