Frage zu Mehrdimensionale arrays



  • Genau. Der Speicher eines Arrays hängt an einem Stück, der Zugriff auf einzelne Positionen wird mit start + sizex * x + y berechnet. Deswegen gibt das hier auch einen Compilerfehler:

    void foo(int **a);
    
    int main()
    {
      char a[2][3];
      foo(a); // Autsch.
    }
    


  • cooky451 schrieb:

    der Zugriff auf einzelne Positionen wird mit start + sizex * x + y berechnet.

    start + sizex * x + y

    int a[3][4]; // x = 3, y = 4
    

    Ist das so gemeint: (start + sizex) * (x+y) == (Startadresse + 3) * (3+4)

    Vielen Dank für deine Hilfe cooky451! 😃



  • Nja, das war so gemeint:

    char a[5][5];
    a[3][1] = 'c'; // Adresse wird errechnet durch a + 3 * 5 + 1
    


  • cooky451 schrieb:

    start + sizex * x + y

    Das stimmt so aber nicht.

    cooky451 schrieb:

    Nja, das war so gemeint:

    char a[5][5];
    a[3][1] = 'c'; // Adresse wird errechnet durch a + 3 * 5 + 1
    

    ⚠ Das * 5 ist die zweite 5 von a[5][5]?

    Bei feld[maxy][maxx]; berechnet sich der Offset durch maxx * y + x

    @zeiger->
    Die Arrayelemente stehen so im Speicher, wie du es auch bei der Definition hingeschrieben hast:

    int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
             |
    Diese 3  +-----------------+ ist die selbe Zahl
                               |
    a[1][2] ist dann *(a + 1 * 3 + 2)  = *(a+5)
    


  • zeiger-> schrieb:

    Folgendes Beispiel:

    int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
    
    cout << a[0] << endl;    // Zeiger welcher auf die erste Adresse zeigt
    cout << &a[0] << endl;   // Adresse der Zeigers
    cout << *a[0] << endl;   // Adresse wird dereferenziert auf den der Zeiger zeigt
    

    Alles falsch.

    Ausdruck   Was das ist                Implizit konvertierbar zu
    ---------------------------------------------------------------
      a[0]     Lvalue vom Typ int[3]      Adresse vom Typ int* (array to pointer decay)
     &a[0]     Rvalue vom Typ int(*)[3]
     *a[0]     Lvalue vom Typ int
    

    Da Postfixoperatoren stärker binden ist &a[0] äquivalent zu &(a[0]), *a[0] äquivalent zu *(a[0]). Hier steht auf der rechten Seite ein Lvalue-Ausdruck vom Typ int[3]. Der Dereferenzierungsoperator will aber eine Adresse haben. Daher findet hier ein array-to-pointer decay statt wobei die Adresse des ersten Elements des Arrays genommen wird. Diese ist hier vom Typ int*. Der Dereferenzierungsoperator nimmt diese Adresse und gibt uns wieder ein Lvalue vom Typ int -- also etwas, was sich auf a[0][0] bezieht.

    Anders formuliert: Falls x ein Zeiger oder ein Array ist, ist x[0] dasselbe wie *x. Deswegen kannst Du *a[0] umschreiben zu a[0][0].



  • DirkB schrieb:

    Die Arrayelemente stehen so im Speicher, wie du es auch bei der Definition hingeschrieben hast:

    int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
             |
    Diese 3  +-----------------+ ist dieselbe Zahl
                               |
    a[1][2] ist dann *(a + 1 * 3 + 2)  = *(a+5)
    

    Das ist nicht ganz richtig. a zerfällt zu int()[3] und nicht int. Hier musst Du natürlich bei der Zeigerarithmetik darauf achten. Es müsste heißen

    a[1][2] ist dann *(&a[0][0] + 1 * 3 + 2)  = *(&a[0][0]+5)
    


  • krümelkacker schrieb:

    ...

    Ob du a oder &a[0][0] nimmst, ist egal, da beide auf das erste Element zeigen. Bei DirkB hat nur der *-Operator gefehlt:

    *(*arr + 1 * 3 + 2) == *(&arr[0][0] + 1 * 3 + 2)
    


  • [Rewind] schrieb:

    krümelkacker schrieb:

    ...

    Ob du a oder &a[0][0] nimmst, ist egal,

    Nein, ist es nicht.
    a+n ist nicht äquivalent zu &a[0][0]+n
    weder vom Typ her, noch vom rohen Adresswert bei beliebigen n.
    Muss ich Dir Zeigerarithmetik erklären?



  • DirkB schrieb:

    cooky451 schrieb:

    start + sizex * x + y

    Das stimmt so aber nicht.

    cooky451 schrieb:

    Nja, das war so gemeint:

    char a[5][5];
    a[3][1] = 'c'; // Adresse wird errechnet durch a + 3 * 5 + 1
    

    ⚠ Das * 5 ist die zweite 5 von a[5][5]?

    Bei feld[maxy][maxx]; berechnet sich der Offset durch maxx * y + x

    Stimmt, ich wollte schreiben: start + sizey * x + y. (Für a[sizex][sizey] und a[x][y])



  • Herzlichen Dank für eure Erklärungen...
    Diese Zeiger sind echt ne Sache für sich (am Anfang ^^) 🙄


Anmelden zum Antworten