http://www.eskimo.com/~scs/cclass/int/sx8.htmlから取得:
` int へのポインタ、 char へのポインタ、定義した任意の構造体へのポインタ、そして実際には C の任意の型へのポインタを持つことができるので、ポインタを持つことができることはそれほど驚くべきことではありません他のポインターへ。単純なポインターについて考えることに慣れていて、ポインター自体とそれが指している対象との区別を頭の中で明確にしておくことに慣れている場合は、ポインターへのポインターについても考えることができるはずですが、今はそうしなければなりません。ポインター、それが指すもの、およびポインターが指すポインターが指すものを区別します。(そしてもちろん、ポインターへのポインターへのポインター、またはポインターへのポインターへのポインターへのポインターになる可能性もありますが、これらは急速に難解になりすぎて実用的ではなくなります。) ポインターからポインターへの宣言は次のようになります。 int **ipp; のように。ここで、2 つのアスタリスクは、2 つのレベルのポインターが関係していることを示します。おなじみの、刺激の少ない幼稚園スタイルの例から始めて、 ipp が指すポインターと、それらのポインターが指す int を宣言することにより、 ipp の使用法を示すことができます。
int i = 5, j = 6; k = 7;
int *ip1 = &i, *ip2 = &j;
これで設定できます
ipp = &ip1;
ipp は、i を指す ip1 を指します。*ipp は ip1 であり、**ipp は i または 5 です。
...
実際には、ポインターへのポインターは何に適していますか? 1 つの使用法は、正式な戻り値としてではなく、ポインター引数を介して、関数からポインターを返すことです。これを説明するために、まず一歩戻って、ポインター引数を介して関数から int などの単純な型を返す場合を考えてみましょう。関数を書くと
f(int *ip)
{
*ip = 5;
}
そして、次のように呼び出します。
int i;
f(&i);
f は、呼び出し元から渡されたポインターによって指定された場所に値 5 を書き込むことにより、値 5 を返します。この場合、呼び出し元の変数 i に。関数は、返すものが複数ある場合、この方法で値を返す可能性があります。これは、関数は 1 つの正式な戻り値しか持てない (つまり、return ステートメントを介して 1 つの値しか返せないため) ためです。注意すべき重要なことは、関数が int 型の値を返すために、int 型へのポインタのパラメータを使用していました。ここで、関数がこの方法でポインターを返したいとします。対応するパラメーターは、ポインターへのポインターである必要があります。たとえば、長さ n の文字列にメモリを割り当てようとする小さな関数を次に示します。この関数は、失敗した場合は 0 (false") を返し、成功した場合は 1 (ゼロ以外、または true") を返します。
#include <stdlib.h>
int allocstr(int len, char **retptr)
{
char *p = malloc(len + 1); /* +1 for \0 */
if(p == NULL)
return 0;
*retptr = p;
return 1;
}
呼び出し元は、次のようなことができます
char *string = "Hello, world!";
char *copystr;
if(allocstr(strlen(string), ©str))
strcpy(copystr, string);
else fprintf(stderr, "out of memory\n");
(これはかなり大雑把な例です。allocstr 関数はあまり役に立ちません。呼び出し元が malloc を直接呼び出すのと同じくらい簡単だったでしょう。malloc の周りにラッパー関数を記述する別の、より便利な方法は次のとおりです。これまで使用してきた chkmalloc 関数がその例です。) `