2009-03-02 11 views

Antwort

64

Ein "Doppelstern" ist ein Zeiger auf einen Zeiger. So ist NSError ** ein Zeiger auf einen Zeiger auf ein Objekt vom Typ NSError. Es ermöglicht grundsätzlich, ein Fehlerobjekt von der Funktion zurückzugeben. Sie können einen Zeiger auf ein NSError Objekt in Ihrer Funktion erstellen (nennen wir es *myError), und dann so etwas tun:

*error = myError; 

auf „Rückkehr“, dass Fehler an den Aufrufer.


In Antwort auf einen Kommentar unten geschrieben:

Sie können nicht einfach eine NSError * verwenden, da in C, Funktionsparameter von Wert geben werden -Das ist, sind die Werte kopiert, wenn an eine Funktion übergeben. Zur Veranschaulichung betrachten diese Schnipsel von C-Code:

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

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

Die Neuzuordnung von x in f() hat keinen Einfluss auf den Wert des Argument außerhalb von f() (in g(), zum Beispiel).

Wenn ein Zeiger in eine Funktion übergeben wird, wird dessen Wert ebenfalls 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 dessen, was z Punkte ziemlich leicht ändern können:

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

So liegt es, dass die Vernunft, den Wert dessen, was ein NSError * Punkte zu ändern Wir müssen auch einen Zeiger auf den Zeiger übergeben.

+0

Hallo, bin etwas spät hier. Möchte fragen: Warum müssen wir einen Zeiger auf einen Zeiger auf NSError oder allgemein auf ein Objekt zurückgeben? Wenn zum Beispiel von oben nur ein Zeiger auf ein Objekt übergeben würde, würde dies ausreichen: error = myError? (Spricht: Fehler ist ein Zeiger auf mein neues Fehlerobjekt myError)? Ich hoffe, Sie können die Rechtfertigung der Verwendung eines Doppelzeigers weiter erläutern. Vielen Dank im Voraus. – Unheilig

+0

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

+0

Danke für das Schreiben, aber du meintest "int f (int ** x)" in deinem letzten Beispiel, richtig? Und wenn ja, sollte dies - 'printf ("% d \ n ", y);' - auch geändert werden in: 'printf ("% d \ n ", &y);' (hinzugefügt '&' nach 'y') in die 'void'-Methode anstelle von' y' auch? – Unheilig

4

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

+9

Objective-C ist eine strenge Obermenge von C. Nichts von C ist anders. –

10

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 anderer Grund wäre, einen Zeiger auf eine Funktion zu übergeben, wo die Funktion den Zeiger ändert (ähnlich einem "out" -Parameter in anderen Sprachen).

41

In C ist alles nach Wert. Wenn Sie den Wert von etwas ändern möchten, übergeben Sie die Adresse (die den Wert der Speicheradresse übergibt). Wenn Sie ändern möchten, wo ein Zeiger zeigt, übergeben Sie die Adressen des Zeigers.

Take a look here for a simple explanation.

+0

Nizza Erklärung .. – Tirth

+1

„alles Pass. nach Wert "- dieser saubere Satz sagt alles. Danke! –

+0

Große und klare Antwort. –

6

Die Doppelstern (**) Notation ist nicht spezifisch für die Initialisierung einer Variablen in einer Klasse. Es ist einfach eine doppelte indirekte Referenz 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 

Doppelzeigernotation verwendet wird, bei dem der Anrufer beabsichtigt, dass eine seiner eigenen Zeiger müssen durch einen Funktionsaufruf geändert werden, so dass die Adresse des Zeigers, anstelle der Adresse des Objekts wird auf den übergebenen Funktion.

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 bei diesen Vorgängen der erste Knoten hinzugefügt oder gelöscht wird, muss der Zeiger des Aufrufers geändert werden, nicht der Zeiger .next in einem der Knoten, und Sie benötigen dazu die Adresse des Zeigers.

+1

gibt es einige Probleme in Ihrem Code –

+2

"* einfach * eine doppelte indirekte Referenz". lol – Eric

Verwandte Themen