Frage zu Mehrdimensionale arrays
-
Hallo...
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 zeigtWenn ich das so ausgebe bekomme ich folgende Werte,
0x28cd00
0x28cd00
1Was ich nicht verstehe: Der Wert des Zeiger ist 0x28cd00, das ist jedoch seine eigene Adresse
und wenn ich diese Adresse dereferenziere bekomme ich aber plötzlich den Wert 1... ich dachte aber das der Inhalt dieser Speicheradresse 0x28cd00 ist...Bin verwirrt

Bitte um Hilfe

-
Du hast dort keinen Pointer im eigentlichen Sinne definiert, sondern ein Array. Und jetzt überleg mal, wie dein Array im Speicher wohl aussieht und warum a[0] == &a[0].

-
Danke für deine Antwort!

Kann es sein das a[0] nicht wirklich eine Adresse besitzt sondern nur eine erhält welche den Anfang des arrays definiert?
-
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 ^^)