BobWheeler
Anmeldungsdatum: 26. September 2006
Beiträge: 32
|
Hallo ich weiß, dies ist kein "richtiges" Programmier-forum, aber trotzdem 😉 folgendes Anliegen: ich habe ein 1D-array int *array; dieses wird dann mittels
array = new int[variable]; "variable" ist ein beliebiger int jetzt möchte ich aber ein zweites dreidimensionales (Pointer-) Array welches auf den obigen zeigt, so dass ich dann auf dieses wie folgt zugreifen kann: int a = array3d[wert1][wert2][wert3]; Kann da einer weiterhelfen?
|
Senex
Anmeldungsdatum: 17. September 2007
Beiträge: 88
|
Google beispielsweise: Wenn du deinen Thread-Titel bei google eingibst, kriegst du unter anderem dies hier: http://www.peacesoftware.de/ckurs8.html wo der Gebrauch von mehrdimensionalen Arrays erläutert wird. Gruß,
Ich
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
BobWheeler schrieb: ich weiß, dies ist kein "richtiges" Programmier-forum
Was denn dann? Ein falsches Programmierforum? Und zum eigentlichen Problem: C kennt keinen new-Operator, ich nehme an, Du sprichst von C++. Außerdem ist die Variable array kein Array, sondern ein Pointer. Zwischen Pointern und Arrays besteht ein fundamentaler Unterschied, den jeder C++-Programmierer verstanden haben sollte. Das ganze ist hier ganz gut erklärt.
|
ryiden
Anmeldungsdatum: 2. Juni 2006
Beiträge: 826
Wohnort: Mos Eisley
|
BobWheeler schrieb: ich habe ein 1D-array
int *array;
Das ist kein Array, sondern ein Zeiger.
dieses wird dann mittels array = new int[variable];
Du verwendest den new-Operator, bist Du sicher dass Du nicht C++ programmierst?
jetzt möchte ich aber ein zweites dreidimensionales (Pointer-) Array welches auf den obigen zeigt
Es gibt keine Pointer-Arrays, weder in C noch in C++.
Kann da einer weiterhelfen?
In C sowie in C++ kannst Du folgende Lösung verwenden:
// 3x3-Matrix
int matrix[3][3];
matrix[0][0] = 5; Ein mehrdimensionales Array mit variabler Feldgröße kannst du in C++ folgendermaßen implementieren:
// 3x3-Matrix erzeugen
int **matrix = new int*[3];
for (int i = 0; i < 3; i++)
{
matrix[i] = new int[3];
} Doch wer in C++ dynamisch Speicher erzeugt, muss diesen auch wieder freigeben. Daher gehört zu jedem new auch immer ein delete.
// Speicher der 3x3-Matrix freigeben
for (int i = 0; i < 3; i++)
{
delete[] matrix[i];
}
delete[] matrix; PS: Ich würde Dir zu Lösung 1 raten, da dort keine Zeigerarithmetik verwendet wird, eine Begründung dafür findest im Abschnitt Nachteile und Gefahren auf http://de.wikipedia.org/wiki/Zeiger_(Informatik).
|
BobWheeler
(Themenstarter)
Anmeldungsdatum: 26. September 2006
Beiträge: 32
|
Hello World schrieb: Und zum eigentlichen Problem: C kennt keinen new-Operator, ich nehme an, Du sprichst von C++. Außerdem ist die Variable array kein Array, sondern ein Pointer. Zwischen Pointern und Arrays besteht ein fundamentaler Unterschied, den jeder C++-Programmierer verstanden haben sollte. Das ganze ist hier ganz gut erklärt.
Die Theorie dahinter habe ich verstanden. Mir ist klar, dass es ein Pointer ist, aber ich drücke mich teils unklar aus :/
Nun, und das ich die Theorie verstanden habe, heisst nicht das ich den Umgang mit Pointern verinnerlicht habe XD Habe zuvor meist in Java programmiert und in C/C++ meist auf Zeiger verzichtet... Und wegen C/C++: ja, das oben ist C++. Habe aber die (dumme) Angewohnheit C und C++ zu vermischen... Der Link oben ist gut, danke dafür ryiden schrieb: jetzt möchte ich aber ein zweites dreidimensionales (Pointer-) Array welches auf den obigen zeigt
Es gibt keine Pointer-Arrays, weder in C noch in C++.
http://www.netzmafia.de/skripten/ad/thomas-c/zeiger.html das Wort ist nur haften geblieben 😉 Ein mehrdimensionales Array mit variabler Feldgröße kannst du in C++ folgendermaßen implementieren:
// 3x3-Matrix erzeugen
int **matrix = new int*[3];
for (int i = 0; i < 3; i++)
{
matrix[i] = new int[3];
} Doch wer in C++ dynamisch Speicher erzeugt, muss diesen auch wieder freigeben. Daher gehört zu jedem new auch immer ein delete.
// Speicher der 3x3-Matrix freigeben
for (int i = 0; i < 3; i++)
{
delete[] matrix[i];
}
delete[] matrix;
Vielen Dank schonmal ☺ ich brauche genau das: ein mehrdimensionales Array mit variabler Feldgröße. Nur eben für eine 3x3x3-Matrix (z.B.) wünschenswert wäre folgendes, ein Beispiel für ein 2D-Array (z.B. "3x3"): | int zeilen, spalten;
int *array;
int **array2d;
array = new int[zeilen*spalten];
array2d = new int*[zeilen];
for(i=0; i<zeilen; i++)
array2d[i] = &(array[i*spalten]);
|
Dann wäre
| array[my*zeilen+mx] == array2d[mx][my]
|
und sowas ähnliches bräuchte ich für ein 3D-Array (z.b. "3x3x3"), also quasi ein array3d[][][]
|
freebirth_one
Anmeldungsdatum: 19. Juli 2007
Beiträge: 5051
Wohnort: Mönchengladbach
|
Also, was dein Problem angeht, da kann ich dir leider nicht helfen (wir hatten sowas auch mal mit dynamischen Arrays, aber da ist laaaaange her.ICh glaube, wir haben das schließlich mit linked Lists realisiert). Allerdings habe ich ein kurzes Video gefunden, was das Händlicng mit Pointern in verschiedenen Programmiersprachen erläutert (ja, intern arbeitet Java _nur_ mit Pointern resp. Refernzen. Nur dass das nach aussen hin nicht ersichtlich wird.) –> Binky Pointer Fun.
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
Ich mach sowas immer mit nem Zeiger. Für den hol ich mir x*y*z*sizeof(typ) Speicher mit malloc (new in C++) und dann schreib ich mir ne Adressierungsfunktion.
|
BobWheeler
(Themenstarter)
Anmeldungsdatum: 26. September 2006
Beiträge: 32
|
habe es jetzt so und es läuft ☺ 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | int i,j;
int dim_x, dim_y, dim_z;
int*** array3d = new int**[dim_x];
int** array_tmp = NULL;
int* array = NULL;
for (i = 0; i < dim_x; i++) {
array_tmp = new int*[dim_y];
for (j = 0; j < dim_y; j++) {
array = new int[dim_z];
array_tmp[j] = array;
}
array3d[i] = array_tmp;
}
|
ich lasse das thema mal noch geöffnet (als noch nicht gelöst markiert), könnt noch vorschläge posten (ob und wie es besser geht z.b.) danke an alle! *EDIT*
→ gelöst
|
ryiden
Anmeldungsdatum: 2. Juni 2006
Beiträge: 826
Wohnort: Mos Eisley
|
BobWheeler schrieb: http://www.netzmafia.de/skripten/ad/thomas-c/zeiger.html#8.6
das Wort ist nur haften geblieben
Lustig wie sie das Pointer-Array nennen. ich brauche genau das: ein mehrdimensionales Array mit variabler Feldgröße. Nur eben für eine 3x3x3-Matrix (z.B.)
Funktioniert eigentlich analog zu meinem Beispiel für das 2D-Array, nur eben mit einer weiteren verschachtelten Schleife.
// Array erzeugen
int ***array3d = new int**[3];
for (int i = 0; i < 3; i++)
{
array3d[i] = new int*[3];
for (int j = 0; j < 3; j++)
{
array3d[i][j] = new int[3];
}
} // Werte setzen
array3d[0][0][0] = 1;
array3d[0][0][1] = 2;
// Werte ausgeben
cout << array3d[0][0][0] << endl;
cout << array3d[0][0][1] << endl; // Speicher freigeben
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
delete[] array3d[i][j];
}
delete[] array3d[i];
}
delete[] array3d; habe es jetzt so und es läuft ☺ 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | int i,j;
int dim_x, dim_y, dim_z;
int*** array3d = new int**[dim_x];
int** array_tmp = NULL;
int* array = NULL;
for (i = 0; i < dim_x; i++) {
array_tmp = new int*[dim_y];
for (j = 0; j < dim_y; j++) {
array = new int[dim_z];
array_tmp[j] = array;
}
array3d[i] = array_tmp;
}
|
In Zeile 3 verwendest du die Variable dim_x, ohne sie vorher initialisiert zu haben. Wozu der ganze Aufwand mit den tmp-Variablen? Ich finde, das macht das ziemlich unübersichtlich.
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
Wenn Du schon C++ verwendest, dann mache auch sinnvollen Gebrauch von der Standardbibliothek. Eine Möglichkeit für zweidimensionale Arrays ist bspw.
| #include <vector>
typedef std::vector<int> intvec;
std::vector<intvec> x(20, intvec(20));
|
Das geht theoretisch auch für drei- oder gar vierdimensionale Arrays, aber wenn ich so etwas verwende, würde ich dann eher zu boost.MultiArray greifen.
|
Kinch
Anmeldungsdatum: 6. Oktober 2007
Beiträge: 1261
|
Na ja, ob der Einsatz eines vectors so viel sinnvoller ist, wenn man die Element-Anzahl, bzw. die Dimension schon vorher kennt? Ich vermute einfach mal, dass ein Array etwas perfomanter ist; zumindest wenn man die Funktionen für einen vector nicht braucht.
|
e1bart0
Anmeldungsdatum: 12. Mai 2007
Beiträge: 927
Wohnort: München
|
Kinch schrieb: Na ja, ob der Einsatz eines vectors so viel sinnvoller ist, wenn man die Element-Anzahl, bzw. die Dimension schon vorher kennt?
BobWheeler schrieb: ein mehrdimensionales Array mit variabler Feldgröße.
(Hervorhebung von mir.) Das heisst für mich, dass er nicht die Anzahl der Elemente kennt, und deshalb dynamisch Elemente (oder Dimensionen) hinzufügen will, was den Einsatz eines vector s rechtfertigen würde.
|
Kinch
Anmeldungsdatum: 6. Oktober 2007
Beiträge: 1261
|
Er kennt die Anzahl der Element zur Compiler-Zeit nicht, aber, so wie ich es sehe, doch zur Laufzeit, oder? Ich habe es jedenfalls so verstanden, dass er zu einem Zeitpunkt im Programmablauf sagen kann, dass er nicht mehr als n Element benötigt wird und demnach genauso viel Speicher alloziert.
|
ryiden
Anmeldungsdatum: 2. Juni 2006
Beiträge: 826
Wohnort: Mos Eisley
|
Kinch schrieb: Na ja, ob der Einsatz eines vectors so viel sinnvoller ist, wenn man die Element-Anzahl, bzw. die Dimension schon vorher kennt? Ich vermute einfach mal, dass ein Array etwas perfomanter ist; zumindest wenn man die Funktionen für einen vector nicht braucht.
Da die vector-Klasse selbst auch als dynamisches Array implementiert ist, dürfte sich an der Performance nichts ändern (siehe http://www.cplusplus.com/reference/stl/vector/). Der Einsatz eines vectors ist soweit sinnvoll, da der Umgang mit ihm keine Zeigerarithmetik erfordert. Die Nachteile von Zeigerartihmetik hatte ich bereits verlinkt. PS: Ich muss sagen Hello World hat da wirklich eine elegante Lösung eingebracht.
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
ryiden schrieb: Kinch schrieb: Na ja, ob der Einsatz eines vectors so viel sinnvoller ist, wenn man die Element-Anzahl, bzw. die Dimension schon vorher kennt? Ich vermute einfach mal, dass ein Array etwas perfomanter ist; zumindest wenn man die Funktionen für einen vector nicht braucht.
Da die vector-Klasse selbst auch als dynamisches Array implementiert ist, dürfte sich an der Performance nichts ändern (siehe http://www.cplusplus.com/reference/stl/vector/).
Sobald der vector einmal erstellt ist, stimmt das. Allerdings muss zunächst Speicher für den vector allokiert werden, und das kostet etwas Zeit. Wenn die Größe des Arrays zur Compile-Zeit bekannt ist, kann man ein std::tr1::Array verwenden. Das ist ein Wrapper für primitive Arrays, der ihnen das Interface eines STL-Containers verpasst.
Der Einsatz eines vectors ist soweit sinnvoll, da der Umgang mit ihm keine Zeigerarithmetik erfordert, die Nachteile von Zeigerartihmetik hatte ich bereits verlinkt.
Die Semantik eines std::vector<T>::iterator ist so definiert, dass sie genau der eines Zeigers entspricht (manchmal ist dieser Typ sogar einfach als T* definiert). Deswegen wird z. B. ein Iterator ungültig, wenn man vector<T>::resize aufruft. Unter Umständen muss beim resize neuer Speicher allokiert und der Inhalt verschoben werden. der Iterator zeigt dann aber noch auf den alten, freigegebenen Speicher. Dabei heraus kommt nichts anderes als ein sog. hängender Zeiger, der nicht auf eine gültige Stelle im Speicher zeigt. Ähnliche Probleme gibt es auch bei vielen anderen Iterator-Typen in der STL, und das ist eine direkte Folge des kompromisslos auf Effizienz ausgelegten Designs der STL. Die Collections im Qt4-Framework (mit new Style-Iteratoren) sind einfacher und sicherer zu benutzen, dafür aber eben ein wenig langsamer.
|