ポインタのポインタ


多重間接参照

ポインタとは変数のアドレスを格納する特殊な変数でした
ポインタも当然、変数のアドレスをメモリのどこかに保存していることになります
つまり、ポインタ変数も独自のアドレスを持つということが考えられますね

そうです、ポインタのアドレスをさらにポインタに格納することが可能です
このことをポインタのポインタと呼びます

ポインタのポインタから、参照しているポインタがさらに参照している大元の変数へアクセスすることもできます
このような多重間接参照の理解は、ポインタの概念において重要な部分ですのでしっかり押さえてください

ポインタのポインタを宣言するにはアスタリスク * をさらに付加します

型 **変数名;

さらに、ポインタのポインタのポインタを作ることも可能です
いくつポインタを連鎖してもかまいませんが、ポインタのポインタ以降の連鎖はプログラマ自身が
参照先がどこなのかを把握しにくくなるため、通常は使用されません
ポインタの多重間接参照は、連鎖の数だけ * をつけて宣言すればよいです

ここで、多重間接参照のサンプルを見ながら
いまだにポインタの理解があやふやな方はアドレスとポインタと配列の関係をまとめましょう
#include <stdio.h>

int main() {
	char str[] = "kitty on your lap";
	char *str_p;
	char **str_pp;	/*ポインタのポインタ*/

	str_p = str;
	str_pp = &str_p;

	printf("文字型配列変数\n");
	printf("配列先頭アドレス = %x\n" , str);
	printf("保持する文字列 = %s\n\n" , str);

	printf("ポインタの示す値\n");
	printf("ポインタアドレス = %x\n" , &str_p);
	printf("保存する値 = %x\n" , str_p);
	printf("保持するアドレスが持つ内容 = %s\n\n" , str_p);

	printf("ポインタのポインタが示す値\n");
	printf("保持する値 = %x\n" , str_pp);
	printf("保持する値が持つ値 = %x\n" , *str_pp);
	printf("保持する値が持つ値の内容 = %s", *str_pp);

	return 0;
}
例として、次のような結果が出ました
(当然アドレスは状況に応じて異なります)
文字型配列変数
配列先頭アドレス = 64fdf0
保持する文字列 = kitty on your lap

ポインタの示す値
ポインタアドレス = 64fdec
保存する値 = 64fdf0
保持するアドレスが持つ内容 = kitty on your lap

ポインタのポインタが示す値
保持する値 = 64fdec
保持する値が持つ値 = 64fdf0
保持する値が持つ値の内容 = kitty on your lap
その関係をまとめると

文字型変数配列 str[] は
str = &str[0]であり、配列の先頭アドレスを指す
str[0]ではなく、&str[0]であることに注意してください

ポインタ str_p は
str_p = strであり
str_pはstr同様に str[0] のアドレス &str[0] を表している

ポインタのポインタ str_pp は
str_pp = &str_pであり、ポインタstr_pのアドレスを指している
*str_pp は str_p と同じであり、ポインタ変数 str_p の内容を表している
すなわち *str_pp は &str[0] と同じである
このときに、str[] のアドレスではなく内容に直接アクセスしたい場合は **str_pp にすればよい
つまり **str_pp = str[0] を表すことになる

ここまでがポインタの基本的な使い方であり、そのまとめです
ポインタはC/C++言語の理解を深めるのに非常に重要です
この後、C言語講座は関数や構造体に入ります
そのときに、以下にポインタが重要なものか、ご理解いただけるでしょう



前のページへ戻る次のページへ