Frage

, wenn die zweidimensionale Anordnung erklärt

int random[height][width];

und dann in einer Funktion mit

void populate(int random[height][width], int x, int y)

gibt die Fehler variabler Größe Art außerhalb einer Funktion deklariert. Ich weiß, ich mache etwas falsch, und dass sie etwas klein. Ich habe nur ein schlechtes Gedächtnis ...

War es hilfreich?

Lösung

Ich werde jetzt intensivieren und zu Ihnen sagen, dass mehrdimensionale Arrays das Gehirn Aufwand in C oder C ++ nicht wert sind. Sie sind viel besser eindimensionalen Arrays (oder, besser noch, Standardcontainer) und das Schreiben eine Indizierungsfunktion:

inline int index (int x, int y)
{
  return x + y * width;
}

Jetzt für Ihr Problem. C ++ unterstützt keine C99 variabler Länge Arrays. Der Compiler muss wissen, bei der Kompilierung, die Größe des Arrays. Die folgende, zum Beispiel, wird nicht funktionieren.

int dim = 4;
int ar[dim];

Wenn dim const wären, würde es funktionieren, weil der Compiler genau zu sagen, wäre in der Lage, wie breit ar sein sollte (weil der Wert von dim nicht ändern würde). Dies ist wahrscheinlich das Problem, das Sie stoßen.

Wenn Sie die Größe zu ändern, bei der Kompilierung-Zeit in der Lage sein wollen, müssen Sie etwas schwieriger zu tun, wie eine Templat-Referenz schreiben. Sie können nicht einen Zeiger für mehrdimensionale Arrays wegen der Art und Weise verwenden sie in C / C ++ angelegt sind. Ein Templat-Beispiel, wie die folgenden Abbildungsfehler aussehen:

template <int Width, int Height>
void populate(int (&(&random)[Width])[Height], int x, int y);

Das ist hässlich.

Für Laufzeit, müssen Sie new verwenden, um Daten zu verteilen, oder einen Containertyp verwenden.

Andere Tipps

Sie können das Array mit nicht-konstanten Abmessungen (Breite, Höhe) außerhalb der Funktion definieren, das ist - nicht in dem Stapelrahmen, da die Abmessungen nicht zur Übersetzungszeit bekannt sind. Sie würden verwenden Konstanten haben oder dynamisch zuweisen (entweder in Haufen oder im Stapelrahmen).

Wenn ein Array direkt als Parameter einer Funktion übergeben wird (mit nach Wert) Es zerfällt in einen Zeiger auf das erste Element des Arrays. Auch wenn Sie eindeutig in der Signatur der Dimensionen des Arrays lesen können, werden diese Dimensionen vom Compiler ignoriert. Dieses Verhalten ist kompatibel mit C.

C ++ Sie das Array als Verweis übergeben können und das wäre kein Problem mehr sein.

int extract_value( int (&a)[10][10], int row, int col ) {
   return a[row][col];
}
int main() {
   int a[10][10] = {};
   a[5][5] = 1;
   std::cout << extract_value( a, 5, 5 ) << std::endl;
   int b[5][5];
//   extract_value( b, 2, 2 ); // error: the function takes an array of 10x10
}

Die Funktion Parameter müssen genau übereinstimmen, das heißt, es nur eine Reihe von 10x10 Elementen nimmt. Sie können Templating die Funktion auf den Array-Größen rid diese Beschränkung nehmen. Sobald man es auch die Art ist:

template <typename T, int Rows, int Cols>
T extract_value( T (&a)[Rows][Cols], int row, int col ) {
   return a[row][col];
}
int main() {
   int a[5][7] = {};
   extract_value( a, 3, 4 );
   int b[8][2] = {};
   extract_value( b, 7, 1 ); // correct, the compiler matches sizes
   double c[4][4] = {};
   extract_value( c, 2, 2 ); // different types are allowed
}

Diese Lösung wird noch umständlich, dass die Größen Zeitkonstanten kompilieren werden müssen, und das Array muss zugeordnet Stapel werden. Die Lösung hierfür ist eine Klasse definiert, die in einem Puffer (linear) dynamischen Speicher nimmt und eine Umwandlung von der N-Koordinatensystem in das 1-dimensionale Feld Wert zu erhalten, wie es zuvor vorgeschlagen wurde. Sie können einige Hinweise bekommen, wie es in diesem zu tun FAQ über Überladen von Operatoren, die eine Implementierung einer 2D-Matrix zur Verfügung stellen. Sobald Sie das umgesetzt haben, können Sie nur verwenden, die als Parameter an Funktionen / Methoden.

Meine Empfehlung diesem letzten Weg zu folgen sei: die N-dimensionalen Array in eine Klasse kapseln, die Umwandlungen in einen 1D-Vektor liefert (die C ++ FAQ lite verwendet einen Rohzeiger, ziehe ich STL-Container)

Ich werde mit einem Beispiel verdeutlichen:

// Globals

const int ARRAY_SIZE = 16 struct ArrayType_t arrayType[ARRAY_SIZE];

Auch wenn ARRAY_SIZE als Konstante int deklariert ist es Wert nicht bei der Kompilierung initialisiert wird und damit der Compiler kennt nicht die Größe des Arrays und einen solchen Fehler gibt. Wenn Sie jedoch, dass als Hash definieren #define ARRAY_SIZE 16 struct ArrayType_t arrayType[ARRAY_SIZE] ===> Das funktioniert, weil ARRAY_SIZE definiert ist bei Kompilierung und Compiler können die Größe des Arrays bei der Kompilierung kennen.

Sie können so etwas wie folgt verwenden:

void populate(int height, int width, int **random)
{
    //here you can work from random[0][0] to random[height][width]
}

, dann können Sie es wie folgt verwendet werden:

int main()
{
    int height=10;
    int width=20;
    int **myarray = new int*[height];
    for( int i=0; i< height; i++ ) myarray[i] = new int[width];
    populate( height, width, myarray);
}

, aber natürlich werden Sie für Pufferüberlauf achten müssen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top