Get Array Index Length !?
-
Sone schrieb:
Soweit ich sehe, hast du die Parameterdeklaration
int (*arr)[123]falsch interpretiert.
Nichtsdestotrotz stimmt da seine Aussage, denn hier wird nicht das Array übergeben, sondern ein Zeiger darauf.
Ein Array, das per value an eine Funktion übergeben wird, zerfällt immer (ohne Ausnahme) in einen Zeiger auf das erste Arrayelement.
-
Nathan schrieb:
ist das Array eine Referenz oder ein Pointer
So einen Blödsinn habe ich lange nicht gehört:
Ein Pointer ist kein Array, ein Array ist kein Pointer.
Außerdem ist hier nirgendwo eine (C++) Referenz zu sehen.
Eine Referenz zerfällt hier zu gar nichts, sie bleibt eine Referenz.
-
Wutz schrieb:
Nathan schrieb:
ist das Array eine Referenz oder ein Pointer
So einen Blödsinn habe ich lange nicht gehört:
Ein Pointer ist kein Array, ein Array ist kein Pointer.
Außerdem ist hier nirgendwo eine (C++) Referenz zu sehen.
Eine Referenz zerfällt hier zu gar nichts, sie bleibt eine Referenz.Sorry, sorry, mein Fehler.
Zu schnell geschrieben.
Dahinter sollte noch ein "auf ein Array".
"ist das Argument esine Referenz oder ein Pointer auf ein Array" sollte da eigentlich stehen.
Tschuldigung.
-
Macht immer noch keinen Sinn
Ein Array ist nie "eine Referenz" (der Satz ist nicht eindeutig)
Ein Array ist nie "eine Referenz auf ein Array"
Ein Array ist nie "ein Pointer auf ein Array"
-
Ein Array ist ein Array und eine Referenz kann nicht an Funktionen übergeben werden (der Typ eines Ausdrucks ist niemals eine Referenz).
-
Sone schrieb:
Ob du ein Array aus Skalaren oder ein Array aus Arrays aus Skalaren übergibst, ist irrelevant.
Soweit ich sehe, hast du die Parameterdeklaration
int (*arr)[123]falsch interpretiert.
Sone du hast keine Ahnung. Bleibe bei deinen Vektoren.
Das Problem ist, dass ein Array als Funktionsargument [...]
hier nicht der Fall ist, denn der Parameter hat dann Referenztyp/Zeigertyp. Die zerfallen zu gar nichts, weil sie mit Arrays nichts zu tun haben.
Sone du hast keine Ahnung. Du kennst nicht den Unterschied zwischen Argument und Parameter.
Du kannst überhaupt nicht wissen, was einer Funktion, die mittelsvoid foo(int (*arr)[123]);deklariert wurde, zur Laufzeit als Argument übergeben wird.
Wird ein Array übergeben, wird ein Zeiger daraus und zwar unabhängig davon, was du deklariert hast.void foo(int (*arr)[123]); void foo(int arr[][123]); void foo(int arr[321][123]);sind absolut äquivalent. Es ist völlig egal, welche Deklaration du wählst und was du glaubst was passiert, ein übergebenes Array wird hierbei immer zum Zeiger und nichts anderes habe ich gesagt.
Liebe Kinder, hört nicht auf Onkel Sone, es gilt nämlich:
- Ein Array ist kein Zeiger, ein Zeiger ist kein Array.
- Ein als Funktionsargument übergebenes Array zerfällt innerhalb der Funktion immer zu einem Zeiger auf sein erstes Element (das seinerseits wiederum ein Array sein darf, was dann natürlich nicht mehr zerfällt).call by referencegibt es nur, wenn die Referenz im Prototyp deklariert ist, alles andere ist immercall by value.
-
Wutz schrieb:
Sone du hast keine Ahnung. Bleibe bei deinen Vektoren.
Natürlich habe ich Ahnung. Ich frage mich langsam, ob du mich hier irgendwie veräppeln willst.
Das Problem ist, dass ein Array als Funktionsargument [...]
hier nicht der Fall ist, denn der Parameter hat dann Referenztyp/Zeigertyp. Die zerfallen zu gar nichts, weil sie mit Arrays nichts zu tun haben.
Sone du hast keine Ahnung. Du kennst nicht den Unterschied zwischen Argument und Parameter.
Lies mein Zitat mehrere hundertmal durch, dann wirst du verstehen, was ich gemeint habe.
Es geht um Parametertypen.Es ist völlig egal, welche Deklaration du wählst und was du glaubst was passiert, ein übergebenes Array wird hierbei immer zum Zeiger und nichts anderes habe ich gesagt.
Schöne Aussage, die kam von dir aber schon ein wenig pauschaler, nicht wahr:
Das Problem ist, dass ein Array als Funktionsargument immer (ohne Ausnahme) in einen Zeiger auf das erste Arrayelement zerfällt
Das ist nämlich Blödsinn, weil es in C++ Referenzen gibt.
Es geht nicht um die Argumente, sondern um den Funktionsrumpf, in dem a/b in diesem Beispiel in beiden Fällen ein Zeiger ist:void foo( int a[54], int b[1][2] ) { static_assert( std::is_same<decltype(a), int*>::value && std::is_same<decltype(b), int(*)[2]>::value, "" ); }Es ist nichts als eine Kopierinitialisierung eines Zeigers (Parameter) mit einem Array (Argument). Wenn der Parameter eine Referenz ist, oder eine Klasse, die eine Referenz auf ein Array im Konvertierungskonstruktor nimmt, dann wird eben diese Referenz bzw. Klasse damit initialisiert. Und zu Zeigern zerfällt nichts.
-
Du kannst überhaupt nicht wissen, was einer Funktion, die mittels
void foo(int (*arr)[123]);deklariert wurde, zur Laufzeit als Argument übergeben wird.
Nein, kann ich tatsächlich nicht:
#include <iostream> void foo( int(*b)[2] ) { std::cout << (*b)[0] << ' ' << (*b)[1]; } int main() { int b[2][2] = { {1, 2}, {3, 4} }; foo( b ); int c[2] = { 1, 2 }; foo( &c ); }Ergibt beides wohldefinierte und logische Ergebnisse. Wobei man solche Funktionssignaturen nur in C finden wird. Hoffentlich.
-
Sone schrieb:
Es ist nichts als eine Kopierinitialisierung eines Zeigers
Ein Zeiger kann nicht "kopierinitialisiert" werden, weil er keinen Kopierkonstruktor hat.
Zeiger = Array geht nicht so ohne weiteres. Wie bekommen wir dann das Array zu einem Zeiger? Na mit der "array-to-pointer conversion", umgangssprachlich als "array to pointer decay" bekannt. Rate mal, woher der Anglizismus "zerfallen" kommt.
Wenn der Parameter eine Referenz ist, oder eine Klasse, die eine Referenz auf ein Array im Konvertierungskonstruktor nimmt, dann wird eben diese Referenz bzw. Klasse damit initialisiert.
Ach genau, wir rufen den Konstruktor der Array-Referenz mit einer Referenz zu einem Array auf.
Um in Sone-Sprech zu bleiben: Dann wird nicht das Array übergeben, sondern der Typ "Referenz auf Array".
Und zu Zeigern zerfällt nichts.
Doch, Arrays.
Lies mein Zitat mehrere hundertmal durch
Nein, dann werde ich ja verrückt.
-
facepalm schrieb:
Ein Zeiger kann nicht "kopierinitialisiert" werden, weil er keinen Kopierkonstruktor hat.
Der Begriff "copy-initialization," wie er im Standard in Absatz 8.5 (14) definiert wird, hat mit Konstruktoren nichts zu tun. Zeiger können sehr wohl kopierinitialisiert werden, und das auch mit Arrays. Zitat:
ISO/IEC 14882:2011 8.5 (14) schrieb:
The initialization that occurs in the form
T x = a;as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization. [Note: Copy-initialization may invoke a move (12.8). -- end note]
facepalm schrieb:
Sone schrieb:
Wenn der Parameter eine Referenz ist, oder eine Klasse, die eine Referenz auf ein Array im Konvertierungskonstruktor nimmt, dann wird eben diese Referenz bzw. Klasse damit initialisiert.
Ach genau, wir rufen den Konstruktor der Array-Referenz mit einer Referenz zu einem Array auf.
Um in Sone-Sprech zu bleiben: Dann wird nicht das Array übergeben, sondern der Typ "Referenz auf Array".
Zum ersten Satz gilt im Grunde der gleiche Einwand. Initialisierung bedeutet nicht notwendigerweise den Aufruf eines Konstruktors, und eine Referenz kann (und muss) durchaus initialisiert werden.
Ich bin nicht sicher, was der zweite Satz bedeuten soll. Nackte Arraytypen können keine Funktionsparameter sein (Funktionen, die mit entsprechender Syntax deklariert werden, haben Zeigerparameter; siehe 13.1 (3)), von daher macht das Betrachten der Übergabe von Arrays an Funktionen überhaupt nur von der Aufrufseite her Sinn -- und Arrays, die an Funktionen übergeben werden, zerfallen nicht in allen Fällen zu Zeigern. nwp3 hatte am Anfang des Threads schonmal entsprechenden Code gepostet.
Wenn ein Array an eine Funktion übergeben wird, die einen passenden Zeiger erwartet, zerfällt es zu einem Zeiger. Wenn es an eine Funktion übergeben wird, die eine passende Array-Referenz erwartet, zerfällt es nicht. Das hat nur am Rande etwas mit dem Funktionsparameter zu tun; das selbe passiert, wenn man entsprechende lokale Variablen mit einem Array initialisiert.