C++のポインター (pointer)、リファレンス(reference)、デリファレンス(dereference)は、C++初心者には理解するのがかなり困難です。ポインターを極めずしてC++を語るなかれとさえ言われている程で、C++入門者には鬼門となっているのが現状です。ちなみに、pointerは、ポインターともポインタとも言われているようなのですが、個人的にはポインターと言っています。ポインタだと。Ponta(ポンタ)のようなポイントの一種なのかな?と勘違いされそうだからです。
import ROOT
リファレンス (Reference)¶
リファレンスは、CPPReferenceで以下のように定義されています。
Declares a named variable as a reference, that is, an alias to an already->existing object or function.
名前付き変数を、リファレンス(参照)、つまり、既存のオブジェクトや関数のエイリアス(別名)として宣言する。何のことかよく分からないので、先ず、このリファレンスとは何なのかを見て行きます。
%%cpp
string str0 = "Trump";
string mystr = str0;
cout<<str0<<endl;
cout<<mystr<<endl;
mystr = "Donald";
cout<<str0<<endl;
cout<<mystr<<endl;
str0をTrumpと定義したので、当然、mystrもTrumpを返しますが、mystrの値を変えてもstr0の値は変わりませんでした。今度は、参照宣言子であるampersand(アンパサンド)&を付けてmystr1を参照型にしてみます。
%%cpp
string str1 = "Trump";
string& mystr1 = str1; //&を付けてmystr1を参照型にする
cout<<str1<<endl;
cout<<mystr1<<endl;
mystr1 = "Donald";
cout<<str1<<endl;
cout<<mystr1<<endl;
今度はmystr1の値を変えることでstr1の値も変わりました。&を付けてmystr1を参照型にすることで、mystr1がstr1になったということです。つまり、mystr1はstr1の別名ということになります。今度は関数の場合を検証してみます。
%%cpp -d
void str2 (string str)
{
str += "Trump";
}
先ず、上記のようにstr2という関数を作ります。
%%cpp
string mystr = "Donald ";
str2(mystr);
cout <<mystr << endl;
pass by value(値渡し)だと、関数が機能していません。今度はpass by reference(参照渡し)で試してみます。
%%cpp -d
void str3 (string& str)
{
str += "Trump";
}
%%cpp
string mystr = "Donald ";
str3(mystr);
cout <<mystr << endl;
ちなみに、&は、参照宣言子としてではなく、address-of operator(アドレス演算子)としても使われます。&がアドレス演算子と言われる所以は、この演算子が以下の例のようにアドレスを参照するからです。
%%cpp
int i = 2;
cout<<i<<endl;
cout<<&i<<endl; //iの値が格納されているアドレスを表示
ポインター(Pointer)¶
ポインタは一言で言えば、アドレスを格納している場所を指します。pointerという単語自体が指し示す物といったような意味合いになるので、感覚的に分かるかと思います。pointer = addressと言ってもいいかもしれません。
%%cpp
int i = 2;
int myptr = i;
cout<<i<<endl;
cout<<myptr<<endl;
pass by pointer(ポインター渡し)で、iのアドレスをmyptrに渡す場合にポインターが必要になります。これにはポインター宣言子のasterisk(アスタリスク)*を使います。
%%cpp
int i = 2;
int* myptr =& i; //asterisk*を使ってポインタ宣言する
cout<<i<<endl;
cout<<myptr<<endl;
ポインターがアドレスを指し示す物であると言えることが分かるかと思います。autoを使うと以下の例のように自動的にポインタ宣言してくれます。
%%cpp
int a = 2;
auto b = &a;
cout<<a<<endl;
cout<<b<<endl;
デリファレンス(Dereference)¶
デリファレンスはその名の通り、参照型から値型に戻すことを意味しています。これにはdereference operator(間接参照演算子)のasterisk(アスタリスク)*を使います。
%%cpp
int a = 2;
auto b = &a;
cout<<a<<endl;
cout<<b<<endl;
cout<<*b<<endl;
この間接参照演算子を使うと以下のようなこともできます。
%%cpp
int c, d;
int * myptr;
myptr = &c;
*myptr = 50;
myptr = &d;
*myptr = 100;
cout << "c is " <<c << '\n';
cout << "d is " << d << '\n';
コメント