Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] 2D Array an Funktion übergeben
Delta 38
07.07.2011, 19:37
Ja, der Titel sollte mein Problem gut beschreiben :D
Also: Ich habe ein 2D Array von Pointern:
unsigned short int mapField[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
<Typ> mapField: unsigned short int*
Matrix:
unsigned short int* map[2][2] = {{mapField, mapField},{mapField, mapField}};
Da ein 2D-Array ein Doppelpointer ist, würde map nun diesem Typen entsprechen:
<Typ>map: unsigned short int***
was mache ich also falsch, wenn ich eine Funktion habe:
void drawMap(unsigned short int*** map)
und sie so aufrufe:
drawMap(map);
Compilerfehler:
cannot convert `short unsigned int* (*)[8]' to `short unsigned int***' for argument `1' to `void prntMapPos(short unsigned int***, int*)'
Gruß Delta
<Typ> mapField: unsigned short int*
Nö. Typ von mapField ist unsigned short int[17]. Das wird manchmal implizit in ein unsigned short int* konvertiert, ist aber nicht das selbe.
Etwas seltsam finde ich, dass du über die Funktion drawMap erzählst, die Fehlermeldung aber beim Aufruf von prntMapPos zustande kommt.
Ich habe nie viel mit C++ gemacht, aber wieso soll *** ein Pointer auf ein 2D Array sein?
Wäre das nicht einfach ein Pointer, auf einen Pointer, auf einen Pointer?
int*** i = &&&5;
Headcool
07.07.2011, 23:48
void drawMap(unsigned short int* blub[2][2])
{
...
}
Zugreifen kannst du dann über (blub[a][b])[c] wenn du ganz nach innen willst, sonst einfach über blub[a][b].
Übergabe einfach mit drawmap(map)
Wenn du Arrays mit Pointer übergibst ist es immer gut zusätzlich die Länge mitzugeben.
Delta 38
08.07.2011, 10:11
Etwas seltsam finde ich, dass du über die Funktion drawMap erzählst, die Fehlermeldung aber beim Aufruf von prntMapPos zustande kommt.
:D naja, die Funktion prntMapPos, tut das gleiche, stammt aber aus einem anderen Projekt ... hab ich wohl übersehen :D
@haddock: Ja eben! So wie ich das Thema Arrays verstanden habe, wird der Name des Arrays auf die Adresse des ersten Elementes aufgelöst. Das würde bedeuten:
int array[] = {1, 2, 3, 4};
int* ptrArray = array
//*ptrArray : 1
array[0] = 10;
// *ptrArray : 10
Bei einem 2Dimensonalen Array würde das, nach meiner Erkenntniss, so aussehen:
int array[2][4] = {{1, 2, 3, 4}{5, 6, 7, 8}};
// array enthält die Adresse eines Arrays, dessen Elemente wiederum eine Adresse auf ein Array enthalten -> Pointer auf einen Pointer
int** ptrArray = array;
Hier gibt es allerdings einen Compilererror ... warum also? Nach der Theorie müsste das doch hinkommen, oder bring ich da was durcheinander?
Was allerdings funktionert ist:
int array[2][4] = {{1, 2, 3, 4}{5, 6, 7, 8}};
// array enthält die Adresse eines Arrays, dessen Elemente wiederum eine Adresse auf ein Array enthalten -> Pointer auf einen Pointer
int* ptrArray = *array; //ptrArray enthält nun die Adresse von array[0][0]
EDIT:
Hier nochmal ein Bild wie ich mir das ganze im Speicher vorstelle:
http://upload.worldofplayers.de/files7/multiArray.png
also Map wäre das 2Dimensionale Array. Es ist ein Pointer auf ein 1 Dimensonales Array, das die Zeilen angibt ( also, *Map zeigt auf die erste Zeile; *(map+1)) zeigt auf die 2. Zeile, etc.)
In diesem 1Dimensionalen Array stehen also die Adresse für die Elemente der Matrix oder des Arrays.
Wenn als der Wert an der Stelle Map einem Pointer auf ein 1Dimensionales Array entspricht, dann lesen sich die Werte der Matrix so:
Map[posY][posX] = *( *(map + posY) + posX);
Das stimmt auch.
Warum kann ich also nicht einen int** auf die Adresse von einem int [][] zeigen lassen?
Ein Array ist ein zusammenhängender Speicherbereich für Elemente gleicher Größe.
Beispiel: ein Array aus 5 Integers:
0 1 2 3 4
[0] [2] [5] [4] [7]
Ein 2-dimensionales Array ist ein Array von 1-dimensionalen Arrays. Insbesondere ist ein 2-dimensionales Array kein Array von Pointern. Ein zweidimensionales Array von integern sieht so aus:
0 1 2 3
[[0][2][5][4][7]] [[1][3][6][5][8]] [[0][1][4][3][6]] [[9][8][2][5][2]]
Alle in diesem Array gespeicherten eindimensionalen Arrays müssen die gleiche Größe haben.
Ein eindimensionales Array von Pointern sieht dagegen so aus:
0 1 2 3 4
[0x20] [0xA4] [0x17] [0x3F] [0x75]
und jeder Eintrag kann auf das erste Element eines Arrays mit anderer Größe zeigen. Verwirrend wird das ganze dadurch, das sich beide Datenstrukturen wie ein zweidimensionales Array behandeln lassen, sie sind aber grundverschieden.
Delta 38
08.07.2011, 13:24
Aber warum hat der Wert an der Stelle Map dann eine Adresse auf ein weiteres Array?
Wenn die Arrays des 2Dimensionalen Arrays im Speicher hintereinanderliegen müsste das ganze doch eine größe von Zeilen*Spalten haben.
Kann ich dann nicht einfach der Funktion einen Pointer auf den ersten Wert übergeben, sowie die größe des Arrays? ( Ich würde praktisch das 2Dimensionale Array in ein 1Dimensionales Array konvertieren.)
http://www.ibiblio.org/pub/languages/fortran/append-c.html
Ich hab' mal ein kleines Programm geschrieben, dass das hoffentlicht verdeutlicht:
#include <iostream>
int main()
{
short int twodim[3][5] = {
{30,31,32,33,34},
{35,36,37,38,39},
{40,41,42,43,44}
};
std::cout << "twodim: " << twodim << "\n\n";
std::cout << "twodim[0]: " << twodim[0] << "\n";
std::cout << "&twodim[0][0]: " << &twodim[0][0] << "\n";
std::cout << "&twodim[0][1]: " << &twodim[0][1] << "\n";
std::cout << "&twodim[0][5]: " << &twodim[0][5] << "\n"; // Dangerous. Don't do this at home.
std::cout << "twodim[1]: " << twodim[1] << "\n";
std::cout << "&twodim[1][0]: " << &twodim[1][0] << "\n";
std::cout << "&twodim[1][1]: " << &twodim[1][1] << "\n";
std::cout << "twodim[2]: " << twodim[2] << "\n";
std::cout << "sizeof twodim[0][0]: " << sizeof twodim[0][0] << "\n";
std::cout << "sizeof twodim[0]: " << sizeof twodim[0] << "\n";
std::cout << "sizeof twodim: " << sizeof twodim << "\n";
short int* onedim[3];
for (int i = 0; i < 3; ++i)
{
onedim[i] = twodim[i]; // implicit cast from short int[5] to short int*
}
std::cout << "sizeof onedim[0][0]: " << sizeof onedim[0][0] << "\n";
std::cout << "sizeof onedim[0]: " << sizeof onedim[0] << "\n";
std::cout << "sizeof onedim: " << sizeof onedim << "\n";
short int* ptr = (short int*)twodim;
std::cout << "sizeof ptr[0]: " << sizeof ptr[0] << "\n";
std::cout << "sizeof ptr: " << sizeof ptr << "\n\n";
for (int i = 0; i < 15; ++i)
{
std::cout << i << ": "
<< *(ptr + i) << " "
<< ptr[i] << " "
<< onedim[i/5][i%5] << " "
<< twodim[i/5][i%5] << "\n";
}
}
Ausgabe (auf meinem Rechner):
twodim: 0xbfa6812a
twodim[0]: 0xbfa6812a
&twodim[0][0]: 0xbfa6812a
&twodim[0][1]: 0xbfa6812c
&twodim[0][5]: 0xbfa68134
twodim[1]: 0xbfa68134
&twodim[1][0]: 0xbfa68134
&twodim[1][1]: 0xbfa68136
twodim[2]: 0xbfa6813e
sizeof twodim[0][0]: 2
sizeof twodim[0]: 10
sizeof twodim: 30
sizeof onedim[0][0]: 2
sizeof onedim[0]: 4
sizeof onedim: 12
sizeof ptr[0]: 2
sizeof ptr: 4
0: 30 30 30 30
1: 31 31 31 31
2: 32 32 32 32
3: 33 33 33 33
4: 34 34 34 34
5: 35 35 35 35
6: 36 36 36 36
7: 37 37 37 37
8: 38 38 38 38
9: 39 39 39 39
10: 40 40 40 40
11: 41 41 41 41
12: 42 42 42 42
13: 43 43 43 43
14: 44 44 44 44
Powered by vBulletin® Version 4.2.2 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.