【问题标题】:What is double star (eg. NSError **)?什么是双星(例如 NSError **)?
【发布时间】:2010-10-10 21:15:13
【问题描述】:

所以,我看到了这个:

error:(NSError **)error

在苹果文档中。为什么是两星?有什么意义?

【问题讨论】:

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


    【解决方案1】:

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

    *error = myError;
    

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


    回复下面的评论:

    您不能简单地使用NSError *,因为在 C 中,函数参数是按值传递的——也就是说,当传递给函数时,值会复制 .为了说明,考虑这个 C 代码的 sn-p:

    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 * 所指向的值,我们还必须将指针传递给该指针。

    【讨论】:

    • 嗨,我来晚了。想问一下:为什么我们必须传递一个指向 NSError 的指针或者一般情况下才能返回一个对象?例如,如果我们只传递一个指向对象的指针,这是否就足够了:error = myError? (说:error 是指向我的新错误对象 myError 的指针)?希望您能进一步解释使用双指针的理由。非常感谢。
    • @Unheilig:我更新了我的答案,回复了你的问题。
    • 感谢您的报道,但您在上一个示例中是指int f(int **x),对吧?如果是这样,这个 - printf("%d\n", y); - 是否也应该在 void 方法中更改为:printf("%d\n", &y);(将 & 添加到 y)而不是 y
    • 另外,我认为第二个示例中的代码存在类型不兼容的问题,即在方法 void f(int*) 中,当您执行 x = 10 时(需要取消引用 *)。谢谢。
    • @Unheilig:该示例是正确的,尽管可能有点令人困惑,但我证明您需要一个指向基本数据类型的指针才能更改值。对于int,这是int *;遵循相同的逻辑,在 NSError * 是您的基本数据类型的情况下,它是 NSError **
    【解决方案2】:

    在 C 中,一切都是按值传递的。如果你想改变一些东西的值,你传递它的地址(它传递内存地址的值)。如果要更改指针指向的位置,请传递指针的地址。

    Take a look here for a simple explanation.

    【讨论】:

    • “一切都是价值传递”——这句简洁的句子说明了一切。谢谢!
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      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 指针,并且您需要指针的地址来执行此操作。

      【讨论】:

        【解决方案5】:

        如果它像 C 那样,那么 ** 表示指向指针的指针。

        【讨论】:

        • Objective-C 是 C 的严格超集。C 没有什么不同。
        猜你喜欢
        • 2017-04-15
        • 2015-03-26
        • 1970-01-01
        • 2014-03-10
        • 2021-09-21
        相关资源
        最近更新 更多