Wie kommt ein array Adresse ist gleich seinem Wert in C?
In der folgende code, pointer-Werte und Zeiger Adressen unterscheiden sich, wie erwartet.
Aber array-Werte und Adressen nicht!
Wie kann das sein?
Ausgabe
my_array = 0022FF00
&my_array = 0022FF00
pointer_to_array = 0022FF00
&pointer_to_array = 0022FEFC
#include <stdio.h>
int main()
{
char my_array[100] = "some cool string";
printf("my_array = %p\n", my_array);
printf("&my_array = %p\n", &my_array);
char *pointer_to_array = my_array;
printf("pointer_to_array = %p\n", pointer_to_array);
printf("&pointer_to_array = %p\n", &pointer_to_array);
printf("Press ENTER to continue...\n");
getchar();
return 0;
}
Aus der comp.lang.c FAQ: - [was ist gemeint mit der `äquivalenz von Zeigern und arrays" in C? ](c-faq.com/aryptr/aryptrequiv.html) - [Da-array-Referenzen Zerfall in Zeiger, wenn arr ist ein array, was ist der Unterschied zwischen arr und &arr? ](c-faq.com/aryptr/aryvsadr.html) Oder gehen Sie Lesen Sie den gesamten Arrays und Zeiger - Bereich.
Ich habe dazu eine Antwort mit Diagramm zu dieser Frage in zwei Jahren wieder hier, Was bedeutet
Ich habe dazu eine Antwort mit Diagramm zu dieser Frage in zwei Jahren wieder hier, Was bedeutet
sizeof(&array)
zurück?
InformationsquelleAutor Alexandre | 2010-03-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der name eines Arrays in der Regel ergibt die Adresse des ersten Elements des Arrays, so
array
und&array
haben den gleichen Wert (aber verschiedene Arten, soarray+1
und&array+1
wird nicht gleich sein, wenn das array mehr als 1 element lang).Gibt es zwei Ausnahmen: wenn der array-name ist ein operand
sizeof
oder unäre&
(Adresse-von), der name bezieht sich auf das array-Objekt selbst. Sosizeof array
gibt die Größe in bytes) des gesamten Arrays, nicht die Größe eines Zeigers.Für ein array definiert als
T array[size]
wird es gebenT *
. Wenn Sie erhöhen Sie, Sie bekommen, um das nächste element im array.&array
wertet die gleiche Adresse, aber die gleiche definition, es erstellt einen Zeiger vom TypT(*)[size]
-- d.h., es ist ein Zeiger auf ein array, nicht zu einem einzigen element. Wenn Sie die Inkrement dieses Zeigers, wird es fügen Sie die Größe des gesamten Arrays, nicht die Größe eines einzelnen Elements. Zum Beispiel, mit code wie diesem:Können wir erwarten, dass der zweite Zeiger um 16 größer als das erste (weil es ein array von 16 char ' s). Da %p in der Regel konvertiert Zeiger in hexadezimaler, es könnte so Aussehen:
array
bezieht sich auf das gesamte array. Der grundlegende Unterschied kann auch beobachtet werden, durch den Vergleichsizeof(array)
zusizeof(&array)
. Beachten Sie jedoch, dass, wenn Sie passierenarray
als argument an eine Funktion, die nur&array
ist in der Tat bestanden. Sie können nicht übergeben Sie ein array von Wert, es sei denn, es ist gekapselt innerhalb einesstruct
.Wenn Sie übergeben Sie ein array an eine Funktion, es zerfällt zu einem Zeiger auf sein erstes element, so effektiv
&array[0]
übergeben wird, nicht&array
das wäre dann ein Zeiger auf das array. Es kann eine nit-pick, aber ich denke, es ist wichtig, klar zu machen; Compiler warnen, wenn die Funktion ein Prototyp, entspricht der Typ des Zeigers übergeben.Sarg Zum Beispiel int *p = &a, wenn ich will, dass die Speicher-Adresse des int-Zeiger p, ich kann &p. Da &array konvertiert und an die Adresse der ganzen Reihe (die beginnt bei der Adresse des ersten Elements). Dann wie finde ich die Speicher-Adresse des array-Zeiger speichert die Adresse des ersten Elements im array)? Es muss irgendwo in den Speicher, richtig?
Nein, es muss sich nicht um einen Zeiger auf das array irgendwo im Speicher. Wenn Sie erstellen Sie einen Zeiger, dann kannst du seine Adresse:
int *p = array; int **pp = &p;
.der erste Kommentar ist falsch, warum noch halten? Ich denke, es könnte zu Missverständnissen führen, für diejenigen, die nicht Lesen Sie die folgenden (@Karl) Antwort.
InformationsquelleAutor Jerry Coffin
Das ist, weil die array-Namen (
my_array
) unterscheidet sich von einem Zeiger auf array. Es ist ein alias für die Adresse eines Arrays, und seine Adresse ist definiert als die Adresse des array selbst.Den Zeiger ist eine normale C-variable auf den stack, jedoch. So können Sie Ihre Adresse ein und erhalten Sie einen anderen Wert aus der Adresse, die er hält im inneren.
Schrieb ich über dieses Thema hier - bitte werfen Sie einen Blick.
Ich bin mir nicht sicher, warum es ist erlaubt, wirklich.
Sie können die Adresse einer variable (wenn nicht gekennzeichnet
register
) unabhängig von Ihrer Lagerdauer: statische, dynamische oder automatische.my_array
sich auf dem Stapel, weilmy_array
ist das gesamte array.my_array
, wenn nicht das Thema der&
odersizeof
Operatoren ausgewertet wird, um einen Zeiger auf sein erstes element (ie.&my_array[0]
) - abermy_array
selbst ist nicht, die Zeiger (my_array
ist noch das array). Dieser Zeiger ist nur eine flüchtige rvalue (zB. angesichtsint a;
ist es wiea + 1
) - konzeptionell zumindest ist es "rechnerische Bedarf". Der wahre "Wert" desmy_array
ist der Inhalt des gesamten Arrays - es ist nur so, dass pinning dieser Wert in C ist wie zu versuchen zu fangen den Nebel in ein Glas.InformationsquelleAutor Eli Bendersky
In C, wenn Sie den Namen eines Arrays in einem Ausdruck (einschließlich der übergabe an eine Funktion), es sei denn, es ist der operand die Adresse des (
&
) der Betreiber oder diesizeof
Betreiber, es zerfällt zu einem Zeiger auf sein erstes element.Ist, in den meisten Kontexten
array
entspricht&array[0]
sowohl für Typ und Wert.In deinem Beispiel
my_array
Typchar[100]
die Zerfälle zu einemchar*
wenn Sie übergeben es an printf.&my_array
Typchar (*)[100]
(Zeiger auf array von 100char
). Als es ist der operand zu&
dies ist einer der Fälle, diemy_array
nicht sofort Karies zu einem Zeiger auf sein erstes element.Den Zeiger auf das array hat die gleiche Adresse-Wert als Zeiger auf das erste element des array als ein array-Objekt ist nur eine zusammenhängende Abfolge Ihrer Elemente, sondern ein Zeiger auf ein array hat eine andere Art, um einen Zeiger auf ein element des Arrays. Dies ist wichtig, wenn Sie tun, Zeiger-Arithmetik auf die zwei Arten von Zeiger.
pointer_to_array
Typchar *
- initialisiert, zeigen Sie auf das erste element des Arrays, wie das ist, wasmy_array
zerfällt in die Initialisierung Ausdruck - und&pointer_to_array
Typchar **
(Zeiger auf einen Zeiger auf einechar
).Dieser:
my_array
(nach Verwesungchar*
),&my_array
undpointer_to_array
alle zeigen Sie entweder direkt im array oder das erste element des Arrays und so haben die gleiche Adresse Wert.InformationsquelleAutor CB Bailey
In der B-Sprache zu Programmieren, das war der unmittelbare Vorgänger von C,
Zeiger und Ganzzahlen waren untereinander austauschbar. Würde das system sich Verhalten, als
obwohl alle Speicher war ein Riesen-array. Jeder Variablenname hatte entweder eine Globale
oder stack-relative Adresse
im Zusammenhang mit es, für jeden Variablennamen nur Dinge, die der compiler hatte, zu verfolgen war, ob es eine Globale oder lokale variable, deren Adresse relativ zu der ersten globalen oder lokalen Variablen.
Gegeben eine Globale Deklaration, wie
i;
[es gab keine Notwendigkeit, einen Typ angeben, da alles, was ein integer/pointer] wäre die Verarbeitung durch dascompiler:
address_of_i = next_global++; memory[address_of_i] = 0;
und eine Aussage wiei++
würde, als verarbeitet werden:memory[address_of_i] = memory[address_of_i]+1;
.Erklärung wie
arr[10];
würde verarbeitet alsaddress_of_arr = next_global; memory[next_global] = next_global; next_global += 10;
. Beachten Sie, dass, sobald die Erklärung bearbeitet wurde, der compiler könnte sofort vergessenarr
wird ein array. Eine Aussage wiearr[i]=6;
würde verarbeitet alsmemory[memory[address_of_a] + memory[address_of_i]] = 6;
. Der compiler würde nicht interessieren, obarr
repräsentiert ein array undi
eine ganze Zahl, oder Umgekehrt. In der Tat, es würde nicht interessieren, wenn Sie waren beide arrays oder beide ganze zahlen; es wäre wunschlos glücklich generieren den code, wie beschrieben, ohne Rücksicht darauf, ob das resultierende Verhalten wäre wahrscheinlich nützlich sein.Eines der Ziele der Programmiersprache C war weitgehend kompatibel mit B. In B, der name eines Arrays [genannt "Vektor" in der Terminologie des B] identifiziert eine variable halten einen Zeiger, der zunächst zugewiesene Punkt-zu-auf das erste element, eine Zuordnung der gegebenen Größe, so dass wenn, der name erschien in der Liste von Argumenten für eine Funktion, würde die Funktion erhält einen Zeiger auf den Vektor. Auch wenn C Hinzugefügt "echte" array-Typen, dessen name war starr Zusammenhang mit der Adresse, der die Zuordnung eher als eine Zeiger-variable, die zunächst zeigen Sie auf die Zuordnung, dass arrays zerlegen, Zeiger aus code, der erklärt, ein C-array-Typs Verhalten sich identisch zu B code deklariert einen vector und dann nie geändert, die variable hält seine Adresse.
InformationsquelleAutor supercat
Der Grund, warum
my_array
und&my_array
Ergebnis in der gleichen Adresse können Sie leicht verstehen, wenn man sich die Speicher-layout eines Arrays.Lassen Sie uns sagen, Sie haben ein array mit 10 Zeichen (anstatt der 100 in deinem code).
Speicher für
my_array
etwa so aussieht:In C/C++ ein array zerfällt, um den Zeiger auf das erste element in einem Ausdruck wie
Wenn Sie prüfen, wo das erste element des Arrays liegt, werden Sie sehen, dass Ihre Adresse ist die gleiche wie die Adresse des Arrays:
InformationsquelleAutor R Sahu
Eigentlich
&myarray
undmyarray
beide sind die Basis-Adresse.Wenn Sie wollen, um den Unterschied zu sehen anstatt
verwenden
InformationsquelleAutor Ravi Bisla