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 NM zu erzeugen, kann man zunächst
einen Speicherbereich von NM 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 fieldDiese Technik läßt sich für Felder mit beliebig vielen Indizes anwenden und führt dann zu entsprechend hohem Grad der verwendeten Zeiger.