Multidimensionale Arrays



  • Hi,

    ich habe einen fest codierten array der ungefähr so aussieht:

    float a[2][2] = {{1,2}, {3,4}};
    

    Nun würde ich gerne den Array einer anderen Variable übergeben.
    Z.B. so:

    float b[2][2] = a;
    

    Ich habe schon einige sachen ausprobiert aber bekomme es nicht hin.
    Kann mir jemand sagen wie man das korrekt macht?

    Viele Grüße



  • Schau mal hier http://de.wikibooks.org/wiki/C-Programmierung:_Zeiger
    im Abschnitt "Unterschied zwischen Call by Value und Call by Reference" bei dem Beispiel mit dem swap.



  • Der Unterschied ist mir klar, glaube ich 😉

    Naja jedenfalls komme ich nicht wirklich auf die Lösung.
    Möchte ich z.B. einen Zeiger auf einen einzelnen Float machen, sieht das ja so aus:

    float a = 5.0f;
    float* b = &a;
    

    Wenn ich nun versuche das auf mein Beispiel mit 2D Arrays zu abstrahieren, komme ich auf so etwas:

    float a[2][2] = {{1,2}, {3,4}};
    float*** b = (float***)&a;
    

    Kompilieren tut er, aber es gibt dann einen Speicherlesefehler wenn ich z.B. so darauf zugreifen will:

    printf("%f\n", (*b)[0][0]);
    

    Also ich habe da wahrscheinlich einen ziemlichen Denkfehler drin, aber ich sehe ihn einfach nicht.
    Kann mich jemand mal aufklären? 🙂



  • Der Denkfehler: der Typ des Arrays ist float(*)[2] (Array auf Array mit 2 Dimensionen) und nicht float** (Array auf Zeiger). Wenn du eine Variable letzteren Types hast und diese mit b[0][0] dereferenzierst, macht der Compiler daraus *(*(b+0)+0) , also **b . Der erste Eintrag des Arrays wird also als Zeiger interpretiert. Richtig wäre aber *(b+0*2+0) , wie es auch beim Typ float(*)[2] gemacht wird (deshalb braucht der Compiler auch im Typen alle Dimensionen außer der ersten, sonst kann er die Dereferenzierung nicht durchführen.

    Übrigens kannst du auch eine Referenz anlegen:

    float (&b)[2][2]
    

    Wenn du Kopiersemantik brauchst siehe dir boost::array (oder std::tr1::array oder std::array) an.



  • Ok, is ganzschön verwirrend mit den Zeigern.

    Also wenn ich den typen wieder zurückcaste zu "float ()[2][2]" statt "float**" dann macht es der compiler richtig:

    float a[2][2] = {{1,2}, {3,4}};
    float*** b = (float***)&a;
    printf("%f\n", ***((float (*)[2][2])b));
    
    float (&b)[2][2]
    

    Das ist natürlich die wesentlich elegantere und verständlichere Lösung 😉

    Danke für die Hilfe.



  • Wenn dir die Schreibweise zu kompliziert ist, kannst du dir ja auch ein typedef machen 😉
    Aber auf Dauer würde ich so komplizierte Konstrukte sowieso nicht verwenden( klar zum üben mal, man muss es ja schon mal gemacht haben und kennen ), sondern probiere es anderster zu lösen, mit Vektoren zum Beispiel. Außer es geht natürlich nicht anders aus irgendeinem Grund.

    Lg freeG


Anmelden zum Antworten