[Mehrdimensionale Arrays]Frage zu Satz aus Lehrbuch
-
VieleDimensionen schrieb:
@out
Laut dem was ich im buch gelesen habe sind Arrays und Pointer in C++ sehr eng miteinander verknüpft.
Im Buch steht geschrieben,wenn ich int arr[5] definiere und den Namen arr in einem beliebigen Ausdruck z.B. arr[1]=3; verwende wird der Name automatisch in einen Zeiger auf das erste Element des Arrays umgewandeltDas ist falsch. Das was in deinem Buch steht, ist falsch. Wie heißt dein Buch denn?
VieleDimensionen schrieb:
int main() { int a = 1; int arr[3][4]; for (int i = 0; i < 2; ++i){ for (int in = 0; i < 3; ++i) { arr[i][in] = a; ++a; } } std::cout << &arr[2][0] <<std::endl; std::cout << arr[2]; std::cin.get(); return 0; }
Es wird die selbe Adresse ausgegeben also greife ich mit arr[2] auf die erste Adresse der dritten Zeile des Arrays zu und nicht auf den Wert selbst der in diesem Array liegt.
Auch das ist falsch.
1. Mit [] greifst du immer auf den Wert des Arrays zu, und nie auf eine Adresse eines Elements. Willst du auf eine Adresse zugreifen, musst du logischerweise den Adressoperator & nehmen.<<
ist eine Funktion. Nämlichoperator<<(*/...*/)
Übergibst du ein Array an eine Funktion, findet auch array-to-pointer-decay statt. Machst du nunstd::cout << arr[2];
wirdarr[2]
an die Funktionoperator<<(*/...*/)
übergeben und du bekommst automatisch einen Zeiger auf das erste Element des Arrays. In der Funktionoperator<<(*/...*/)
wird dann einfach der Zeiger ausgegeben. Gibst du ein Zeigervariable aus, wird - wie bei jeder anderen Variable auch - der Inhalt der Variablen ausgeben. Der Inhalt einer Zeigervariablen ist die Adresse, auf die der Zeiger zeigt. Und diese Adresse ist jetzt halt die Adresse vom ersten Element des Arrays.
Wie heißt jetzt nochmal dein Buch?:D
-
Ergänzung zu oben:
Ein Array ist nie ein Zeiger auf irgendwas.
Es gibt nur bestimmte Fälle, also Ausnahmen, wo ein Array in einen Zeiger auf das erste Element konvertiert werden muss. Da findet eine Konvertierung statt. Die müsste nicht stattfinden, wenn ein Array ein Zeiger wäre. Lässt sich auch leicht beweißen, dass ein Array kein Zeiger ist.int main() { int array[5] = {1,2,3,4,5}; int nochmal_array[5] = {10,20,30,40,50}; array = nochmal_array; // Fehler int* zeiger; zeiger = nochmal_array; // Kein Fehler. }
Wäre ein Array wie ein Zeiger, gäbe es keinen Fehler...
-
Also das verwirrt mich jetzt echt.
Ich lerne mit dem C++ Primer das hier steht wörtlich so im Buch auf Seite 158:
"Zeiger und Arrays sind in C++ eng miteinander verknüpft.
Insbesondere wird der Name eines Arrays automatisch in einen Zeiger auf das erste Arrayelement umgewandelt,wenn wir ihn in einem Ausruck verwenden."
Beispiel dazu aus dem Buch:int ia[] = {0,2,4,6,8}; int *ip = ia;
Und das Buch ist ja jetzt nicht von irgendeinem Deppen verfasst und bekommt überall gute Rückmeldungen.
-
VieleDimensionen schrieb:
Also das verwirrt mich jetzt echt.
Ich lerne mit dem C++ Primer das hier steht wörtlich so im Buch auf Seite 158:
"Zeiger und Arrays sind in C++ eng miteinander verknüpft.
Insbesondere wird der Name eines Arrays automatisch in einen Zeiger auf das erste Arrayelement umgewandelt,wenn wir ihn in einem Ausruck verwenden."Das ist im Wesentlichen richtig. Es stimmt für alle Ausdrücke außer für sizeof- und Adressausdrücke.
Und das Buch ist ja jetzt nicht von irgendeinem Deppen verfasst und bekommt überall gute Rückmeldungen.
Das hat nichts zu bedeuten.
-
Ja das Buch ist gut.
Wie soll ich das jetzt erklären. Er meint nicht "immer wenn der Name des Arrays auftaucht", sondern er meint, wenn "DAS ARRAY" an sich auftaucht. Also
int ia[] = {0,2,4,6,8}; int *ip = ia; // ia => DAS ARRAY an sich.
int ia[] = {0,2,4,6,8}; int varialbe = ia[0]; // Hier ist es aber ia[N], und NICHT das Array an sich.
Verstehst du nun, worauf es hinausläuft. Also ohne Indexoperator ist das Array an sich.
-
out schrieb:
Ja das Buch ist gut.
Wie soll ich das jetzt erklären. Er meint nicht "immer wenn der Name des Arrays auftaucht", sondern er meint, wenn "DAS ARRAY" an sich auftaucht. Also
int ia[] = {0,2,4,6,8}; int *ip = ia; // ia => DAS ARRAY an sich.
int ia[] = {0,2,4,6,8}; int varialbe = ia[0]; // Hier ist es aber ia[N], und NICHT das Array an sich.
Verstehst du nun, worauf es hinausläuft. Also ohne Indexoperator ist das Array an sich.
Achso ja jetzt habe ich es auch verstanden :D.
Der Name allein ohne Index wird zum Zeiger auf das erste Element umgewandelt und der Name mit Index wird einfach direkt angesprochen.
Ich schätze mal es wird der Übersetzung des Buches ins Deutsche geschuldet sein,aber ich hatte einfach keinen Nerv so einen Wälzer komplett in Englisch zu lesen.
Nochmals vielen Dank an euch für die Hilfe.
-
out schrieb:
int ia[] = {0,2,4,6,8}; int varialbe = ia[0]; // Hier ist es aber ia[N], und NICHT das Array an sich.
Verstehst du nun, worauf es hinausläuft. Also ohne Indexoperator ist das Array an sich.
Falls du damit sagen willst, dass das Array hier nicht in einen Zeiger umgewandelt wird, liegst du falsch. Ergebnis:
Achso ja jetzt habe ich es auch verstanden :D.
Ja, toll
-
Bashar schrieb:
out schrieb:
int ia[] = {0,2,4,6,8}; int varialbe = ia[0]; // Hier ist es aber ia[N], und NICHT das Array an sich.
Verstehst du nun, worauf es hinausläuft. Also ohne Indexoperator ist das Array an sich.
Falls du damit sagen willst, dass das Array hier nicht in einen Zeiger umgewandelt wird, liegst du falsch. Ergebnis:
Achso ja jetzt habe ich es auch verstanden :D.
Ja, toll
Oh nein bitte nicht
.
Und wer hat jetzt Recht?
-
Bashar schrieb:
out schrieb:
int ia[] = {0,2,4,6,8}; int varialbe = ia[0]; // Hier ist es aber ia[N], und NICHT das Array an sich.
Verstehst du nun, worauf es hinausläuft. Also ohne Indexoperator ist das Array an sich.
Falls du damit sagen willst, dass das Array hier nicht in einen Zeiger umgewandelt wird, liegst du falsch.
Das hör ich jetzt zum ersten Mal. Kann das jemand bestätigen
?
-
Du könntest in einem C++-Buch deines Vertrauens oder im Standard nachlesen, wie der []-Operator definiert ist.
-
So ich habe nochmal nachgeforscht auf der MSDN Seite wird es auch so erklärt:
"Usually, the value represented by postfix-expression is a pointer value, such as an array identifier, and expression is an integral value (including enumerated types). However, all that is required syntactically is that one of the expressions be of pointer type and the other be of integral type. Thus the integral value could be in the postfix-expression position and the pointer value could be in the brackets in the expression or subscript position. Consider the following code fragment:"
int nArray[5] = { 0, 1, 2, 3, 4 }; cout << nArray[2] << endl; // prints "2" cout << 2[nArray] << endl; // prints "2"
Und hier die fortsetzung:
"In the preceding example, the expression nArray[2] is identical to 2[nArray]. The reason is that the result of a subscript expression e1[ e2 ] is given by:"*( (e2) + (e1) )
Das Ergebniss wird also mit dem vorangestellten * dereferenziert was ja nochmal deutlich macht,dass es sich hier im einen Pointer handelt .
-
Bashar schrieb:
Du könntest in einem C++-Buch deines Vertrauens oder im Standard nachlesen, wie der []-Operator definiert ist.
Ok, muss ich mal gugen. Könnte schwören das trifft auf [] nicht zu.
Ok, dann muss man also sagen, dass es Ausnahmen gibt, bei denen array-to-pointer-decay nicht passiert, z.B. bei call-by-reference. Hab ich in diesem Thread auch was gelernt :).
-
VieleDimensionen schrieb:
Das Ergebniss wird also mit dem vorangestellten * dereferenziert was ja nochmal deutlich macht,dass es sich hier im einen Pointer handelt .
Vorsicht mit solchen Interpretationen. Das Array ist selbst kein Pointer, es wird in einen Pointer umwandelt. Den Unterschied siehst du dann, wenn diese Umwandlung mal nicht passiert, z.B. bei sizeof(array) und bei &array. Ansonsten führt diese Umwandlung dazu, dass sich ein Array weitestgehend wie ein Pointer anfühlt, daher auch diese relativ ungenaue Beschreibung in der MSDN.
-
Bashar schrieb:
VieleDimensionen schrieb:
Das Ergebniss wird also mit dem vorangestellten * dereferenziert was ja nochmal deutlich macht,dass es sich hier im einen Pointer handelt .
Vorsicht mit solchen Interpretationen. Das Array ist selbst kein Pointer, es wird in einen Pointer umwandelt. Den Unterschied siehst du dann, wenn diese Umwandlung mal nicht passiert, z.B. bei sizeof(array) und bei &array. Ansonsten führt diese Umwandlung dazu, dass sich ein Array weitestgehend wie ein Pointer anfühlt, daher auch diese relativ ungenaue Beschreibung in der MSDN.
Kann ich es dann so verstehen?:
Das Array selbst ist einfach ein Typ welcher aus anderen Typen zusammengesetzt wird.Um aber mit den einzelnen Werten der Elementen eines Arrays zu arbeiten wird ein Pointer erzeugt welcher auf die Adresse des ersten Elements zeigt.Mithilfe der im Pointer enthaltenden Start Adresse ist es dann möglich die anderen Adressen der im Array enthaltenden Elemente zu berechnen.
-
Ja, genau so ist es.
-
Das Array selbst ist einfach ein Typ welcher aus anderen Typen zusammengesetzt wird.
Abgesehen von der Tatsache dass es nur ein Typ ist und nicht mehrere ist das korrekt. Arrays sind neben Klassen, Funktionen, Zeigern, Referenzen und Enumerationen auch sog. compound types - zusammengesetzte Typen.
Ok, muss ich mal gugen. Könnte schwören das trifft auf [] nicht zu.
Doch.
One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type.
The result is of type “T
.” The type “T
” shall be a completely-defined object type. **The expressionE1[E2]
is identical (by definition) to*((E1)+(E2))
**[...].Im Ausdruck
(E1)+(E2)
zerfällt, wennE1
oderE2
ein Arrayobjekt ist, dieses Arrayobjekt zu einem Zeiger. Auf diesen Zeiger wird dann der Index addiert. Natürlich aber ist das Arrayobjekt zu keinem Zeitpunkt ein Zeiger - die Differenzierung im Zitat macht das nochmal deutlich.