Ich erwarte, dass das Folgende die Ausgabe des obigen Programms ist. Zum Beispiel:
x // 0x100
x+1 // 0x104 Because x is an integer array
&x // 0x100 Address of array
&x+1 // 0x104
Aber die Ausgabe der letzten Anweisung ist anders als ich erwartet hatte. &x ist auch die Adresse des Arrays. Wenn Sie hier also um 1 erhöhen, wird die um 4 erhöhte Adresse gedruckt. Aber &x+1 ergibt die Adresse um 10 erhöht. Warum?
Es scheint, dass &x+1 Ihnen die Adresse nach dem Array-Speicher gibt (4*4=16 oder 0x100) …
– Alnet
18. November 2015 um 9:09 Uhr
Dies ist einer der Fälle, in denen Sie den Unterschied zwischen einem Zeiger und einem Array deutlich sehen.
– Klas Lindbäck
18. November 2015 um 9:15 Uhr
Wichtige Klarstellung: Diese Adressen sind in Hex. “Um 4 erhöht” bedeutet auch ein 0x4-Inkrement, aber “um 0x10 erhöht” meint “um 16 erhöht,” nicht um 10.
– kdbanman
18. November 2015 um 17:36 Uhr
@LukePark Es sollte eigentlich vom Typ int sein[4]
– Rationalcoder
18. November 2015 um 21:54 Uhr void * Nur eine Anmerkung (unabhängig von der Frage, die Sie stellen): Ihr Programm hat ein undefiniertes Verhalten (zumindest unter C99), da Sie die Zeiger darauf umwandeln müssen printf bevor Sie sie weitergeben
(weil es eine variadische Funktion ist). Siehe Drucken von Zeigern in C.
– schleske
Benutzeravatar von thepace
x -> Points to the first element of the array.
&x ->Points to the entire array.
i486 0x100 + sizeof x In Fall 4 erhalten Sie sizeof x und sizeof int ist 4 *
= 4 * 4 = 16 = 0x10. sizeof int (Auf Ihrem System
ist 4). sizeof int Hinzugefügt
Schritt, da es von System zu System unterschiedlich ist.
– Bathseba
Kowshikas Benutzeravatar
Kowshika
Eine einfache Daumenregel, um dies zu bewerten, lautet: Jeder Zeiger auf Inkrement zeigt auf den nächsten Speicherplatz seinerBasistyp
. Der Basistyp von &x ist hier[4] Ganzzahl (*p) die einZeiger auf Array von 4 Ganzzahlen
.
Der nächste Zeiger dieses Typs zeigt also auf eine Entfernung von 16 Bytes (unter der Annahme, dass int 4 Bytes beträgt) vom ursprünglichen Array. x Wenngleich &x und x auf den gleichen Zeigerwert auswerten, sie sind unterschiedliche Typen. Art der int* nachdem es zu einem Zeiger zerfällt &x während Art von int (*)[4]ist
sizeof(x) . sizeof(int)*4ist
. &x Daher der numerische Unterschied zwischen &x + 1 und sizeof(int)*4ist
.
int array[2][4];
Es kann besser mit einem 2D-Array visualisiert werden. Nehmen wir an, Sie haben: array Das Speicherlayout für
und schau dir den Speicher durch den Zeiger an, es sieht so aus: ptr Wie Sie sehen können, ist der Unterschied zw ptr+1 und sizeof(int)*4ist &x . Diese Analogie gilt für den Unterschied zwischen &x + 1 und
Benutzeravatar von Bathsheba
Bathseba Ob Sie es glauben oder nicht, das Verhalten Ihres Programms istnicht definiert
&x + 1 ! weist eigentlich darauf hin nur jenseits des Arrays, wie die Antwort von @ i486 geschickt hervorhebt. Sie besitzen diese Erinnerung nicht. Selbst der Versuch, ihm einen Zeiger zuzuweisen, ist ein undefiniertes Verhalten, geschweige denn der Versuch, dies zu tun Dereferenzierung
es. int[4]Ich dachte immer, dass dies definiert wurde, da ein Zeiger auf das Ende eines Arrays definiert wurde. Ich denke, es kann anders sein, da dies kein Array von ist
s, es ist nur eine.
– chbaker0
18. November 2015 um 11:03 Uhr
@Bathsheba: Können Sie hier den Standard zitieren? Normalerweise sind Pointer nach dem Ende wohldefinierte Dinge; Warum sollte es in diesem speziellen Fall nicht sein? –
Benutzer1084944
18. November 2015 um 11:57 Uhr
@Bathsheba: Wie Hurkyl erwähnt, sollte es im Standard einen Klappentext darüber geben, wie “skalare” Objekte als Arrays der Größe 1 zum Zweck von “über das Ende hinausgehenden” Zeigern behandelt werden. Ich würde erwarten, dass dies in diesem Fall zutrifft (da ein Array Arrays enthalten kann), aber der Standard widerspricht regelmäßig meinen Erwartungen.
– Matthias M.
18. November 2015 um 12:36 Uhr
@Bathsheba Sie dürfen nicht über das Array hinaus “schauen”, aber IIRC darf diese Adresse ausdrücklich in einem Zeiger speichern. Ich denke, diese Antwort (und andere auf diese Frage) decken dies ab.
– TripeHound
18. November 2015 um 13:59 Uhr @Bathsheba C11 6.5.6 p7: “Ein Zeiger auf ein Objekt, das kein Element eines Arrays ist, verhält sich genauso wie ein Zeiger auf das erste Element eines Arrays der Länge eins”. Nicht einmal eine Notiz – das ist der Haupttext. (geht unmittelbar dem Zeug über One-Past-the-End voraus) Keine UB hier.
Skalare sind genau das Gleiche wie Arrays für Zwecke der Zeigerarithmetik.
– Leuschenko
18. November 2015 um 16:19 Uhr int[4]Ich dachte immer, dass dies definiert wurde, da ein Zeiger auf das Ende eines Arrays definiert wurde. Ich denke, es kann anders sein, da dies kein Array von ist
s, es ist nur eine.
– chbaker0
18. November 2015 um 11:03 Uhr
@Bathsheba: Können Sie hier den Standard zitieren? Normalerweise sind Pointer nach dem Ende wohldefinierte Dinge; Warum sollte es in diesem speziellen Fall nicht sein? –
Benutzer1084944
18. November 2015 um 11:57 Uhr
@Bathsheba: Wie Hurkyl erwähnt, sollte es im Standard einen Klappentext darüber geben, wie “skalare” Objekte als Arrays der Größe 1 zum Zweck von “über das Ende hinausgehenden” Zeigern behandelt werden. Ich würde erwarten, dass dies in diesem Fall zutrifft (da ein Array Arrays enthalten kann), aber der Standard widerspricht regelmäßig meinen Erwartungen.
– Matthias M.
18. November 2015 um 12:36 Uhr
@Bathsheba Sie dürfen nicht über das Array hinaus “schauen”, aber IIRC darf diese Adresse ausdrücklich in einem Zeiger speichern. Ich denke, diese Antwort (und andere auf diese Frage) decken dies ab.
– TripeHound
18. November 2015 um 13:59 Uhr @Bathsheba C11 6.5.6 p7: “Ein Zeiger auf ein Objekt, das kein Element eines Arrays ist, verhält sich genauso wie ein Zeiger auf das erste Element eines Arrays der Länge eins”. Nicht einmal eine Notiz – das ist der Haupttext. (geht unmittelbar dem Zeug über One-Past-the-End voraus) Keine UB hier.
Skalare sind genau das Gleiche wie Arrays für Zwecke der Zeigerarithmetik.
– Leuschenko
14095900cookie-checkUnterschiedliche Pointer-Arithmetik-Ergebnisse beim Nehmen der Adresse des Arraysyes
Es scheint, dass &x+1 Ihnen die Adresse nach dem Array-Speicher gibt (4*4=16 oder 0x100) …
– Alnet
18. November 2015 um 9:09 Uhr
Dies ist einer der Fälle, in denen Sie den Unterschied zwischen einem Zeiger und einem Array deutlich sehen.
– Klas Lindbäck
18. November 2015 um 9:15 Uhr
Wichtige Klarstellung: Diese Adressen sind in Hex. “Um 4 erhöht” bedeutet auch ein 0x4-Inkrement, aber “um 0x10 erhöht” meint “um 16 erhöht,” nicht um 10.
– kdbanman
18. November 2015 um 17:36 Uhr
@LukePark Es sollte eigentlich vom Typ int sein[4]
– Rationalcoder
18. November 2015 um 21:54 Uhr
void *
Nur eine Anmerkung (unabhängig von der Frage, die Sie stellen): Ihr Programm hat ein undefiniertes Verhalten (zumindest unter C99), da Sie die Zeiger darauf umwandeln müssenprintf
bevor Sie sie weitergeben(weil es eine variadische Funktion ist). Siehe Drucken von Zeigern in C.
– schleske