Dreidimensionale Arrays?



  • Hallo.

    Ich lerne gerade C++ und bin jetzt bei Kapitel 5, wo elementare C-Sachen erläutert werden die ja immer noch sehr wichtig sind. Nun bin ich bei dem Thema "Mehrdimensionale C-Arrays" angekommen und hab da Probleme.

    Ich verstehe irgendwie nicht die Funktionsweise von dreidimensionalen Arrays..
    Ein eindimensionaler Array ist einfach, auch die Zeigerarithmetik dazu.
    Zweidimensionale Arrays kann ich mir einfach per [Zeile][Spalte] merken, nur versteh ich da nicht wie ich per Zeigerarithmetik auf die Elemente zugreifen kann.
    Und bei dreidimensionalen Arrays versteh ich weder, wie und wozu ich die benutzen (Zeile, Spalte und was noch?!), noch wie ich dann per Zeigerarithmetik auf die Elemente zugreifen soll ( ***array gibt array[0][0][0] aus, aber wie gebe ich dann array[1][2][3] aus? Etwa per ***(((matrix+1)+2)+3)? argh 😞 ).
    Kann mir jemand mal bitte erklären wie das geht? Wäre echt nett 🙂

    Danke schonmal!



  • Warum willst du deine Array mit Zeigerarithmetik verunstalten? In der Regel ist man froh, dass man Zeiger dadurch vereinfachen kann, indem man sie als Feld betrachtet.
    Wenn es dir aber hilft, so ist ein mehrdimensionales Feld nur ein verschachteltes Feld, so wie du es auch bei deinen Zeigern betrachten würdest. Sprich int[][][], ist ein Feld aus int[][], welches wiederum ein Feld aus int[] ist und dieses selber ein Feld aus int ist. Mit Zeigern müsstest du jetzt über mehrere Offsets auf die Elemente zugreifen.

    int feld[][][];
    
    int * pos = feld + x * breite_erstes_feld + y * breite_zweites_feld + z;
    


  • Erstmal danke für die Antwort 🙂

    Wie ist das jetzt mit "Ein Feld aus int[][]" gemeint?
    Und wie greife ich jetzt mit deinem Beispiel mit dem Zeiger auf ein Feld "int matrix[5][5][5]" zu? Was meinst du mit "breite_erstes_feld"?
    Und von wollen kann bei Zeigerairithmetik ja nicht die Rede sein, Ich würde das eben nur gerne wissen^^



  • Paul Müller schrieb:

    int feld[][][];
    
    int * pos = feld + x * breite_erstes_feld + y * breite_zweites_feld + z;
    

    So geht es nicht.

    #define X 2
    #define Y 3
    #define Z 4
    
    int feld[X][Y][Z];
    int *pos;
    
    pos = (feld + x * (Y+Z) + y * (Z) + z);
    


  • Incocnito schrieb:

    Erstmal danke für die Antwort 🙂

    Wie ist das jetzt mit "Ein Feld aus int[][]" gemeint?
    Und wie greife ich jetzt mit deinem Beispiel mit dem Zeiger auf ein Feld "int matrix[5][5][5]" zu? Was meinst du mit "breite_erstes_feld"?
    Und von wollen kann bei Zeigerairithmetik ja nicht die Rede sein, Ich würde das eben nur gerne wissen^^

    Wenn ich mich richtig entsinne ging das so: (hab lange nichts mehr mit "3D-Pointern" gemacht 😃

    int main()
    {
      int matrix[5][5][5];
    
      *(*(*(matrix + 1) + 1) + 1) = 3;
      printf("%i", matrix[1][1][1]);
    
      return 0;
    }
    


  • So kannst du dir ein dreidimensionales Feld im Speicher vorstellen.
    http://img191.imageshack.us/i/3dfeld.png/, zum Beispiel int feld[3][3][3]. Um jetzt das Feld genau in der Mitte zu adressieren ([1][1][1]), gehst du also wie folgt vor:

    breite_erstes_feld = 9; /* 3*3 */
    breite_zweites_feld = 3; 
    
    feld + 1 * breite_erstes_feld + 1 * breite_zweites_feld + 1;
    => 1 * 9 + 1 * 3 + 1 = 13
    

    Hier ist es also wichtig zu wissen, in welcher Reihenfolge die Felder ineinander verschachtelt werden. Das werden dir aber sicher die Standardauswendiglerner sagen können.



  • Richtig der Zugriff ist falsch bei mir. Die Idee sollte aber recht einfach anhand der Grafik zu erkennen sein. Du holst dir wie gewohnt das innerste Feld aus dem Würfel über einen zweidimensionalen Zugriff. pos = Y * Breite + X; und aus dem gewonnenen Feld über Z das entsprechende Element zu holen, sollte keine weiteren Schwierigkeiten machen.



  • Korrektur

    #define X ...
    #define Y ...
    #define Z ...
    
    int feld[X][Y][Z];
    int *pos;
    
    pos = (feld + x * (Y*Z) + y * (Z) + z); // es ist (Y mal Z)
    

    Bei X=2, Y=3, Z=4

    000 001 002 003  010 011 012 013  020 021 022 023  100 101 102 103  110 111 112 113  120 121 122 123 
                     | 4=0*(Y*Z)+1*Z  | 8=0*(Y*Z)+2*Z  | 12=1*(Y*Z)+0*Z | 16=1*(Y*Z)+1*Z
    

Anmelden zum Antworten