2.2 ポインタ  1999.03.22(初版)

2.2.1 ポインタは変数である  ポインタはアドレスを値に持つ変数です。値を持つという意味では普通の変数と変わり はありません。メモリアドレスを値に持つ変数とはどういうことでしょう。次のコードを 見てください。 int x = 5, y = 10; y = x; まず最初の宣言文。これは変数の定義をも意味していますから、メモリ内にxとy整数型 の変数が確保されて、それぞれの値が5と10にセットされます。次の代入文は、xの値 5を変数yに代入します。つまりyの値10は上書きされて5になります。  このようなコードを書くとき、わたしたちは同じシンボルx、yを2つの意味に使って います。「変数xの値を変数yに代入する」とは、等号(=)の左側(左辺値)のyはデ ータを記憶する入れ物を意味し、右側(右辺値)のxは入れ物の中のデータを意味します。 するとこの代入文は次のように言い換えることができます。「xが置かれている場所の中 のデータ」を「yが置かれている場所に」代入する。この場所がメモリ内の位置、アドレ スです。つまり変数のアドレスが分かればそこに格納さてれいる値を間接的に読み書きが できる、という機能をポインタは持ちます。

2.2.2 宣言  ポインタはアスタリスク(*)を使って宣言します。 int *ptr; は、変数ptrが(int *)型つまり整数変数のアドレスを値として持つことを表し、「ptrは intへのポインタである」、あるいは「ptrは整数型オブジェクトを指す」と読みます。教 師が黒板を指す指示棒をポインタ(pointer)といい、時計の針のこともポインタといい ます。アドレスを値に持つ変数(ポインタ)はアドレスの実体である変数を指していると いう意味です。これは、常に指している実体がなければ意味を持ちません。従ってポイン タは宣言時か代入文で初期化しておかなければいけません。次のようにアドレス演算子& を使って変数のアドレスをセットします。 int x = 5; int *ptr = &x; // ptrはxを指している は、ポインタptrを変数xのアドレスで初期化しています。 int x = 5, *ptr; ptr = &x; は、ポインタptrにxのアドレスを代入しています。ポインタはどんなデータ型の変数(オ ブジェクト)でも指すことができます。 float *fPtr; // floatへのポインタ char *cPtr; // char へのポインタ int **pPtr; // intへのポインタを指すポインタ(ポインタも変数である)  ポインタが値に持つことができるのはアドレスと0(またはNULL)に限られます。0 (またはNULL)の値を持つポインタは何も指していないことを意味します。C++では0の方 をよく使います。ポインタは変数ですから、指している変数つまりアドレスを変更すること ができます。またポインタ同士の代入ができます。 int x = 5, y = 10; int *ptr1, *ptr2; ptr1 = &x; // ptr1 はxを指す ptr1 = &y; // ptr1 は今度はyを指す ptr2 = ptr1; // ptr2 もyを指す ただし、ある型のポインタを別の型のポインタに代入することはできません。

2.2.3 間接参照  ポインタを使ってそれが指す変数を間接的に読み書きできます。これを間接参照(in- direction)あるいは逆参照(dereferencing)といいます。 int x = 5; int ptr = &x; // ptr はxを指す cout << *ptr << endl; // これは cout << x << endl と同じ ポインタの前の*演算子は間接参照演算子(あるいは逆参照演算子)と呼ばれ、これはポイ ンタが指している変数を意味します。つまり指している変数の別名となります。間接参照と は、*演算子はポインタptrの値すなわちxのアドレスを取得して、そのアドレスにある値す なわちxの中身を参照するのでそう呼ばれます。また、間接参照を使ってxの値を変更でき ます。 *ptr = 10; // X = 10; と同じ 以上をまとめたプログラムを示します。
// lst02_00.cpp
// ポインタの使い方
#include <iostream.h>

int main()
{
    int x = 100;
    cout << "xの  値:  x = " <<  x << endl;
    cout << "xの位置: &x = " << &x << endl << endl;

    int *ptr = &x; // ptrはxを指す

    cout << "ptr = &x; とすると" << endl;
    cout << "  ptrの値: ptr = " <<  ptr << endl;
    cout << " *ptrの値:*ptr = " << *ptr << endl;
    cout << "ptrの位置:&ptr = " << &ptr << endl << endl;

    *ptr = 300; // 間接参照でxの値を変更する

    cout << "*ptr = 300; とすると" << endl;
    cout << " xの  値:  x = " <<  x << endl;
    cout << "*ptrの値:*ptr = " << *ptr << endl << endl;

    cout << "&*ptr = " << &*ptr << endl
         << "*&ptr = " << *&ptr << endl;

    return 0;
}

ソースファイル lst02_00.cpp
[実行結果]
xの  値:  x = 100                    
xの位置: &x = 0x0063FDF0             

ptr = &x; とすると                     
  ptrの値: ptr = 0x0063FDF0           
 *ptrの値:*ptr = 100                  
ptrの位置:&ptr = 0x0063FDF4           

*ptr = 300; とすると                   
 xの  値:  x = 300                   
*ptrの値:*ptr = 300                   

&*ptr = 0x0063FDF0                     
*&ptr = 0x0063FDF0
ポインタptrの値がxのアドレスであること、間接参照*ptrを使ってxの値を読み書きで きることを確認してください。  また最後の結果に注目してください。&*ptrと*&ptr共にxのアドレスを返します。 &*ptrは&xです。*&ptrはptrのアドレスの値ptrを間接参照、すなわちxのアドレスです。  ポインタを使う上で大切なことは、(1)ポインタが指している実体は何かを常に意識 すること(2)その中身(値)はアドレスなのか、データなのかということを理解してい ることです。ptrがポインタのときは「ptr はアドレス」で「*ptrは指しているデータ」 です。また、xが変数なら「&xはアドレス」です。

| 目次 | 前のページ | 次のページ |

Copyright(c) 1999 Yamada,K