ダブルスターとは何ですか(NSError **など)?
-
03-07-2019 - |
質問
だから、私はこれを見ました:
error:(NSError **)error
アップルドキュメント内。なぜ2つ星?意味は何ですか?
解決
「二重星」ポインターへのポインターです。したがって、 NSError **
は、 NSError
型のオブジェクトへのポインターです。基本的に、関数からエラーオブジェクトを返すことができます。関数内で NSError
オブジェクトへのポインターを作成し( * myError
と呼びます)、次のようにします:
*error = myError;
「戻る」に呼び出し元へのエラー。
以下に投稿されたコメントへの返信:
Cでは、関数パラメータは値ごとに渡される—つまり、値はコピーされるため、単に NSError *
を使用することはできません関数に渡されたとき。説明のために、次のCコードのスニペットを考えてください。
void f(int x)
{
x = 4;
}
void g(void)
{
int y = 10;
f(y);
printf("%d\n", y); // Will output "10"
}
f()
での x
の再割り当ては、 f()
( g( )
など)。
同様に、ポインターが関数に渡されると、その値がコピーされ、再割り当ては関数外の値に影響しません。
void f(int *x)
{
x = 10;
}
void g(void)
{
int y = 10;
int *z = &y;
printf("%p\n", z); // Will print the value of z, which is the address of y
f(z);
printf("%p\n", z); // The value of z has not changed!
}
もちろん、 z
が指す値をかなり簡単に変更できることはわかっています。
void f(int *x)
{
*x = 20;
}
void g(void)
{
int y = 10;
int *z = &y;
printf("%d\n", y); // Will print "10"
f(z);
printf("%d\n", y); // Will print "20"
}
したがって、 NSError *
が指す値を変更するには、ポインターをポインターに渡す必要もあります。
他のヒント
Cでは、すべてが値渡しです。何かの値を変更したい場合は、そのアドレスを渡します(メモリアドレスの値を渡します)。ポインターが指す場所を変更する場合は、ポインターのアドレスを渡します。
Cでは、二重星はポインターへのポインターです。これにはいくつかの理由があります。 1つ目は、ポインターがポインターの配列を指す場合があることです。もう1つの理由は、関数にポインターを渡すことです。関数はポインターを変更します(他の言語の「out」パラメーターに似ています)。
二重星(**)表記は、クラス内の変数の初期化に固有のものではありません。これは単にオブジェクトへの二重間接参照です。
float myFloat; // an object
float *myFloatPtr; // a pointer to an object
float **myFloatPtrPtr; // a pointer to a pointer to an object
myFloat = 123.456; // initialize an object
myFloatPtr = &myFloat; // initialize a pointer to an object
myFloatPtrPtr = myFloatPtr; // initialize a pointer to a pointer to an object
myFloat; // refer to an object
*myFloatPtr; // refer to an object through a pointer
**myFloatPtrPtr; // refer to an object through a pointer to a pointer
*myFloatPtrPtr; // refer to the value of the pointer to the object
ダブルポインター表記は、呼び出し元が関数呼び出しによって自身のポインターの1つを変更する必要がある場合に使用されるため、オブジェクトのアドレスではなく、ポインターのアドレスが関数に渡されます。
例としては、リンクリストの使用があります。呼び出し元は、最初のノードへのポインターを維持します。呼び出し元は、検索、追加、および削除する関数を呼び出します。これらの操作に最初のノードの追加または削除が含まれる場合、呼び出し元のポインターは変更する必要があります。ノードの.nextポインターではなく、変更するにはポインターのアドレスが必要です。
Cなどの場合、 **
はポインターへのポインターを意味します。