2009-09-16 5 views
1

lors de la déclaration de la matrice bidimensionnelletype à taille variable déclarée en dehors de toute fonction

int random[height][width]; 

et ensuite l'utiliser dans une fonction

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

donne l'erreur type à taille variable déclarée en dehors de toute fonction. Je sais que je fais quelque chose de mal, et que c'est quelque chose de petit. J'ai juste une mauvaise mémoire ...

Répondre

4

Je vais maintenant m'étendre et vous dire que les tableaux multidimensionnels ne valent pas l'effort cérébral en C ou en C++. Vous êtes beaucoup mieux à l'aide des tableaux simples dimensions (ou, mieux encore, des conteneurs standard) et l'écriture d'une fonction d'indexation:

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

Maintenant, pour votre problème. C++ ne prend pas en charge les tableaux de longueur variable C99. Le compilateur doit connaître, au moment de la compilation, la taille du tableau. Ce qui suit, par exemple, ne fonctionnera pas.

int dim = 4; 
int ar[dim]; 

Si dim étaient const, cela fonctionnerait parce que le compilateur serait en mesure de dire exactement la largeur ar devrait être (car la valeur de dim ne changerait pas). C'est probablement le problème que vous rencontrez.

Si vous voulez pouvoir modifier la taille au moment de la compilation, vous devrez faire quelque chose de plus difficile, comme écrire une référence basée sur un modèle. Vous ne pouvez pas utiliser de pointeur pour les tableaux multidimensionnels en raison de leur disposition en C/C++. Un exemple de modèle peut ressembler à l'aberration suivante:

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

Ceci est moche.

Pour l'exécution, vous devez utiliser new pour allouer des données ou utiliser un type de conteneur.

+0

J'ai depuis changé les dimensions du tableau en constantes, et je reçois toujours l'erreur. – Mike

+0

Mike, je pense qu'il serait plus utile si vous pouviez publier le code minimal que les erreurs sur le compilateur. Parce que 'int random [25] [80]' semble parfaitement légal. –

+0

coppro, comment votre modèle aide-t-il à modifier les dimensions * lors de l'exécution *? ;-) –

1

Vous ne pouvez pas définir le tableau avec des dimensions non constantes (largeur, hauteur) en dehors de la fonction, c'est-à-dire - pas dans le cadre de la pile, car les dimensions ne sont pas connues à la compilation. Vous auriez besoin d'utiliser des constantes ou de l'allouer dynamiquement (soit dans le tas, soit dans le cadre de la pile).

-1

Vous pouvez utiliser quelque chose comme ceci:

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

alors vous pouvez l'utiliser comme ceci:

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); 
} 

mais, bien sûr, vous devrez surveiller des trop-pleins tampon

+0

Non, vous ne pouvez pas passer un tableau multidimensionnel comme '**'. Vous devez avoir un tableau de pointeurs à cette fin. –

+0

C'est correct, édité mon message ... – Vargas

1

Lorsqu'un tableau est transmis directement en tant que paramètre à une fonction (valeur de passage), il se désintègre en un pointeur vers le premier élément du tableau. Même si vous pouvez lire clairement dans la signature les dimensions du tableau, ces dimensions sont ignorées par le compilateur. Ce comportement est compatible avec C.

En utilisant C++ vous pouvez transmettre le tableau par référence et ce ne serait plus un problème.

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 
} 

Le paramètre function doit correspondre exactement, c'est-à-dire qu'il ne prend qu'un tableau de 10x10 éléments.Vous pouvez supprimer cette restriction en configurant la fonction sur les tailles de tableau. Une fois que vous y êtes aussi le type:

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 
} 

Cette solution est encore lourde en ce que les dimensions doivent être compiler des constantes de temps, et le tableau doit être alloué stack. La solution consiste à définir une classe qui prend la mémoire dynamique dans un tampon (linéaire) et qui a une conversion du système de coordonnées N dans le tableau à une dimension pour obtenir des valeurs, comme cela a été suggéré précédemment. Vous pouvez obtenir quelques conseils sur la façon de le faire dans ce FAQ sur la surcharge de l'opérateur qui fournit une implémentation d'une matrice 2D. Une fois que vous avez implémenté cela, vous pouvez simplement utiliser cela comme paramètre pour les fonctions/méthodes. Ma recommandation serait de suivre ce dernier chemin: encapsuler le tableau N-dimensional dans une classe qui fournit des conversions dans un vecteur 1D (la FAQ C++ FAQ utilise un pointeur brut, je préfère les conteneurs STL).

1

J'illustrerai avec un exemple:

// GLOBALS

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

Même si ARRAY_SIZE est déclarée comme sa valeur int constante n'est pas initialisé au moment de la compilation et donc le compilateur ne connaître la taille du tableau et donne une telle erreur. Toutefois, si vous définissez cela comme un hachage, définissez #define ARRAY_SIZE 16 struct ArrayType_t arrayType[ARRAY_SIZE] ===> cela fonctionne car ARRAY_SIZE est défini à et le compilateur peut connaître la taille du tableau au moment de la compilation.

Questions connexes