web-dev-qa-db-ja.com

ダブルスター(NSError **など)とは何ですか?

だから、私はこれを見ました:

error:(NSError **)error

Apple doc's。なぜ2つの星なのか?意義は何ですか?

51
Allyn

「二重星」は、ポインターへのポインターです。したがって、_NSError **_はNSError型のオブジェクトへのポインターへのポインターです。基本的に、関数からエラーオブジェクトを返すことができます。関数でNSErrorオブジェクトへのポインターを作成し(_*myError_と呼びます)、次のように実行できます。

_*error = myError;
_

そのエラーを呼び出し元に「返す」ために。


以下に投稿されたコメントへの返信:

Cでは関数パラメータが渡されるため、単純に_NSError *_を使用することはできませんby value —つまり、関数に渡されると値がコピーになります。説明のために、この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 *_が指すものの値を変更するには、ポインターにポインターを渡す必要もあります。

68
mipadi

Cでは、すべてが値渡しされます。何かの値を変更したい場合は、そのアドレスを渡します(メモリアドレスの値を渡します)。ポインターが指す場所を変更する場合は、ポインターのアドレスを渡します。

簡単な説明はこちらをご覧ください

43
TofuBeer

Cでは、二重星はポインターへのポインターです。これにはいくつかの理由があります。 1つ目は、ポインターがポインターの配列を指す場合があることです。もう1つの理由は、関数にポインターを渡すことです。この場合、関数はポインターを変更します(他の言語の「出力」パラメーターに似ています)。

10
geofftnz

ダブルスター(**)表記は、クラス内の変数の初期化に固有のものではありません。これは、単にオブジェクトへの二重間接参照です。

  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ポインターではなく、変更するにはポインターのアドレスが必要です。

6
Kumarsunil

Cのようなものであれば**は、ポインターへのポインターを意味します。

4
Andrew Hare