MENU
コンテンツ再構築中

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

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

INDEX

ポインタについて

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

変数のアドレス

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

サンプルコード
[code]
#include
using namespace std;

int main(int argc, const char * argv[])
{
int val = 10;

cout << "変数valの値 : " << val << "\n"; cout << "変数valのアドレス : " << &val << "\n"; return 0; } [/code]

結果
[code]
変数valの値 : 10
変数valのアドレス : 0x7fff5fbff86c
[/code]

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

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

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

サンプルコード
[code]
#include
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]

結果
[code]
変数valの値 : 10
変数valのアドレス : 0x7fff5fbff87c
ポインタpValの値 : 0x7fff5fbff87c
[/code]

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

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

サンプルコード
[code]
#include
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]

結果
[code]
変数valの値 : 10
変数valのアドレス : 0x7fff5fbff87c
ポインタpValの値 : 0x7fff5fbff87c
*pValの値 : 10
[/code]

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

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

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

サンプルコード
[code]
#include
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]

結果
[code]
変数valの値 : 10
変数valの値 : 100
[/code]

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

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

補足説明

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

まとめ

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

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

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

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

Please share it!
  • URLをコピーしました!
  • URLをコピーしました!
INDEX