Als Anfängerprogrammierer beschäftige ich mich mit einigen einfachen Problemen in Bezug auf Pointer. Im folgenden Code habe ich festgestellt, dass der Wert von *a
und a
in hexadezimal identisch ist. Aber ich kann den Grund nicht verstehen.
Hier ist die Ausgabe:
%Vor% In C- und C ++ - Sprachen werden Werte des Array-Typs T [N]
implizit in die Werte des Zeigertyps T *
in den meisten Kontexten konvertiert (mit wenigen Ausnahmen). Der resultierende Zeiger zeigt auf das erste Element des ursprünglichen Arrays (Index 0). Dieses Phänomen wird informell als Array-Typ-Zerfall bezeichnet.
printf
Argument ist einer dieser Kontexte, wenn Array-Typ-Zerfall passiert.
Ein 2D-Array vom Typ int [5][5]
ist nichts anderes als ein "1D-Array von 1D-Arrays", dh es ist ein Array von 5 Elementen, wobei jedes Element selbst ein Array von 5 int
s ist.
Die obige Abklingregel des Array-Typs trifft natürlich auf diese Situation zu.
Der Ausdruck a
, der ursprünglich den Array-Typ int [5][5]
hat, wird in einen Zeiger vom Typ int (*)[5]
umgewandelt. Der Zeiger zeigt auf das Element a[0]
, was der Anfang des Unterarrays a[0]
im Speicher ist. Dies ist der erste Zeiger, den Sie drucken.
Der Ausdruck *a
ist ein Dereferenzierungsoperator, der auf den Unterausdruck a
angewendet wird. Der Unterausdruck a
verhält sich in diesem Kontext genau so wie zuvor: Er verfällt in den Zeiger vom Typ int (*)[5]
, der auf a[0]
zeigt. Daher ist das Ergebnis von *a
a[0]
selbst. Aber a[0]
ist auch ein Array. Es ist ein Array von int[5]
type. Es unterliegt auch dem Verfall des Array-Typs. Es wird zum Zeiger des Typs int *
, der auf das erste Element von a[0]
verweist, also auf a[0][0]
, verfallen. Dies ist der zweite Zeiger, den Sie drucken.
Der Grund dafür, dass beide Zeigerwerte numerisch gleich sind, besteht darin, dass der Anfang des Unterarrays a[0]
dem gleichen Speicherort entspricht wie das Element a[0][0]
.
Ein Array und sein erstes Element haben dieselbe Adresse.:
Für diese Deklaration
%Vor% Der Ausdruck a
, der im printf-Aufruf verwendet wird, wird implizit in den Zeiger auf sein erstes Element konvertiert. Der Ausdruck *a
liefert das erste Element des Arrays, das wiederum ein eindimensionales Array ist, das auch in einen Zeiger auf sein erstes Element konvertiert wird.
Somit haben die Ausdrücke a
und *a
den gleichen Wert wie der Ausdruck &a[0][0]
a
kann als pointer to a pointer to an int
betrachtet werden (in Wirklichkeit ist es ein array of array of int
, aber nahe genug).
Also zeigen a
und *a
beide auf dieselbe Adresse (was zufällig a[0][0]
ist).
*a
ist immer noch ein Zeiger und a[0]
ist dieselbe Adresse wie a[0][0]
.