こんにちは!こんばんは!
ちゃとらです(・ω・)/
ポインタのポインタ(ダブルポインタ)って聞いただけで嫌な感じになりませんか?
でも、ダブルポインタはポインタ変数とほぼ同じで、ただ参照する回数が1回増えただけです。
仕組みが分かればすんなり理解できるかと思います。
ダブルポインタについて分かりやすく解説していきます!
ダブルポインタとは
説明
ダブルポインタとは、ポインタ変数のアドレスを格納することができるポインタ変数のことです。
役割としてはポインタ変数と同じで、参照して参照した先の値を示すことが可能です。
う~~ん、よく分かんねぇ…
そっかぁ、よく分かんねぇかぁ~…
言葉だけだとイメージしにくいと思うので、サンプルコードを交えて具体的な説明をしていきます。
サンプルコード
ダブルポインタを使ってポインタ変数のアドレスを代入し、参照先の参照先の値を表示するプログラムを作ってみました。
#include <stdio.h>
int main(void)
{
int i = 100;
int *p;
int **pp;
p = &i; /* ポインタ変数pにiのアドレスを代入*/
pp = &p; /* ダブルポインタ変数ppにポインタ変数pのアドレスを代入*/
printf("iのアドレス:%p\n", &i);
printf("iの値:%d\n\n", i);
printf("*pのアドレス:%p\n", &p);
printf("*pが持っている値:%p\n", p);
printf("*pの参照先の値:%d\n\n", *p);
printf("**pのアドレス:%p\n", &pp);
printf("**pが持っている値:%p\n", pp);
printf("**pの参照先の値:%p\n", *pp);
printf("**pの参照先の参照先の値:%d\n", **pp);
return 0;
}
iのアドレス:00CFFB8C
iの値:100
*pのアドレス:00CFFB80
*pが持っている値:00CFFB8C
*pの参照先の値:100
**pのアドレス:00CFFB74
**pが持っている値:00CFFB80
**pの参照先の値:00CFFB8C
**pの参照先の参照先の値:100
まずはポインタの役割として、iと*pの関係について説明します。
9行目で*pにiのアドレスを渡しているので、*pの参照先の値はiの値(100)を示します。
また当然ですが、*pが持っている値とiのアドレスが一致していることも分かります。
イメージは以下の図のようになります。

続いてダブルポインタついて説明します。
ダブルポインタの宣言方法は簡単で、ポインタ変数とほぼ同じです。
// ダブルポインタの宣言方法
データ型 **変数名
iと*pと**ppの関係については…
10行目で**ppに*pのアドレスを渡しているので、**ppの参照先の値は*pが持っている値を示し、**ppの参照先の参照先の値はiの値(100)を示します。
またここでも、**ppが持っている値と*pのアドレスが一致しています。
イメージは以下のようになります。

ダブルポインタの使い道
んー、ダブルポインタの使い道ってなんかあるの?
代表的なものだと、関数の引数ですね。
ダブルポインタは用途に応じて様々な使い方ができます。
今回はダブルポインタの用途として、関数の引数に使われるパターンを紹介します。
関数の引数
以下のプログラムでは、関数の引数にポインタ変数のアドレスを渡して実行することで、ポインタ変数の参照先が変わります。
#include <stdio.h>
static int num1 = 100;
static int num2 = 200;
// ポインタ変数の参照先をnum1に設定する
void paddressChange1(int **pp)
{
*pp = &num1;
}
// ポインタ変数の参照先をnum2に設定する
void paddressChange2(int **pp)
{
*pp = &num2;
}
int main(void)
{
int *p;
paddressChange1(&p);
printf("*p = %d\n", *p);
paddressChange2(&p);
printf("*p = %d\n", *p);
return 0;
}
*p = 100
*p = 200
22行目では、関数が実行されることで*pの参照先がnum1になっています。
また25行目では、関数が実行されることで*pの参照先がnum2になっています。
多重ポインタ
ダブルポインタができるのならば、その先のトリプルポインタやクアドアラプルポインタなどの多重ポインタも使用可能です。
以下のプログラムは、一~五重ポインタを使って変数iの値を表示します。
#include <stdio.h>
int main(void)
{
int i = 100;
int *p;
int **pp;
int ***ppp;
int ****pppp;
int *****ppppp;
p = &i;
pp = &p;
ppp = &pp;
pppp = &ppp;
ppppp = &pppp;
printf("i = %d\n", i);
printf("*p = %d\n", *p);
printf("**pp = %d\n", **pp);
printf("***ppp = %d\n", ***ppp);
printf("****pppp = %d\n", ****pppp);
printf("*****ppppp = %d\n", *****ppppp);
return 0;
}
i = 100
*p = 100
**pp = 100
***ppp = 100
****pppp = 100
*****ppppp = 100
16行目で、五重ポインタ*****pppppにポインタのポインタの…ポインタのアドレスを代入してます。
そして23行目で、参照先の参照先の…参照先の値を表示させています。
このように、多重ポインタで一番最後に行き着く参照先の値を表示させることができます。
でも、多重ポインタでこんな使い方しないでしょ?
うん、まぁ、そうだね…
とりあえず、「2以上の多重ポインタもあるよっ!」ってことを知ってほしかっただけです…
まとめ
ダブルポインタは知識として覚えておくといいと思います!
今回はここまでです。
ちゃとら(・ω・)/