Um ein Feld an eine Funktion (vgl. Abschnitt
) zu übergeben,
muß man einen entsprechenden Zeiger übergeben. In einer Dimension
ist das einfach ein Zeiger auf das erste Datenelement, in zwei
Dimensionen ein Zeiger auf ein Feld der passenden (festen)
Anzahl von Elementen. Nur die erste Dimension in der Deklaration
kann dabei entfallen, alle anderen müssen zur Compilezeit
feststehen, damit der Compiler den für die Zeigerarithmetik
nötigen Code erzeugen kann. Dies macht C-Felder sehr unpraktisch im
Gebrauch, wenn variable Dimensionen erforderlich sind.
void f( int b[][30] ) void g( int (*q)[30] ) int b[20][30]; int c[10][30]; int d[15][31]; f(b); g(b); f(c); g(c); // ok f(d); g(d); // errors, since second dimension not ==30
Wir wollen hier kurz auf die dynamische Speicherverwaltung vorgreifen und
eine weitere Technik zur dynamischen Erzeugung mehrdimensionaler
Felder schildern. Der operator new type[N]
gibt einen Zeiger auf das erste Element eines linearen Speicherbereiches
von N Variablen des Typs type zurück. Um ein
zweidimensionales
Feld von, sagen wir, Dimension N
M zu erzeugen, kann man zunächst
einen Speicherbereich von N
M Elementen anfordern. Dann kann man ein
Hilfsfeld von Pointern einrichten, die auf die Positionen der Variablen
a[i][0] verweisen, i
Ein weiterer Zeiger auf die
erste Position dieses Hilfsfeldes kann syntaktisch wie ein zweidimensionales
Feld behandelt werden. Dieser kann dann auch unproblematisch an
Unterprogramme weitergereicht werden und erlaubt damit die Übergabe
dynamisch angelegter Felder.
void f(int **a); // function expecting 2D array
// ...
int nx, ny;
std::cin >> nx >> ny; // read dimensions
int **array; // pointer to first element of
// the 'secondary' array
array = new int *[nx]; // create memory for nx pointers to int
array[0] = new int[nx*ny];
// nx*ny elements in the entire array,
// array[0] is a pointer to the first
// ``row'' of ny elements and equals
// the pointer to the beginning of the
// entire array
for(int i=1; i < ny; i++ )
array[i] = array[0] + i * ny;
// points to i'th segment of ny integers
if ( nx > 23 && ny > 10 )
array[23][10] = 17; // ok if 23 < nx and 10 < ny
f( array ); // OK, array is int **, but subscripting
// behaves as if it were a 2D field
Diese Technik läßt sich für Felder mit beliebig vielen
Indizes anwenden und führt dann zu entsprechend hohem Grad der
verwendeten Zeiger.