- 締切済み
ポインタのポインタの利用方法
ポインタはデータのアドレスと解釈しているのですが、ポインタのポインタはどう理解したらよいのでしょうか? よく利用する場面や、使用にあたって注意する点などプロの方お願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- Oh-Orange
- ベストアンサー率63% (854/1345)
★ポインタのポインタの利用方法 ・ポインタ配列のポインタを関数の引数や、戻り値として返したり出来ます。 他にもポインタ配列を動的確保して管理するような場合が考えられます。 多用すると分かりにくくなる可能性があります。気をつけましょう。 例えば: const char **get1( void ) { static const char *msg[] = { "1a", "1b", "1c", NULL, }; return msg; } const char **get2( void ) { static const char *msg[] = { "2a", "2b", "2c", NULL, }; return msg; } const char **get3( void ) { static const char *msg[] = { "3a", "3b", "3c", NULL, }; return msg; } // メイン関数 int main( void ) { const char **msg; const char **pp; int select; scanf( "%d", &select ); switch ( select ){ case 1: msg = get1(); break; case 2: msg = get2(); break; case 3: msg = get3(); break; default: msg = NULL; break; } if ( msg != NULL ){ for ( pp = msg ; *pp != NULL ; pp++ ){ printf( "%s\n", *msg ); } } return 0; } 解説: ・上記の例えのように文字列配列のテーブルを関数(get1、get2、get3)などで 切り替えたいときにはポインタのポインタを活用したりします。 特に文字列配列の個数が大幅に異なる場合には使えそうです。 もちろん文字列の2次配列でテーブルを持つことも可能です。 例えば上記の場合は個数が同じなので static const char *msg[3][4] = { … }; と出来ます。msg[] の個数が大幅に異なる場合は2次元配列にすると少ない場合は 無駄が多くなります。このような場合はポインタのポインタで切り替えるように すれば良さそうです。 ・上の例えはほんの1例です。 他にも良い方法があったり、別の処理でポインタのポインタが活用できるかもしれません。 今は上記ぐらいしか思いつきませんでしたので参考にして下さい。 ・以上。
- Tacosan
- ベストアンサー率23% (3656/15482)
リストや木など, 再帰的な構造を使うようになると便利さがわかるかと. 今どき「自分で作る」のは合理的じゃないけど, 作れるようになってもいいんじゃないかな.
- ddnp009
- ベストアンサー率25% (15/58)
ポインタといえど変数。 >ポインタはデータのアドレスと解釈しているのですが、ポインタのポインタはどう理解したらよいのでしょうか? それならば (データのアドレス)のアドレスと解釈すれば? 使い方としては、わしの場合関数内でメモリをアロケートするとき。 char* char_alloc(char** pp, size_t bytes); という関数があるとして、 char* p; char_alloc(&p, 16); とできる。できたはず。 C++ではポインタのリファレンスを渡せるので 上のような用途では使わなくなりました。
- Pkakedashi
- ベストアンサー率68% (11/16)
ポインタはデータのアドレスと理解されているのなら、ポインタのポインタはポインタのデータのアドレスという説明だと判りやすいですかね。 int a = 1 ; int* pa = &a ; aの変数の領域アドレス値を仮に0x01とします。(こんな単純な値はありえないでしょうけど。) paに格納される値は0x01というのは理解されていると思います。 int** ppa = &pa ; ポインタのポインタは上記のようなことが可能です。 paの領域アドレス値が0x10とすれば、ppaには0x10が入ります。 つまり、 *ppa == pa ; **ppa == a ; の関係が成り立ちます。 ポインタに格納される値は常にアドレスで、そのアドレスの値が実態のアドレスなのか、ポインタのアドレスなのかの違いだけです。 ポインタのポインタをよく利用する場面といったら2(多)次元配列を扱うときですね。もしくは、ポインタの配列を扱う時ですね。それ以外は思いつきません。(;^_^A 使用にあたっての注意点は、ポインタのポインタに限ったことではないですが、ポインタが示す値が配列なのか実態なのかでdeleteの仕方が変わるのでそこが注意点でしょうか。(自分だけかもですが。。。)
- koko_u_
- ベストアンサー率18% (459/2509)
プロじゃねぇけど。 >よく利用する場面や int main(int argc, char** argv) { ... } >使用にあたって注意する点 関数プロトタイプで void foo(char** u); とあっても、 char** u; foo(u); という使い方を想定しているのか char* v; foo(&v); という使い方を想定しているのかにわかにはわからないトコ。 # わしだけ?