C++:ポインタの概要(1)>ポインタについて

CやC++において重要なポインタについてのメモ。

ポインタについて

ポインタを理解するために、変数やメモリの仕組みから順を追って説明します。

変数のアドレス

すべての変数はメモリに記憶される。その記憶されたメモリの位置を16進数で表したものがアドレス。変数のアドレスはアドレス演算子 & でアクセスできる。

サンプルコード
#include <iostream>
using namespace std;

int main(int argc, const char * argv[])
{
    int val = 10;
    
    cout << "変数valの値 : " <<  val << "\n";
    cout << "変数valのアドレス : " << &val << "\n";
    
    return 0;
}
[/code]
</dd>
<dt>結果</dt>
<dd>
[code]
変数valの値 : 10
変数valのアドレス : 0x7fff5fbff86c

※アドレスの値は環境により異なります。

ポインタの宣言とアドレスの格納

上記のアドレスを格納する変数が「ポインタ」。ポインタは型の後に*(アスタリスク)を使用し宣言する。
アスタリスクの位置はポインタ名の直前でも構わないが、後述する関節演算子と区別するため、ここでは int* とする。

サンプルコード
#include <iostream>
using namespace std;

int main(int argc, const char * argv[])
{
    int val = 10;
    int* pVal = &val; // int *pVal = &val;でも構わない
    
    cout << "変数valの値 : " <<  val << "\n";
    cout << "変数valのアドレス : " << &val << "\n";
    cout << "ポインタpAの値 : " << pVal << "\n";
    
    return 0;
}
[/code]
</dd>
<dt>結果</dt>
<dd>
[code]
変数valの値 : 10
変数valのアドレス : 0x7fff5fbff87c
ポインタpValの値 : 0x7fff5fbff87c

ポインタから変数の値にアクセスする

ポインタに変数のアドレスが格納されると、ポインタに 関節演算子 * を使用することで変数の値にアクセスすることができる。

サンプルコード
#include <iostream>
using namespace std;

int main(int argc, const char * argv[])
{
    int val = 10;
    int* pVal = &val; // int *pVal = &val;でも同じ
    
    cout << "変数valの値 : " <<  val << "\n";
    cout << "変数valのアドレス : " << &val << "\n";
    cout << "ポインタpValの値 : " << pVal << "\n";
    cout << "*pValの値 : " << *pVal << "\n";
    
    return 0;
}
[/code]
</dd>
<dt>結果</dt>
<dd>
[code]
変数valの値 : 10
変数valのアドレス : 0x7fff5fbff87c
ポインタpValの値 : 0x7fff5fbff87c
*pValの値 : 10

※int* 型の pVal というポインタを作成し、ポインタ pVal の値には *pVal でアクセスしていると考える。

ポインタから変数の値を変更する

関節演算子 * を使用しポインタに値を代入すれば、参照先の変数の値を変更することができる。

サンプルコード
#include <iostream>
using namespace std;

int main(int argc, const char * argv[])
{
    int val = 10;
    int* pVal = &val;
    
    cout << "変数valの値 : " <<  val << "\n";
    
    *pVal = 100;
    
    cout << "変数valの値 : " <<  val << "\n";
    
    return 0;
}
[/code]
</dd>
<dt>結果</dt>
<dd>
[code]
変数valの値 : 10
変数valの値 : 100

サンプルコードの変数とポインタの関係

val 変数val
&val 変数valのアドレス
pVal ポインタ(変数valのアドレスが格納されている)
*pVal ポインタが指している変数(=変数valの値)

補足説明

  • int型のポインタ val を宣言するときは int* pVal; もしくは int *pVal; となる。このときの *(アスタリスク)はポインタの宣言を意味する記号であって、関節演算子を意味するものではない。

まとめ

C や C++ を基礎から勉強しないまま Objective-C でコーディングしていたため、変数名の前に*が付いているとポインタだと思っていましたが、この考えは正確には間違いでした。

int* pVal; // もしくは int *pVal;
pVal = &val;

最近まで、なぜポインタ宣言のルールが統一されていないのかがずっと疑問でした。
「int型のポインタを宣言する」と考えれば int* pVal; となります。
ポインタの用途を考えれば、格納されているアドレスの16進数は人間にとって意味はなく、「同じアドレスを持つの変数の値を変更させる」使い方がポインタの役割と考えれば、宣言時にはポインタ使用時と同じ表記である int *pVal; を使用する方がスマートに感じます。
コーディングする人の考え方によって、どちらも間違っていないのですが、ポインタにアドレスを代入する際は関節演算子*を使用しないので、これがポインタをわかりにくくさせる原因の一つでした。

たった一文字の記号が左にあるか右にあるかで、その人の性格がでてしまうものなんですね。

siro:chro 無料ゲーム SQN をリリースしました

img_sqn_00

sirochro 初の無料ゲームアプリ SQN をリリースしました。
記事:SQN: iOS 無料ゲームアプリ SQN - Sequential Numbers をリリース
ちょっとした時間に楽しめる完全無料のゲームなっていますので、是非ダウンロードして遊んでみてください。

↓SQN のダウンロードはこちらから

Related Contents

Pickup Contents