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 = 4Ist 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 zeigtAlles 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 intDa 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
aoder&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
aoder&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 + xStimmt, 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 ^^)