什么是双星(例如NSError **)?

时间:2009-03-02 21:37:11

标签: c objective-c cocoa pointers multiple-indirection

所以,我看到了这个:

error:(NSError **)error

在苹果医生中。为什么两颗星?有什么意义?

5 个答案:

答案 0 :(得分:68)

“双星”是指向指针的指针。所以NSError **是指向类型为NSError的对象的指针。它基本上允许您从函数返回错误对象。您可以在函数中创建指向NSError对象的指针(称之为*myError),然后执行以下操作:

*error = myError;

将该错误“返回”给调用者。


回复下面发表的评论:

你不能简单地使用NSError *,因为在C中,函数参数是按值传递 - 也就是说,传递给复制的值一个功能。为了说明,请考虑以下C代码片段:

void f(int x)
{
    x = 4;
}

void g(void)
{
    int y = 10;
    f(y);
    printf("%d\n", y);    // Will output "10"
}

xf()的重新分配不会影响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 *指向的值,我们还必须传递一个指向指针的指针。

答案 1 :(得分:43)

在C中,一切都是按值传递的。如果要更改某些内容的值,则传递它的地址(通过内存地址的值)。如果你想改变指针指向的地方,你就会传递指针的地址。

Take a look here for a simple explanation

答案 2 :(得分:10)

在C中,双星是指向指针的指针。有几个原因可以做到这一点。首先,指针可能指向一个指针数组。另一个原因是将指针传递给函数,其中函数修改指针(类似于其他语言中的“out”参数)。

答案 3 :(得分:6)

双星(**)表示法并非特定于初始化类中的变量。它只是对对象的双重间接引用。

  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

使用双指针表示法,其中调用者想要通过函数调用修改其自己的指针之一,因此指针的地址而不是对象的地址被传递给函数。

一个例子可能是使用链表。调用者维护指向第一个节点的指针。调用者调用函数来搜索,添加和删除。如果这些操作涉及添加或删除第一个节点,则调用者的指针必须更改,而不是任何节点中的.next指针,并且您需要指针的地址来执行此操作。

答案 4 :(得分:4)

如果它类似于C,则 ** 表示指向指针的指针。