Die anderen Antworten sind richtig, aber keine von ihnen betont die Idee, dass es möglich ist, dass alle drei den gleichen Wert enthalten , und dass sie daher in gewisser Weise unvollständig sind.
Der Grund, warum dies aus den anderen Antworten nicht verstanden werden kann, ist, dass alle Abbildungen, obwohl sie unter den meisten Umständen hilfreich und definitiv vernünftig sind, nicht die Situation abdecken, in der der Zeiger x
auf sich selbst zeigt.
Dies ist ziemlich einfach zu konstruieren, aber eindeutig etwas schwieriger zu verstehen. Im folgenden Programm werden wir sehen, wie wir erzwingen können, dass alle drei Werte identisch sind.
HINWEIS: Das Verhalten in diesem Programm ist nicht definiert, aber ich bin Entsendung es hier rein als eine interessante Demonstration von etwas , dass Zeiger können tun, aber soll nicht .
#include <stdio.h>
int main () {
int *(*x)[5];
x = (int *(*)[5]) &x;
printf("%p\n", x[0]);
printf("%p\n", x[0][0]);
printf("%p\n", x[0][0][0]);
}
Dies wird sowohl in C89 als auch in C99 ohne Warnungen kompiliert, und die Ausgabe lautet wie folgt:
$ ./ptrs
0xbfd9198c
0xbfd9198c
0xbfd9198c
Interessanterweise sind alle drei Werte identisch. Das sollte aber keine Überraschung sein! Lassen Sie uns zunächst das Programm aufschlüsseln.
Wir deklarieren x
als Zeiger auf ein Array von 5 Elementen, wobei jedes Element vom Typ Zeiger auf int ist. Diese Deklaration weist 4 Laufzeitbytes auf dem Laufzeitstapel zu (oder mehr, abhängig von Ihrer Implementierung; auf meinem Computer sind Zeiger 4 Bytes), x
bezieht sich also auf einen tatsächlichen Speicherort. In der C-Sprachfamilie ist der Inhalt von x
nur Müll, etwas, das von der vorherigen Nutzung des Standorts übrig geblieben ist, sodass er x
selbst nirgendwo hinweist - schon gar nicht auf zugewiesenen Speicherplatz.
Natürlich können wir die Adresse der Variablen nehmen x
und irgendwo ablegen , also tun wir genau das. Aber wir werden weitermachen und es in x selbst setzen. Da es &x
sich um einen anderen Typ handelt x
, müssen wir eine Besetzung durchführen, damit wir keine Warnungen erhalten.
Das Speichermodell würde ungefähr so aussehen:
0xbfd9198c
+------------+
| 0xbfd9198c |
+------------+
Der 4-Byte-Speicherblock an der Adresse 0xbfd9198c
enthält also das Bitmuster, das dem Hexadezimalwert entspricht 0xbfd9198c
. Einfach genug.
Als nächstes drucken wir die drei Werte aus. Die anderen Antworten erklären, worauf sich jeder Ausdruck bezieht, daher sollte die Beziehung jetzt klar sein.
Wir können sehen, dass die Werte gleich sind, aber nur in einem sehr niedrigen Sinne ... ihre Bitmuster sind identisch, aber die jedem Ausdruck zugeordneten Typdaten bedeuten, dass ihre interpretierten Werte unterschiedlich sind. Wenn wir beispielsweise x[0][0][0]
mit der Formatzeichenfolge ausdrucken %d
, erhalten wir eine große negative Zahl, sodass die "Werte" in der Praxis unterschiedlich sind, das Bitmuster jedoch dasselbe ist.
Das ist eigentlich ganz einfach ... In den Diagrammen zeigen die Pfeile nur auf dieselbe Speicheradresse und nicht auf verschiedene. Obwohl wir in der Lage waren, ein erwartetes Ergebnis aus undefiniertem Verhalten zu erzwingen, ist es nur das - undefiniert. Dies ist kein Produktionscode, sondern lediglich der Vollständigkeit halber eine Demonstration.
In einer vernünftigen Situation malloc
erstellen Sie das Array mit 5 int-Zeigern und erneut die Ints, auf die in diesem Array verwiesen wird. malloc
Gibt immer eine eindeutige Adresse zurück (es sei denn, Sie haben nicht genügend Speicher, in diesem Fall wird NULL oder 0 zurückgegeben), sodass Sie sich nie um solche selbstreferenziellen Zeiger kümmern müssen.
Hoffentlich ist das die vollständige Antwort, die Sie suchen. Sie sollten nicht erwarten x[0]
, x[0][0]
und x[0][0][0]
gleich zu sein, aber sie könnten sein, wenn sie gezwungen werden. Wenn Ihnen etwas über den Kopf ging, lassen Sie es mich wissen, damit ich es klären kann!
x[0]
,x[0][0]
Undx[0][0][0]
verschiedene Typen haben. Sie können nicht verglichen werden. Was meinst du damit!=
?