苦手な人が多いポインタ・アドレスに関する記事です。
配列とポインタの関係性についても解説しています。
アドレス
変数・配列等のデータは、コンピューターのメモリ上に保存されています。
メモリには、アドレスという連続した番号が付いているので、どの場所に何が記録されているのかを管理することが出来るようになっています。
アドレスの表し方
変数名の先頭に【&】を付けることで、アドレスを表すことが出来ます。
コーディング例①
#include <stdio.h> // printf()を使用するために必要
int main()
{
int x;
int y;
printf("xのアドレス:%x\n", &x);
printf("yのアドレス:%x\n", &y);
return 0;
}
出力
xのアドレス:a06ff7c4
yのアドレス:a06ff7e4
アドレスは、個人のPC環境によって違う値が表示されます。
ポインタ
変数や関数が格納されているアドレスを値とする変数をポインタと言います。
ポインタにも、変数や関数と同様にデータ型があります。
ポインタの宣言
int* p;
int *p;
ポインタの宣言は、上記のように記述します。
どちらの記述でも同じ意味なので、好きな方を使いましょう。
ポインタに代入
ポインタにアドレスを代入する際は、以下のように記述します。
int A; // 変数
int *pA; // ポインタ
pA = &A; // ポインタにアドレスを代入
ポインタが指すデータの参照
宣言後のポインタの頭に【*】を付けると、そのポインタが指す先のデータを参照します。
宣言する際にも【*】を使用するので、初心者が混乱する部分ですね。
まぁ、こんな分かりにくい仕様にしたら、そりゃ混乱しますよね。
コーディング例①
#include <stdio.h> // printf()を使用するために必要
int main()
{
int A = 10;
int* pA = &A;
printf("%d\n", pA);
printf("%d\n", *pA);
return 0;
}
出力
1708127748
10
アドレスは、個人のPC環境によって違う値が表示されます。
NULLポインタ
プログラムの中で、どこも指し示していないことを示したい場合は、NULLポインタを利用します。
記述方法は、以下の通りです。
コーディング例①
#include <stdio.h> // printf()を使用するために必要
int main()
{
int* pA = NULL;
printf("%d\n", pA);
if (!pA) { // pA == NULLの場合
printf("pAはNULLです。\n");
}
else if (pA) { // pA != NULLの場合
printf("pAはNULLではありません。\n");
}
return 0;
}
出力
0
pAはNULLです。
NULLポインタは、0を返します。
配列との関係
配列の[]を省略したものは、配列の最初の要素のアドレスを示します。
そのため、&を利用する必要はありません。
また、整数の加算・減算を利用することで、配列の要素番号を示すことも可能です。
コーディング例①
#include <stdio.h> // printf()を使用するために必要
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *pA = a; // a[0]のアドレス
int *pB = &a[0];
printf("%x\n", pA);
printf("%x\n", pB);
pA = a + 1; // a[1]のアドレス
pB = &a[1];
printf("%x\n", pA);
printf("%x\n", pB);
return 0;
}
出力
f8ffb08
f8ffb08
f8ffb0c
f8ffb0c
アドレスは、個人のPC環境によって違う値が表示されます。
コーディング例②
ポインタを利用した、配列の値の参照も可能です。
#include <stdio.h> // printf()を使用するために必要
int main()
{
int a[5] = { 10, 20, 30, 40, 50 };
int *pA = a; // a[0]のアドレス
printf("%d\n", *pA); // a[0]の値
printf("%d\n", *(pA + 3)); // a[3]の値
printf("%d\n", *pA + 3); // a[0]の値に+3
return 0;
}
出力
10
40
13
()の付け方によって、意味合いが変わってくるので注意が必要です。
strchr()
指定した文字が文字列内に存在するか、検索出来る関数です。
存在する場合は、指定した文字が最初に現れた位置のポインタを返します。
存在しない場合は、NULLを返します。
読み方は、『ストリングチャー』です。
コーディング例①
#include <stdio.h> // printf()を使用するために必要
#include <string.h> // strchr()を使用するために必要
int main()
{
char A[] = "Nonbirimaru";
char* pA = strchr(A, 'b');
char* pB = strchr(A, 'c');
printf("%x\n", pA);
printf("%x\n", &A[3]);
printf("%x\n", pB);
return 0;
}
出力
96f3fcab
96f3fcab
0
this
オブジェクトで使用される特殊なポインタとして、【this】があります。
【this】ポインタは、記述したオブジェクトそのものを指すポインタです。
コーディング例①
#include <iostream>
class MyClass {
public:
int value;
void SetValue(int value) {
this->value = value; // thisポインタを使用してメンバ変数にアクセス
}
void PrintValue() {
std::cout << "Value:" << this->value << std::endl; // thisポインタを使用してメンバ変数にアクセス
}
};
int main() {
MyClass obj;
obj.SetValue(10);
obj.PrintValue();
return 0;
}
出力
Value:10