G
Original erstellt von HumeSikkins:
Hallo,
Es gibt aber mehrere verschiedene Lösungen für dein Problem.
1. Wenn der Speicher nich am Stück sein muss, kannst du ein Array von Zeigern auf Arrays verwenden
int main()
{
const int FirstDim = 4;
const int SecDim = 5;
// 1. Schritt: Dynamische Array von Zeigern anlegen:
int** p2DimArr = new int*[FirstDim];
// 2. Schritt: An jeden Zeiger ein Array hängen
for (int i = 0; i < FirstDim ; i++)
p2DimArr[i] = new int[SecDim];
// mit dem neuen 2-dimensionalen Array arbeiten
p2DimArr[0][0] = 42;
//...
// alles wieder löschen
for (int j = 0; j < FirstDim ; j++)
delete [] p2DimArr[j] ;
delete [] p2DimArr;
}
2. Wenn der Speicher am Stück sein muss, empfiehlt es sich das 2-dimensionale Array auf ein 1-dimensionales abzubilden:
class Simple2DimArr
{
private:
int* pArr;
int Rows, Cols;
public:
Simple2DimArr(int Zeilen, int Spalten)
{
Rows = Zeilen;
Cols = Spalten;
// 2-Dimensionales Array auf 1-Dimensionales abbilden
pArr = new int[Rows * Cols];
}
int* operator[](int Zeile)
{
// Array liegt "zeilenweise" im Speicher
return & pArr[Zeile * Cols];
}
~Simple2DimArr()
{
delete [] pArr;
}
};
int main()
{
Simple2DimArr Arr(2,3);
Arr[0][0] = 42;
}
3. Einen dritten Weg eröffnet die Verwendung von Zeigern auf Felder.
Dieser Weg hat aber den Nachteil, dass nur wenige Leute mit deren Syntax vertraut sind:
int main()
{
// Einen Zeiger auf ein Int-Array mit 5 Elementen anlegen
int (*pArr)[5] = 0;
// Den Zeiger auf ein zweidimensionales Array zeigen lassen.
// Wichtig: Die zweite Dimension muss mit der Array-Größe
// übereinstimmen, mit der der Zeiger deklariert wurde
// pArr = new int [5][2]; wäre z.B. illegal, da ein Zeiger auf ein
// Array mit 5 Elementen nicht in einen Zeiger auf ein Array mit
// 2 Elementen konvertiert werden kann.
pArr = new int[2][5];
pArr[0][0] = 42;
// ...
// Am Ende aufräumen nicht vergessen
delete [] pArr;
}
4. Der Weg für C++ Programmierer: Man verzichtet auf dynamische Arrays und verwendet stattdessen die Container der STL. Für den Anfang reichen vectoren. Wenn etwas schneller werden soll, bieten sich valarrays an:
#include <vector>
using namespace std;
int main()
{
const int FirstDim = 3;
const int SecDim = 2;
vector< vector<int> > My2DimArr(FirstDim);
for (int i = 0; i < FirstDim; i++)
My2DimArr[i].resize(SecDim);
My2DimArr[1][1] = 42;
}
Für den Spezialfall char-Arrays bietet sich die Klasse std::string aus der C++ Standardbibliothek an.
Original erstellt von Dimah:
Eine kleine Ergenzung zu Nr. 4.
#include <vector>
#include <cstddef> // für size_t
using namespace std;
template<typename T>
void resize2DimVector(vector< vector<T> > & vec, size_t FirstDim, size_t SecDim)
{
vec.resize( FirstDim );
for(size_t i = 0; i < FirstDim; ++i)
vec[i].resize( SecDim );
}
template<typename T>
const vector< vector<T> > make_2DimVector(size_t FirstDim, size_t SecDim)
{
vector< vector<T> > vec;
resize2DimVector( vec, FirstDim, SecDim );
return vec;
}
template<typename T>
void resize3DimVector(vector< vector< vector<T> > > & vec, size_t FirstDim, size_t SecDim, size_t ThirdDim)
{
vec.resize( FirstDim );
for (size_t i = 0; i < FirstDim; ++i)
{
vec[i].resize( SecDim );
for (size_t j = 0; j < SecDim; ++j)
vec[i][j].resize( ThirdDim );
}
}
template<typename T>
const vector< vector< vector<T> > > make_3DimVector(size_t FirstDim, size_t SecDim, size_t ThirdDim)
{
vector< vector< vector<T> > > vec;
resize3DimVector( vec, FirstDim, SecDim, ThirdDim );
return vec;
}
int main()
{
vector< vector<int> > My2DimVec = make_2DimVector<int>( 100, 100 );
My2DimVec[47][11] = 13;
resize2DimVector( My2DimVec, 333, 333 );
My2DimVec[222][222] = 1980;
vector< vector< vector<int> > > My3DimVec = make_3DimVector<int>( 100, 100, 100 );
My3DimVec[4][71][1] = 42;
resize3DimVector( My3DimVec, 200, 200, 200 );
My3DimVec[111][111][111] = 1337;
}
Die make_ Funktionen sind nur auf Compilern zu empfehlen die, die named return value Optimierung Beherrschen.