Mehrdimensionale Arrays in und um Funktionen. Möglichst viel Array-Syntax..



  • Ich habe versucht mehrdimensionale arrays als Funktionsparameter zu übergeben..
    also statt

    void funktion(int ary[])
    

    ,

    void funktion(int ary[][])
    

    ,
    damit ich dann innerhalb der Funktion auch so darauf zugreifen kann..
    Sehe ich das richtig, dass ich das nur mit Zeigern machen kann, sowohl im Parameter als auch in der Funktion!?

    void funktion(int ary[])
    {
    ... = ary[i]; //oder
    ary[i] = ...;
    }
    

    scheint zu gehen,

    void funktion(int ary[][])
    {
    ... = ary[i][j]; //oder
    ary[i][j] = ...;
    }
    

    geht nicht.

    Also bleibt nur:

    void funktion(int *ary)
    {
    ... = ary+i; //oder
    ary+i = ...;
    }
    

    , oder kann ich zumindest in der Funktion auch irgendwie mit "[]" arbeiten???

    Kurz gesagt, möchte ich so viel wie möglich vom array-Syntax behalten und so wenig wie möglich mit Pointern machen.. Wie mache ich das am besten??
    Gruß



  • Du übergibst Pointer und verwendest Arraysyntax wie gehabt.



  • Harray19085 schrieb:

    Also bleibt nur:

    void funktion(int *ary)
    {
    ... = ary+i; //oder
    ary+i = ...;
    }
    

    , oder kann ich zumindest in der Funktion auch irgendwie mit "[]" arbeiten???

    Du kannst dann auch [] benutzen:

    void funktion(int *ary)
    {
    ... = ary[i]; // oder
    ary[i] = ...;
    }
    

    Kurz gesagt, möchte ich so viel wie möglich vom array-Syntax behalten und so wenig wie möglich mit Pointern machen.. Wie mache ich das am besten??
    Gruß

    Bei parameterübergabe degenerieren Arrays zu Pointer. Da kommst du nicht rum. Ein 2D-Array würde zu einem Pointer auf einen Pointer degenerieren:

    void funktion(int **ary)
    {
    ... = ary[i][j]; // oder
    ary[i][j] = ...;
    }
    

    Natürlich solltest du die Array-Grenzen noch als zusätzliche Parameter übergeben, damit du sie beachten kannst.


  • Mod

    oenone schrieb:

    Bei parameterübergabe degenerieren Arrays zu Pointer. Da kommst du nicht rum. Ein 2D-Array würde zu einem Pointer auf einen Pointer degenerieren:

    void funktion(int **ary)
    {
    ... = ary[i][j]; // oder
    ary[i][j] = ...;
    }
    

    Natürlich solltest du die Array-Grenzen noch als zusätzliche Parameter übergeben, damit du sie beachten kannst.

    Das ergibt keinen Sinn.



  • oenone schrieb:

    Ein 2D-Array würde zu einem Pointer auf einen Pointer degenerieren:

    Nein.


  • Mod

    Da kommst du nicht rum. Ein 2D-Array würde zu einem Pointer auf einen Pointer degenerieren:

    Das macht tatsächlich keinen Sinn. Es ist nämlich so dass ein Array in einen Zeiger auf das erste Element zerfallen kann. Der Elementtyp eines multidimensionalen Arrays ist jedoch ein anderes Array, kein Zeiger. Wie soll das also gehen?



  • Das gehört imho eindeutig ins C Forum


  • Mod

    hardware schrieb:

    Das gehört imho eindeutig ins C Forum

    Nur weil der fragliche Code mit einem C-Compiler auch übersetzt gehört es nicht ins C Forum.



  • Arcoth schrieb:

    Nur weil der fragliche Code mit einem C-Compiler auch übersetzt gehört es nicht ins C Forum.

    Endlich mal ein Moderator, der das auch so sieht 👍



  • Ich war mir nicht sicher, ob ich es nicht doch ins C Forum schreiben sollte, aber hätte ja sein können, dass C++ etwas neues zur Problemlösung bereitgestellt hätte..
    Was ist denn eigentlich nun die Lösung??
    Und in was zerfällt ein array[][] im Funktionsargument?

    Ich habs jetzt auch mal mit einfachen Zeigern und deren Inkrementierung versucht und bin gescheitert.. Irgendwie habe ich so meine Probleme mit mehrdimensionalen Arrays..


  • Mod

    Harray19085 schrieb:

    Ich war mir nicht sicher, ob ich es nicht doch ins C Forum schreiben sollte, aber hätte ja sein können, dass C++ etwas neues zur Problemlösung bereitgestellt hätte..
    Was ist denn eigentlich nun die Lösung??

    C++ traegt insofern etwas bei, als dass man nicht direkt mit den rohen Arrays arbeiten wuerde. Man wurde sich eine schoene Klasse basteln (oder das fertige std::array nehmen), die das Array wrappt. Dank Operatorueberladung bekommt man auch sehr leicht eine halbwegs schoene Syntax hin (mit runden Klammern, statt eckigen) oder, mit etwas mehr Aufwand, sogar die exakt gleiche Syntax wie bei 2D-Arrays (also mit eckigen Klammern). Dank Templates ist es dann auch nicht schwierig, eine allgemeine Funktion zu schreiben, die auf diesen Array-artigen Klassen arbeitet, selbst wenn die Groesse ein Teil des Typs sein sollte. Ebenso sind templates natuerlich ausserst hilfreich, um diese Klassen ueberhaupt zu erzeugen.

    Und in was zerfällt ein array[][] im Funktionsargument?

    array[][] ist kein Typ.

    Wenn du eine Funktion

    void foo(int bar[][])
    

    hast, ist das nur eine andere Schreibweise fuer

    void foo(int **bar)
    

    Also fuer Zeiger auf Zeiger (Arrays sind keine Zeiger und umgekehrt!). Dem kannst du entsprechend auch kein 2D Array uebergeben, denn beispielsweise ein Array int my_array[2][3] wuerde beim Aufruf foo(my_array) in ein int (*)[3] zerfallen, also einen Zeiger auf ein Array von 3 ints. Die Funktion will aber einen Doppelzeiger, daher passt es nicht.

    Die C++-igste Loesung habe ich oben schon beschrieben. C++ kann aber prinzipiell auch auf den rohen 2D-Arrays arbeiten, indem man die inneren Dimensionen templatisiert:

    template <size_t N> void foo(int bar[][N])
    

    Eine Funktion nach dieser Vorlage erwartet also tatsaechlich einen Zeiger auf ein Array von N ints und wenn man in dem obigen Beispiel N=3 setzt, dann passt es.
    Wenn man vielleicht sowieso weiss, dass N immer 3 ist, dann kann man das Template natuerlich auch weg lassen:

    void foo(int bar[][3])
    

    Diese Funktion erwartet immer und nur Zeiger auf Arrays aus 3 ints.

    Wenn man gar nichts weiss, dann sind in C++ die beschriebenen Wege gut. Aber wie geht das in C? Da wuerde man vermutlich so etwas machen:

    void foo(int bar[], size_t length_x, size_t length_y)
    

    Und dann Aufruf mit einem Zeiger auf das erste Element des ersten Elements des 2D-Arrays, also im obigen Beispiel foo(my_array[0], 2, 3) . Das my_array[0] ist das erste Array im 2D-Array und beim Aufruf der Funktion zerfaellt dies in einen Zeiger auf sein erstes Element, also den allerersten int im 2D-Array (man haette auch &my_array[0][0] schreiben koennen). Die Funktion muss dann selber Indexberechnungen durchfuehren und hat nicht mehr die schicke Arraysyntax.



  • Harray19085 schrieb:

    Was ist denn eigentlich nun die Lösung??

    In C++? Meiner Meinung nach Matrix-Klassen und Views.



  • SeppJ schrieb:

    Wenn du eine Funktion

    void foo(int bar[][])
    

    hast, ist das nur eine andere Schreibweise fuer

    void foo(int **bar)
    

    Nein.



  • man kann 2 dimensionale arrays in c++ mit z.B. mit strukturen(also array als "inhalt/bestandteil" der struktur), mit pointern oder mit klassen übergeben...

    einfach so funktioniert das nicht da du dann die rückgabe "überlädst" mit argumenten... also d.h. nur 1 rückgabe... -> alles was dir hilft soetwas "zuerzeugen/zubenutzen" kannst du also verwenden um dein array zurückzugeben...

    meiner meinung nach je nachdem wie du es machen willst und was du machen willst...
    vll auch wie groß dein projekt schon ist und wahrscheinlich noch wird... 🙂


  • Mod

    Bashar schrieb:

    SeppJ schrieb:

    Wenn du eine Funktion

    void foo(int bar[][])
    

    hast, ist das nur eine andere Schreibweise fuer

    void foo(int **bar)
    

    Nein.

    😃 Zu lange keine Arrays mehr benutzt.



  • Ok, vielen Dank für die Antworten. Ich hatte zwar gehofft, dass es in C++ direkter geht, aber ich werde mir die Möglichkeiten mal ansehe, sofern ich was dazu finde. Im Moment habe ich das Array 1D-isiert. Strukturen sind auch nicht schlecht, dann sind die auch mal zu was gut.


  • Mod

    Harray19085 schrieb:

    Strukturen sind auch nicht schlecht, dann sind die auch mal zu was gut.

    Vielleicht solltest du mal ein Buch lesen, das C++ stärker objektorientiert lehrt. 😉
    Diese ganze class- und template-Zeugs ist nämlich sehr, sehr nützlich.


Log in to reply