Variablen, Zeiger, Objekte und Speicheradressen:Warum bekomme ich dieses seltsame Ergebnis?

StackOverflow https://stackoverflow.com/questions/802717

  •  03-07-2019
  •  | 
  •  

Frage

Nachdem ich dachte, dass ich verstanden habe, wie Sie funktionieren, habe ich versucht, dieses:

NSString *str1 = [NSString stringWithCString:"one"];
NSString *str2 = [NSString stringWithCString:"two"];
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3cc, one
NSLog(@"str2: %x, %@", &str2, str2); //bfffd3c8, two

str1 = str2;
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3cc, two

Der Wert eines Zeigers (wie str1, str2) ist eine Speicher-Adresse.Wenn Sie gehen Sie zu dieser Adresse erreichen Sie die "Bereich" im Speicher, in dem das Objekt gespeichert ist.

Aber:Wenn ich aufgebe, str2, str1, str1 sollte als Wert die Speicheradresse des gleichen Objekts, auf die verwiesen wird, durch str2, richtig?Das merkwürdige hier ist, dass der Wert der Zeiger bleibt der gleiche (bfffd3cc memory Adresse), wo die Sache hinter-Adresse ändert.das ist eigentlich völlig unlogisch für mich ;) da ich denke das die Speicheradresse des Objekts (oder der Homepage des Objekts im Speicher Ziegel, was auch immer).Also habe ich gerechnet:

NSString *str1 = [NSString stringWithCString:"one"];
NSString *str2 = [NSString stringWithCString:"two"];
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3cc, one
NSLog(@"str2: %x, %@", &str2, str2); //bfffd3c8, two

str1 = str2;
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3c8, two

Ansonsten, ich wusste immer noch nicht den Punkt.Das Verhältnis zwischen dem Wert der "Zeiger variable" und der "wahre Wert", sagen wir, dass das Objekt, das sitzt dahinter, dass der Speicher Adresse.

War es hilfreich?

Lösung

Denken Sie daran, dass eine Zeigervariable ist eine variable selbst, hat also eine Adresse.So &str1 Ergebnisse in der Adresse der Zeigervariable, und str1 ist ein Ausdruck, dass die Ergebnisse, in welcher die Zeiger-variable holding - die Adresse des Objekts, es verweist.

Davon ausgehen, dass:

  • das Objekt, halten Sie die NSString "ein" wird bei der Adresse 0 x 00000100
  • das Objekt, halten Sie die NSString "zwei" liegt bei Adresse 0x00000200

Dann Zeigern könnte wie folgt Aussehen:

Bei der Initialisierung:

str1
0xbfffd3c8  +---------------+
            |               |
            |  0x00000100   |
            |    ("one")    |
            +---------------+

str2
0xbfffd3cc  +---------------+
            |               |
            |  0x00000200   |
            |    ("two")    |
            +---------------+

=======================================

Nach der str1 = str2; Zuordnung:

str1
0xbfffd3c8  +---------------+
            |               |
            |  0x00000200   |
            |    ("two")    |
            +---------------+

str2
0xbfffd3cc  +---------------+
            |               |
            |  0x00000200   |
            |    ("two")    |
            +---------------+

Andere Tipps

Sie drucken die Referenz Ihres Zeiger, der die Adresse des Zeigers ist, nicht der Wert des Zeigers.

&str1 nimmt die Adresse des Zeigers.

Ok, daran erinnern, wie wir gesagt, dass alles, was „lebt“ zu einem bestimmten Adresse im Speicher? Und dass ein Zeiger ist nur die Zahl, eine Zahl, die die Adresse?

Nun Zeiger sind die Dinge zu, und als solche sie haben Adressen.

Wenn Sie &str1 ausdrucken, Sie drucken den Speicher durch den Zeiger besetzt werden. Wenn Sie str1 ausdrucken, bedrucken möchten Sie den Wert des Zeigers aus, die die Speicheradresse ist es auf .

Wenn Sie ausdrucken *str1 Sie den Zeiger sind dereferencing und Drucken von , die druckt der Wert gezeigt wird.


Im übrigen gute Arbeit: Ich habe Ihre letzten beiden Fragen zu lesen, und Sie bekommen es, und Ihren Code Kredit schriftlich zu beweisen oder zu widerlegen, dass Ihr Verständnis korrekt ist. Das ist genau das, was Sie tun sollen, und du bist auf dem richtigen Weg.

Ein Teil des Problems ist, den Sie haben, dass Strings sind lustige Dinge, dass ein String wirklich ein Array von (const) Zeichen und Funktionen wie NSLog geschrieben werden, um die übliche Sache mit einem Zeiger zu tun, verkohlen, das ist die Zeichenfolge zu drucken. ein Zeiger auf String gegeben, es ist wirklich Looping: den Zeiger zu dereferenzieren, die Spitz zum Charakter Druck, ein auf den Zeiger des Hinzufügen, um das nächste Zeichen gedruckt wird, bis das gewünschte Zeichen an welcher Stelle ein Sonderzeichen mit dem Wert 0, ist spitz es hat das Ende der Schnur und stoppt den Ausdruck Zeichen gefunden.

Sie können das alles finden leichter zu verstehen, wenn Sie so etwas wie ints und Zeiger auf Ints verwendet werden.

Pointers sind in der Tat ganze Zahlen mit einem eigenen Arithmetik (IIRC, ist garantiert, dass sizeof (int) == sizeof (void *))

Wenn Sie verweisen Zeiger, werden Sie die Adresse, wo sie gespeichert wird; wenn die Variable automatisch, dann werden Sie die Adresse in dem Stapel, wo der Zeiger gespeichert ist. Das ist, warum Sie diese Ergebnisse bekommen

Zuordnung wie Zuordnung zwischen ganzen Zahlen verhalten; in der Tat:

#include <stdio.h>

int main() {
        char *str1 = "Ciao";
        char *str2 = "Mondo";
        printf("%x\n", str1);
        printf("%x\n", str2);
        str1 = str2;
        printf("%x\n", str1);
}

druckt:

:~$ ./a.out
80484f8
80484fd
80484fd

str1 ist ein Zeiger auf einen NSString Wert.

&str1 bedeutet: die Adresse der str1 Variable. Dies ist ein Doppel indirection.

Ich denke, dass Sie die Adresse des Wertes wollen, das heißt, str1 selbst, nicht &str1.

Nehmen wir an, dass der NSString Objektwert @"one" enthält, an der Adresse 0x12345678 befindet und @"two" ist bei 0x1234ABC0.

Zunächst wird der Wert von str1 ist 0x12345678 und der Wert von str2 ist 0x1234ABC0. Diese beiden Werte werden im Speicher jeweils bei Adressen 0xbfffd3cc und 0xbfffd3c8 gespeichert. Dies sind die Adressen von str1 und str2 Variablen, das heißt, die Werte von &str1 und &str2.

Wenn Sie str1 = str2 schreiben, der Zuordnung ändert Wert von str1 die gleichen wie Wert von str2 zu sein, das heißt, den Wert von str1 ist dann 0x1234ABC0. Dies ist die Adresse des @"two" Objekts. Aber Adresse str1 Variable (0xbfffd3cc) nicht verändert wird.

Objekte in Objective-C werden auf mit Zeigern gearbeitet. Also, um Ihr NSString Objekt zu behandeln, haben Sie einen Zeiger auf sie zu nehmen. Welches ist das, was str1 ist, ein Zeiger auf ein NSString-Objekt.

Wenn Sie eine Nachricht an Ihre NSString senden möchten, können Sie die Syntax [str1 doSomething] verwenden.

Wenn Sie die Zeichenfolge drucken möchten, müssen Sie den Zeiger auf NSLog passieren und NSLog sagen, dass der Zeiger auf ein NSString, die durch die Formatierungsregel „% @“ durchgeführt wird.

Nun, wenn Sie nur an die Adresse darauf drucken möchten durch str1, haben Sie immer noch die Zeiger str1 passieren, aber Sie müssen NSLog sagen, dass Sie es als hexadezimalen Wert unter Verwendung der Formatierungsregel „% x“ drucken.

So etwas sollte drucken, was Sie wollen:

// First print str1 as an hexadecimal value
// Then print the content of the NSString object str1 points to
NSLog(@"str1: %x, %@", str1, str1);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top