Mehrdimensionales Array an Funktion übergeben
-
ok nochmal ne andere Frage dazu ist eine String Tabelle nicht auch ein mehrdimensionales Array? Wieso werden die Parameter der main Funktion dann so festgelegt:
int main( int argc, char *argv[] ) {
-
Ich denke, es ist sehr hilfreich, wenn man das mal "aufmalt".
void foo(int *x[]); Array aus Zeiger Zeigern +------+ x -----> | x[0] |----> ? ? ? ... (ein int oder mehrere |------| hintereinander im Speicher) | x[1] |----> ? ? ? ... |------| | x[2] |----> ? ? ? ... +------+ : : wobei zu void foo(int x[][3]); folgendes Bildchen gehört Array aus Zeiger Arrays von 3 ints +---------------+ x -----> | x[0]: [? ? ?] | |---------------| | x[1]: [? ? ?] | |---------------| | x[1]: [? ? ?] | +---------------+ : :
wobei ? jeweils für einen int steht, welche im letzten Fall alle hintereinander im Speicher angeordnet sind, also x[0][1] steht hinter x[0][0], x[1][0] steht hinter x[0][2], u.s.w.
edit: Tippfehler 5 in 3 geändert
-
ok dazu habe ich nochmal ein paar Fragen. Erstmal wieso "5 ints "? SInd es nicht nur 3?
Dann das man für Stringtabellen
void foo(int *x[]);
verwndet erscheint mir logisch, mann weis ja nicht wie lang die einzelnen Strings sind.
Aber warum muss man bei der Übergabe mehrdimensionaler Arrays
void foo(int x[][3]);
verwenden. Liegt das nur am Zerfallsverhalten bei der Übergabe?
Aber wieso ist beim ersten die Übergabe der Länge nicht erforderlich? Wenn man sie doch beim 2. unbedingt zum berechnen braucht.
-
Max123 schrieb:
ok dazu habe ich nochmal ein paar Fragen. Erstmal wieso "5 ints "? SInd es nicht nur 3?
Sebastian Pizer war in seinem Schaublid anscheinend zu faul, alle 5 hin zu malen und hat sich mit 3 begnügt um das Prinzip zu zeigen. Aber int[5] sind nun mal 5 ints.
Dann das man für Stringtabellen
void foo(int *x[]);
verwndet erscheint mir logisch, mann weis ja nicht wie lang die einzelnen Strings sind.
Aber warum muss man bei der Übergabe mehrdimensionaler Arrays
void foo(int x[][3]);
verwenden. Liegt das nur am Zerfallsverhalten bei der Übergabe?
Mach dir nochmal den Unterschied klar: Das erste ist ein Array von Zeigern, das zweite ist ein Array von Array. Das sind ganz verschiedene Dinge! Sebastian Pizers Bild zeigt das schon genau wie es ist, mehr kann man da eigentlich nicht erklären. Guck dir das noch mal an!
Aber wieso ist beim ersten die Übergabe der Länge nicht erforderlich? Wenn man sie doch beim 2. unbedingt zum berechnen braucht.
Nochmal: Wenn man ein Array hat, muss man irgendwie berechnen können, wo array[0], array[1], array[2], usw. tatsächlich im Speicher liegen. Dazu muss man wissen, wie lang jedes einzelne Element ist, es ist aber egal, wie viele Elemente das Array selber hat.
Wenn man nun ein Array von Arrays hat, dann muss man wissen, wie viele Elemente die inneren Arrays haben, damit man weiß, wie lang die Elemente des äußeren Arrays sind.
-
Max123 schrieb:
ok dazu habe ich nochmal ein paar Fragen. Erstmal wieso "5 ints "? SInd es nicht nur 3?
Tippfehler von mir.
Max123 schrieb:
Aber wieso ist beim ersten die Übergabe der Länge nicht erforderlich? Wenn man sie doch beim 2. unbedingt zum berechnen braucht.
Du hast anscheinend den Unterschied zwischen Zeiger und Array nicht verstanden. Wie gesagt, der Elementzugriff ist syntaktisch derselbe. Trotzdem ist ein Zeiger etwas anderes als ein Array.
Gruß,
SP
-
Ok ich glaube ich habs jetzt verstanden.
void foo(int *x[]);
bei dem Array aus Zigern ist die Größe ja durch die Zeigerart festgelegt, also bekannt.
Beim Array aus Arrays hängt die Größe der Elemente des äußeren Arrays jedoch von der Element Anzahl der inneren ab- Deshalb muss diese bekannt sein.
Nur noch eine Frage wieso kann ich mehrdimensionale Arrays nicht an eine Funktion übergeben, indem ich mit
void foo(int *x[]);
einen Zeiger auf ein Zeigerarray übergebe?
-
Max123 schrieb:
bei dem Array aus Zigern ist die Größe ja durch die Zeigerart festgelegt, also bekannt.
Beim Array aus Arrays hängt die Größe der Elemente des äußeren Arrays jedoch von der Element Anzahl der inneren ab- Deshalb muss diese bekannt sein.
Das ist ein Bingo!
Max123 schrieb:
Nur noch eine Frage wieso kann ich mehrdimensionale Arrays nicht an eine Funktion übergeben, indem ich mit
void foo(int *x[]);
einen Zeiger auf ein Zeigerarray übergebe?
Hmm... Das sitzt noch nicht 100%. Also nochmal: Array != Zeiger
Deine Frage ist: Warum kann die Funktion foo
void foo(int *x[]);
nicht mit einem 2D-Array aufgerufen werden:
int dings[5][5]; foo(dings);
Die Antwort ist: Der Typ von
dings
istint[5][5]
(Array von Arrays von 5 ints). Der/Die/Das "array-to-pointer decay" würde in einem Objekt vom Typint(*)[5]
resultieren (Zeiger auf (das erste) Array von 5 ints). Der Typ vonx
ist aberint**
(Zeiger auf Zeiger auf int). Es passt also nicht zusammen.Was man auch nicht zu oft sagen kann:
std::vector
benutzen. Das Ding ist so schlau, dass es sogar weiß, wie groß es ist, kann die Größe dynamisch anpassen -- und das obwohl sizeof(std::vector<int>) konstant ist.Gruß,
SP
-
Das ist ein Bingo!
inglorious bastards geschaut?
ok danke also bei dem vector bin ich in meinem Buch noch nicht angekommen und ich würde das ganze schon ein wenig geordnet angehen wollen.
Mit dem Zerfallen kann man sich das so vorstellen, das der Typ immer um eins hin zur Adresse "degradiert wird" also aus:
int[5][5] wird int* [5], aus int [5] wird int*
nur wieso zerfällt die Stingtabelle, also die Parameter, die ich an main Übergebe zu char**?
-
Max123 schrieb:
int[5][5] wird int* [5], aus int [5] wird int*
fast, Klammern nicht vergessen. Aus
int[5][5] wird int(*)[5], eine Zeiger auf ein Array, nicht ein Array aus Zeigern - sonst könnte der Arrayzerfall ja weitergehen.nur wieso zerfällt die Stingtabelle, also die Parameter, die ich an main Übergebe zu char**?
Das ist von vornherein ein Array aus Zeigern. Arrays zerfallen beim kleinsten Anzeichen von Gefahr zu Zeigern.
-
ok dann ist ja alles klar mich hat nur das in meinem Buch verwirrt:
C-String-Tabellen sind [...] mehrdimensionale
char-Arrays.Das hat mich annehmen lassen, dass mehrdimensionale Arrays und String Tabellen das selbe sind.
Also zusammenfassend kann man sagen, Stringtabellen sind Arrays aus Zeigern und ein mehrdimensionales, "normales" Array ist ein Array aus Arrays.
-
Max123 schrieb:
ok dann ist ja alles klar mich hat nur das in meinem Buch verwirrt:
C-String-Tabellen sind [...] mehrdimensionale
char-Arrays.Das hat mich annehmen lassen, dass mehrdimensionale Arrays und String Tabellen das selbe sind.
Dann ist die Aussage entweder ungenau oder falsch. Ein mehrdimensionales char Array ist sowas wie char[5][20], das wären 5 Zeichenkette mit Länge 19 (weil ein Zeichen bei cstrings für das Ende draufgeht). Es werden aber immer 20 chars pro Zeichenkette belegt, egal wie lang die Zeichenketten wirklich sind.
Bei der Übergabe zur main hat man *char[], ein eindimensionales array von Zeigern auf andere chars. Dort wo diese Zeiger hinzeigen, liegen dann char Arrays mit genau der passenden Größe für die an main übergebenen Zeichenfolgen.
-
Man kann sich sogar darüber streiten, ob es eigentlich wirklich "mehrdimensionale Arrays" gibt, oder ob es nur Arrays von Arrays sind. :p
In Pascal gibt es -- wenn ich mich richtig erinnere -- "echte" mehrdimensionale Arrays, bei denen die Indizierung nicht über [x][y], sondern [x,y] läuft.
C++ erlaubt es einem aber, einen eigenen Typen so zu definieren, so dass er wie ein dynamisches mehrdimensionales Array benutzbar wird. ZB Boost.MultiArray.