next up previous contents
Next: Referenzen Up: Zeiger, Zeiger-Feld-Dualität, und Referenzen Previous: Zeiger-Feld-Dualität

Feldvariablenübergabe an Funktionen, dynamische Speicherverwaltung

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$ \times$M zu erzeugen, kann man zunächst einen Speicherbereich von N$ \times$M Elementen anfordern. Dann kann man ein Hilfsfeld von Pointern einrichten, die auf die Positionen der Variablen a[i][0] verweisen, i $ =0..N-1.$ 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.


next up previous contents
Next: Referenzen Up: Zeiger, Zeiger-Feld-Dualität, und Referenzen Previous: Zeiger-Feld-Dualität
© R.Hilfer et al., ICA-1, Univ. Stuttgart
28.6.2002