array übergeben
-
funk(int** p)
geht auch nicht !!
Gibt es irgendeine Möglichkeit !!
Ich dachte eigentlich immer der Arrayname ist vom Typ int*
Aber scheinbar doch nicht .
-
Kóyaánasqatsi schrieb:
Für dein 2D-Array würde ich einfach einen doppelten Zeiger nehmen...
Dir ist schon klar, daß die automatische Array-zu-Zeiger Umwandlung nur in einer Dimension funktioniert?
@blurry: Damit die Funktion korrekt arbeiten kann, muß sie einen Zeiger auf int-Arrays bekommen:
void func(int* arr[3]);
(hoffe ich, könnte auch eine 4 sein). Aber in C++ sollte man eher weniger mit blanken Arrays und Zeigern hantieren - stattdessen sind STL-Container (std::vector<>, std(::tr1)::array<> etc) praktischer.
-
void func(int* arr[3])
geht auch net.
-
CStoll schrieb:
Kóyaánasqatsi schrieb:
Für dein 2D-Array würde ich einfach einen doppelten Zeiger nehmen...
Dir ist schon klar, daß die automatische Array-zu-Zeiger Umwandlung nur in einer Dimension funktioniert?
Funktioniert doch:
void test(int sizeA, int sizeB, int **b) { } int main(int argc, char* argv[]) { int a[5][7]; test(5, 7, (int**)a); return 0; }
Ich weiß nicht genau was du meinst.
-
Wenn ich weiß, dass der c-string "\xB8\x00\x00\x00\x00\xC3" einer asm-Funktion entspricht, die 0 zurückgibt, kann ich auch das machen mit einem Cast. Es geht um implizierte Konvertierungen.
-
Kóyaánasqatsi schrieb:
Ich weiß nicht genau was du meinst.
Und hast du mal versucht, in der Funktion etwas mit dem übergebenen Array zu machen.
@blurry: Riskiere es blos nicht, die Fehler genauer in Worte zu fassen. Es könnte ja sein, daß dir dann jemand helfen kann
-
CStoll schrieb:
Kóyaánasqatsi schrieb:
Ich weiß nicht genau was du meinst.
Und hast du mal versucht, in der Funktion etwas mit dem übergebenen Array zu machen.
Auf die schnelle:
#include <iostream> void test(int sizeA, int sizeB, int **b) { for(int n = 0; n < sizeB; ++n) { for(int i = 0; i < sizeA; ++i) { b[i][n]; } } } int main() { int a[5][7]; test(5, 7, (int**)a); test; return 0; }
-
Ich rede nicht von irgendwelchen noop-Spielereien, die jeder Amateur-Compiler wegoptimieren kann, sondern von echten Zugriffen - und da macht sich der Cast nicht besonders gut.
PS: Mit den richtigen Parametern sieht es schon wesentlich besser aus.
-
#include <iostream> #include <array> template<std::size_t Size1, std::size_t Size2> void funk(std::array<std::array<int, Size1>, Size2>& p) { cout<<"Funktioniert"; } int main() { std::array<std::array<int, 4>, 3> arr; funk(arr); }
Fixed
-
Kóyaánasqatsi schrieb:
void test(int sizeA, int sizeB, int **b); int main() { int a[5][7]; test(5, 7, (int**)a); return 0; }
Lieber Kóyaánasqatsi, das, was Du da von Dir gegeben hast, lässt sich zwar wegen des Casts kompilieren, ist aber völlig unbrauchbar. Der Cast ist äquivalent zu einem reinterpret_cast von int(*)[7] zu int**. Es hat einen Grund, warum Dich der Compiler diese Konvertierung nicht ohne einen reinterpret_cast durchführen lässt. Ein Zeiger auf ein 7-elementiges int-Array ist eben kein Zeiger auf einen int-Zeiger.
-
ein mehrdimensionales array von char wird aber doch auch mit einem char** übergeben. Siehe nur argv .
-
blurry333 schrieb:
ein mehrdimensionales array von char wird aber doch auch mit einem char** übergeben. Siehe nur argv .
Nein.
argv ist ein Array von char*
Bei einem mehrdimensionales Array liegen alle Elemente hintereinander im Speicher, wobei der ganze rechte Index am schnellsten wechselt.
char a[3][4]
liegt im Speicher als a00, a01, a02 a03, a10, a11, a12, a13, a20, a21, a22 ,a23.Damit entspricht a einem
char*
Wenn du ein
char a[z][s]
hast, kannst du auf das Elementa[i][j]
auch mit*(a+i*s+j)
zugreifen
-
argv[0] argv[1] argv[2] . . usw
werden mit char** argv übergeben
-
blurry333 schrieb:
ein mehrdimensionales array von char wird aber doch auch mit einem char** übergeben. Siehe nur argv.
Das kommt auf Deine Definition von "mehrdimensionales Array" an. Ich verwende diesen Begriff erst gar nicht. Eindeutiger ist da schon "Array von Arrays" versus "Array von Zeigern".
int w[5][7]; // 5-elementiges Array von 7-elementigen Arrays int (*x)[7] = w; // Zeiger auf 7-elementiges Array (zeigt auf das erste Element von w) int *y[5]; // 5-elementiges Array von Zeigern int **z = y; // Zeiger auf Zeiger (zeigt auf das erste Element von y)
Per array-to-pointer decay kommt man von w nach x und von y nach z. Und da Zeiger keine Arrays sind, macht
int **silly = (int**)w;
absolut keinen Sinn.
Das einzige, was w,x,y,z, gemeinsam haben ist, dass man zweimal den []-Operator drauf anwenden kann. Wenn das schon ausreicht, um von "zweidimensionalen Arrays" zu sprechen, dann bist Du leider unpräzise, blurry333; denn man weiß dann nicht wirklich, was für ein Speicherlayout Du Dir vorstellst.
Irgendwas noch unklar? Dann guckt doch am besten mal in einem schlauen Buch nach, statt Fehlinformationen aus bescheidenen Tutorials zu extrahieren oder sie selbst zu produzieren.
-
CStoll schrieb:
@blurry: Damit die Funktion korrekt arbeiten kann, muß sie einen Zeiger auf int-Arrays bekommen:
void func(int* arr[3]);
Das ist kein Zeiger auf int-Arrays sondern ein Array von Zeigern auf int.
Ein Zeiger auf ein int-Array sieht so aus:void func(int (*arr)[3]);
-
blurry333 schrieb:
argv[0] argv[1] argv[2] . . usw
werden mit char** argv übergeben
Ja und? argv verweist auf (das erste Element) ein(es) Zeiger-Array(s). Bei
int foo[5][7];
gibt es kein Zeiger-Array. foo ist ein Array von Arrays. Du kannst jetzt noch ein Zeiger-Array einführen:
int* za[] = { foo[0], foo[1], foo[2], foo[3], foo[4] }; int** p = za;
dann zeigt p aber nicht auf irgendwas in foo sondern auf das erste Element des Zeiger-Arrays za.
Haben wir's jetzt?
-
Jetzt würde ich aber auch gerne Mal diese Klammerungen verstehen bzw. den Hintergrund der Schreibweisen verstehen.
int * a[5];
Bindet jetzt [] oder * stärker und was bedeutet das? Und gehört * überhaupt zum a oder int? Eigentlich doch zum int, aber die int*-Schreibweise verwirrt ja wiederum, weil:
int* a, b;
a als int-Zeiger aber b als int deklariert. Dann ist das von C++ aber unlogisch, wenn * eigentlich zum int gehört, oder?
So, und (*a) macht ja nur Sinn, wenn [] sonst stärker binden würde, also ist:
int * a[5];
äquivalent zu
int * (a[5]);
(es sei denn, die Klammern erhalten hier noch irgend eine andere Sonderbedeutung)Aber a[5] ohne den Typen macht für mich auch erstmal wenig Sinn. Kann mir das jemand verständlich erklären? Oder ist das willkürlich?
-
funk(int* arr); int array[3]; funk(&array) // Warnung aber funktioniert funk(array) // funktioniert auch
-
@Eisflamme: Du hast es dir quasi schon selber erklärt, du bist nur bei einer Grundannahme falsch und deshalb verwirrt: Das * gehört zur Variable, nicht zum Typen! Ich dachte immer, das wäre Grundbildung bei Pointern, weil es eben genau die Erklärung ist, warum bei
int *a,b;
das b kein Pointer ist. Das Sternchen heißt, dass der Bezeichner als ein Pointer auf den angegebenen Typ anzusehen ist (wodurch der Bezeichner dann vom Typ "Pointer auf X" wird).Der Rest ist dann die Stärke der Bindung, [] bindet stärker als *.
-
blurry333 schrieb:
void funk(int* arr); int array[3]; funk(&array); // Warnung aber funktioniert funk(array); // funktioniert auch
Dein "Warnung aber funktioniert" kompiliert bei mir nicht.
Lieber blurry333. Dieses Beispiel ist nicht selbsterklärend. Es ist nicht klar, was du damit sagen wolltest. Es steht jedenfalls in keinem Widerspruch zu dem, was hier von mir, Wutz, DirkB und CStoll gesagt worden ist.
Weißt Du, was eine implizite Konvertierung ist? Das ist eine Konvertierung die automatisch stattfindet, ohne dass man dafür etwas besonderes hat hinschreiben müssen. Beispiel:
void foo(double); int main() { int i = 3; foo(i); }
Ist i jetzt auch ein double, weil Du foo mit i aufrufen kannst und foo einen double erwartet? Nein. i ist ein lvalue-Ausdruck vom Typ int. Das was foo bekommt ist ein double-Wert. Hier findet eine unsichtbare Konvertierung statt.
Genauso verhält es sich mit dem array-to-pointer decay. Arrays sind keine Zeiger. Aber Du kannst einen Array-Ausdruck vom Typ T[N] dort verwenden, wo ein T* erwartet wird. Das liegt an dieser impliziten Konvertierung. Das Ergebnis dieser Konvertierung ist die Adresse des ersten Array-Elements.
int arr[7]; int* p = arr; // implizite Konvertierung int* q = &arr[0]; // explizit die Adresse des ersten Elenents holen assert(p==q);