なぜあなたはこれをしますか:
void f(Struct** struct)
{
...
}
構造体のリストを操作したい場合、渡すだけでは不十分Struct*
ですか?このようにしstruct++
て、次の構造体に対処するために行うことができますか、それともここで非常に混乱していますか?:)
構造体のリストを何らかの方法で再配置したい場合にのみ役立つのではないでしょうか。しかし、私が読んでいるだけでは、要点はわかりません。
なぜあなたはこれをしますか:
void f(Struct** struct)
{
...
}
構造体のリストを操作したい場合、渡すだけでは不十分Struct*
ですか?このようにしstruct++
て、次の構造体に対処するために行うことができますか、それともここで非常に混乱していますか?:)
構造体のリストを何らかの方法で再配置したい場合にのみ役立つのではないでしょうか。しかし、私が読んでいるだけでは、要点はわかりません。
データ構造がどのように見えるかによって異なります。p
それがへのポインタのnullで終了する配列であると仮定するとstruct s
、次のようなループを使用してそれを実行できます。
void f(struct s **p)
{
while (*p != NULL) {
/* some stuff */
(*p)++;
}
}
一般に、ポインターへのポインターの使用は、ポインター自体を変更しようとする場合にのみ役立ちます。
この関数に渡された呼び出し元のポインターを変更する場合は、通常、これを行います。
すべてがCの値によって渡されるため、渡すstruct*
とポインターのコピーのみが渡され、呼び出し元のポインターは変更されません。合格の理由struct *
は、このC-FAQで説明されています。
呼び出し元でポインターを変更する予定がない場合は、を渡す必要はありませんstruct **
。
この種のパラメータには多くの用途があります...
すでに述べたように、非常に一般的なのは、呼び出し元が関数を使用してポインターを変更できるようにすることです。ここでの明らかなケースは、データのブロブを取得する場合です...
void getData( void** pData, int* size )
{
*pData = getMyDataPointer();
*size = getMyDataSize();
}
別のオプションは、おそらく余分なレベルの間接参照により、リストが何らかの方法で動作できるようになるということです。たとえば、インデックスを使用して特定の要素を参照することにより、ポインタをぶら下げるリスクなしに、インデックスを割り当てたり再割り当てしたりできます。
さらに別のオプションは、リストが非常に大きく、断片化されたメモリに存在するか、リストが実際にグループ化されたいくつかの小さなリストになるように迅速にアクセスされることです。この種の手法は、巨大な配列を「怠惰に」割り当てるためにも使用できます。たとえば、10億個の要素の配列へのインターフェイスを提供しますが、全体を指すstruct **を使用して読み取り/書き込みを行うときに、オンデマンドで100kのチャンクを割り当てます。物事、そして各構造体*はnullであるか、100k構造体を指しています...
正直なところ、コンテキストは非常に重要です...同様の推論に従う関数パラメーターとしてトリプルポインターの使用法もたくさんあります。(例えば、私が言及した最初のものを2番目のものと組み合わせたり、2番目のものを3番目のものと組み合わせたりするなど)
APIの作成者は、すべての関数の最初の引数が同じであれば、引数リストを覚えやすいと考えていたでしょう。
正解です。関数が渡されたポインタを変更することを意図していない限り、ポインタをポインタに渡す理由はありません。sの配列にアクセスする場合はstruct
、単一レベルの間接参照で間違いなく十分です。