Was ist ein Doppelstern (z. B. NSError **)?

Lesezeit: 5 Minuten

Allyns Benutzeravatar
Allyn

Also, ich habe das gesehen:

error:(NSError **)error

in der Apple-Dokumentation. Warum zwei Sterne? Was ist die Bedeutung?

Benutzeravatar von mipadi
mipadi

Ein “Doppelstern” ist ein Zeiger auf einen Zeiger. So NSError ** ist ein Zeiger auf einen Zeiger auf ein Objekt des Typs NSError. Es erlaubt Ihnen grundsätzlich, ein Fehlerobjekt von der Funktion zurückzugeben. Sie können einen Zeiger auf eine erstellen NSError Objekt in Ihrer Funktion (nennen Sie es *myError), und dann so etwas tun:

*error = myError;

um diesen Fehler an den Aufrufer “zurückzugeben”.


Als Antwort auf einen unten geposteten Kommentar:

Sie können nicht einfach ein verwenden NSError * weil in C Funktionsparameter übergeben werden nach Wert– das heißt, die Werte sind kopiert bei Übergabe an eine Funktion. Betrachten Sie zur Veranschaulichung diesen Ausschnitt aus C-Code:

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

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

Die Neuzuweisung von x in f() beeinflusst den Wert des Arguments außerhalb von nicht f() (in g()zum Beispiel).

Wenn ein Zeiger an eine Funktion übergeben wird, wird sein Wert kopiert, und die Neuzuweisung wirkt sich nicht auf den Wert außerhalb der Funktion aus.

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!
}

Natürlich wissen wir, dass wir den Wert von was ändern können z zeigt ziemlich leicht:

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"
}

Es liegt also nahe, den Wert von was zu verändern NSError * zeigt auf, müssen wir auch einen Zeiger auf den Zeiger übergeben.

  • Hallo, bin etwas spät hier. Möchte fragen: Warum müssen wir einen Zeiger auf einen Zeiger auf NSError oder allgemein übergeben, um ein Objekt zurückzugeben? Wenn wir beispielsweise nur einen Zeiger auf ein Objekt übergeben, würde dies ausreichen: error = myError? (Sprich: Fehler ist ein Zeiger auf mein neues Fehlerobjekt myError)? Ich hoffe, Sie können die Rechtfertigung für die Verwendung eines Doppelzeigers weiter erläutern. Vielen Dank im Voraus.

    – Unheilig

    8. Januar 2014 um 2:52 Uhr

  • @Unheilig: Ich habe meine Antwort mit einer Antwort auf Ihre Frage aktualisiert.

    – Mipadi

    8. Januar 2014 um 9:14 Uhr

  • Danke für den Bericht, aber du meintest es int f(int **x) in deinem letzten beispiel, oder? Und wenn ja, sollte dies – printf("%d\n", y); – auch geändert werden zu: printf("%d\n", &y); (hinzugefügt & zu y) in dem void Methode statt y auch?

    – Unheilig

    8. Januar 2014 um 14:57 Uhr


  • Außerdem denke ich, dass es ein Problem im Code aus dem 2. Beispiel mit inkompatiblen Typen gibt, nämlich in der Methode void f(int*) wenn Sie das tun x = 10 (muss dereferenziert werden *). Vielen Dank.

    – Unheilig

    8. Januar 2014 um 15:57 Uhr

  • @Unheilig: Das Beispiel ist korrekt, wenn auch vielleicht etwas verwirrend, aber ich habe gezeigt, dass Sie einen Zeiger auf Ihren Basisdatentyp benötigen, um den Wert zu ändern. Im Falle einer intdas ist ein int *; nach der gleichen Logik, im Fall von NSError * Da es sich um Ihren Basisdatentyp handelt, ist es NSError **.

    – Mipadi

    9. Januar 2014 um 4:04 Uhr

In C wird alles als Wert übergeben. Wenn Sie den Wert von etwas ändern möchten, übergeben Sie die Adresse davon (die den Wert der Speicheradresse übergibt). Wenn Sie ändern möchten, wohin ein Zeiger zeigt, übergeben Sie die Adresse des Zeigers.

Schauen Sie hier für eine einfache Erklärung.

  • „Alles ist Pass-by-Value“ – dieser nette Satz sagt alles. Vielen Dank!

    – Jim Chang

    7. Oktober 2012 um 13:51 Uhr

In C ist ein Doppelstern ein Zeiger auf einen Zeiger. Dafür gibt es mehrere Gründe. Erstens könnte der Zeiger auf ein Array von Zeigern verweisen. Ein weiterer Grund wäre, einen Zeiger an eine Funktion zu übergeben, wobei die Funktion den Zeiger modifiziert (ähnlich einem “out”-Parameter in anderen Sprachen).

Benutzeravatar von Kumarsunil
Kumarsunil

Der Doppelstern (**)-Notation ist nicht spezifisch für die Initialisierung einer Variablen in einer Klasse. Es ist einfach ein doppelter indirekter Verweis auf ein Objekt.

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

Die Doppelzeigernotation wird verwendet, wenn der Aufrufer beabsichtigt, dass einer seiner eigenen Zeiger durch einen Funktionsaufruf geändert werden muss, sodass die Adresse des Zeigers anstelle der Adresse des Objekts an die Funktion übergeben wird.

Ein Beispiel könnte die Verwendung einer verketteten Liste sein. Der Aufrufer verwaltet einen Zeiger auf den ersten Knoten. Der Aufrufer ruft Funktionen zum Suchen, Hinzufügen und Entfernen auf. Wenn diese Operationen das Hinzufügen oder Löschen des ersten Knotens beinhalten, muss sich der Zeiger des Aufrufers ändern, nicht der .next-Zeiger in einem der Knoten, und Sie benötigen dazu die Adresse des Zeigers.

Wenn es so etwas wie C ist, dann ** bedeutet ein Zeiger auf einen Zeiger.

  • Objective-C ist eine strenge Obermenge von C. Nichts von C unterscheidet sich.

    – Peter Hosey

    2. März 2009 um 22:43 Uhr

  • Objective-C ist eine strenge Obermenge von C. Nichts von C unterscheidet sich.

    – Peter Hosey

    2. März 2009 um 22:43 Uhr

1411290cookie-checkWas ist ein Doppelstern (z. B. NSError **)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy