ポインタのポインタ(ダブルポインタ)とはポインタを示すポインタです。
詳しくは以下で図を使って解説します。
ポインタのポインタは配列のポインタ渡しの際などに使えます。
ポインタのポインタとは?
ポインタには変数のアドレスが格納されますよね。
-
参考【C言語】アドレスとポインタをわかりやすく解説!使うメリットは?
ポインタって何?使うメリットは?わかりやすく教えてほしい。 アドレスって何?ポインタに関係あるの?メモリのアドレスって言われてもピンとこない… こんなお悩みにお答えします。 アドレスとはメインメモリ上 ...
続きを見る
ポインタのポインタ(ダブルポインタ)にはポインタのアドレスが格納されます。
例えばある変数aはメモリアドレス100の位置に値10が格納されているとします。(アドレスは適当です。)
aのポインタをpとするとpにはaのアドレス100が格納されます。
ポインタpのポインタをppとするとppにはpのアドレス200が格納されます。
このppはpというポインタを示すポインタ、つまりポインタのポインタと呼ばれます。
ポインタのポインタの使い方
ポインタのポインタの使い方
定義:
データ型 **ダブルポインタ名;
定義と初期化:
データ型 **ダブルポインタ名=&ポインタ名;
代入:
ダブルポインタ名=&ポインタ名;
例1:
#include <stdio.h> void main() { int num=10; int *p=# int **pp=&p; printf("*p=%d\n",*p); //=num printf("p=%u\n",p); //=&num printf("&p=%u\n",&p); printf("**pp=%d\n",**pp); //=*p=num printf("*pp=%u\n",*pp); //=p printf("pp=%u\n",pp); //=&p printf("&pp=%u\n",&pp); }
実行結果
*p=10
p=1501559628
&p=1501559616
**pp=10
*pp=1501559628
pp=1501559616
&pp=1501559608
アドレス値は非常に大きな値を取るため、正しい値を出力するために符号なし整数のフォーマット指定子%uを使っています。
ポインタのポインタを使うメリット・使いどき
配列をポインタ渡しするとき
ポインタのポインタは配列を引数としてポインタ渡しするときに使えます。
配列をポインタ渡しをすると仮引数(関数作成時に定義する引数)の値の変更を関数外に引き継げます。
以下の例ではGetHello関数の仮引数ptrに「Hello」が代入され、その値が実引数(関数呼び出し時に渡す引数)arrayに引き継がれます。
例2:
#include <stdio.h> void GetHello(char **ptr) { *ptr="Hello"; //配列の先頭アドレスarrayを文字列 printf("*ptr=%s\n",*ptr); //=array printf("**ptr=%c\n",**ptr); //=*array printf("*((*ptr)+1)=%c\n",*((*ptr)+1)); =//*(array+1) } void main() { char *array; GetHello(&array); printf("array=%s\n",array); printf("*array=%c\n",*array); printf("*(array+1)=%c\n",*(array+1)); }
実行結果
*ptr=Hello
**ptr=H
**(ptr+1)=e
array=Hello
*array=H
*(array+1)=e
GetHello関数内の1行目で*ptr(=array)に文字列Helloの先頭アドレス(Hが格納されているメモリのアドレス)が格納されます。
そのため**ptr(=*array)を出力するとHが得られます。
次の文字eが格納されているアドレスはarray+1のように表されるので、*(array+1)を出力するとeが得られます。
同じように*(array+2)からはl、*(array+4)からはoが得られます。
ポインタのポインタであるptrはポインタarrayを指しているので、**ptr=*array、*ptr=arrayが成り立ちます。
それぞれに格納された値とメモリアドレスの関係は以下のようになります。(アドレスは適当です。)
関数内でポインタのアドレスを変更するとき
実引数として渡したポインタのアドレスを関数内で変更したい場合にはポインタのポインタが使えます。
例3:
#include <stdio.h> int num=10; void GetNum(int **ptr) { *ptr=# } void main() { int *i=0; GetNum(&i); printf("*i=%d\n",*i); }
実行結果
*i=10
C言語で行き詰まったら…
-
C言語・C++がわからない時に質問できるサイト・サービス5選
C言語を独学で勉強しているけど内容がイマイチわからない。もはや何がわからないのかもわからない。 C++のエラーが解決できない。ググってもわからない。わかる人に解説してほしい。 こんなお悩みにお答えしま ...
続きを見る