Что такое двойная звезда (например, NSError **)? - PullRequest
51 голосов
/ 03 марта 2009

Итак, я увидел это:

error:(NSError **)error

в яблочном доке. Почему две звезды? Какое значение?

Ответы [ 5 ]

68 голосов
/ 03 марта 2009

«Двойная звезда» - это указатель на указатель. Таким образом, 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"
}

Переназначение x в f() не влияет на значение аргумента за пределами 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 *, мы также должны передать указатель на указатель.

43 голосов
/ 03 марта 2009

В C все передается по значению. Если вы хотите изменить значение чего-либо, вы передаете его адрес (который передает значение адреса памяти). Если вы хотите изменить, куда указывает указатель, вы передаете адрес указателя.

Посмотрите здесь простое объяснение .

10 голосов
/ 03 марта 2009

В C двойная звезда - это указатель на указатель. Есть несколько причин для этого. Во-первых, указатель может быть на массив указателей. Другой причиной было бы передать указатель на функцию, где функция изменяет указатель (аналогично параметру out в других языках).

6 голосов
/ 24 апреля 2013

Обозначение двойной звезды (**) не относится к инициализации переменной в классе. Это просто двойная косвенная ссылка на объект.

  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 голосов
/ 03 марта 2009

Если это что-то вроде C, то ** означает указатель на указатель.

...