72 votes

c++ array - l'expression doit avoir une valeur constante

J'obtiens une erreur lorsque j'essaie de créer un tableau à partir des variables que j'ai déclarées.

int row = 8;
int col= 8;
int [row][col];

Pourquoi est-ce que je reçois cette erreur :

doit avoir une valeur constante.

0 votes

Qu'attendez-vous int [row][col]; à faire, exactement ?

17 votes

Ne modifiez pas le code de votre question avec le correctif ; cela rend votre question extrêmement confuse pour les futurs lecteurs.

1 votes

@Brian Roach cette question n'est pas traitée. Limitez-vous pour faire une bonne réponse.

69voto

Gunther Fox Points 3990

Lorsque l'on crée un tel tableau, sa taille doit être constante. Si vous voulez un tableau de taille dynamique, vous devez lui allouer de la mémoire sur le tas et vous devrez également le libérer avec la commande delete quand vous aurez terminé :

//allocate the array
int** arr = new int*[row];
for(int i = 0; i < row; i++)
    arr[i] = new int[col];

// use the array

//deallocate the array
for(int i = 0; i < row; i++)
    delete[] arr[i];
delete[] arr;

Si vous voulez une taille fixe, alors ils doivent être déclarés const :

const int row = 8;
const int col = 8;
int arr[row][col];

Aussi,

int [row][col];

ne fournit même pas de nom de variable.

0 votes

De plus, cette solution ne fonctionnera pas pour le code de style C. Je ne pense pas qu'il soit juste de supposer que tout le monde a la liberté d'utiliser C++ :'(

5 votes

@BhupeshPant La question est étiquetée pour C++ donc je ne fais pas de supposition. Quoi qu'il en soit, utiliser le C signifierait simplement que vous malloc au lieu de new un pointeur vers le pointeur : int **arr = (int **)malloc(row * sizeof(int *)); puis le remplir de la même façon, avec une boucle : for (i=0; i<row; i++) { arr[i] = (int *)malloc(col * sizeof(int)); }

27voto

La norme exige que la longueur du tableau soit une valeur calculable au moment de la compilation afin que le compilateur puisse allouer suffisamment d'espace sur la pile. Dans votre cas, vous essayez de définir la longueur du tableau à une valeur qui est inconnue au moment de la compilation. Oui, je sais qu'il semble évident que le compilateur devrait la connaître, mais ce n'est pas le cas ici. Le compilateur ne peut faire aucune supposition sur le contenu des variables non constantes. Donc, allez-y :

const int row = 8;
const int col= 8;
int a[row][col];

MISE À JOUR : certains compilateurs vous permettent de le faire. IIRC, g++ possède cette fonctionnalité. Cependant, ne l'utilisez jamais car votre code ne sera plus portable d'un compilateur à l'autre.

22voto

Mark Ransom Points 132545

Le C++ n'autorise pas les valeurs non constantes pour la taille d'un tableau. C'est simplement la façon dont il a été conçu.

C99 permet à la taille d'un tableau d'être une variable, mais je ne suis pas sûr que cela soit autorisé pour deux dimensions. Certains compilateurs C++ (gcc) le permettent en tant qu'extension, mais vous devrez peut-être activer une option du compilateur pour l'autoriser.

Et j'ai failli le manquer - vous devez déclarer un nom de variable, pas seulement les dimensions du tableau.

1 votes

"mais je ne suis pas sûr que ce soit autorisé pour deux dimensions" -- ça l'est. Pour le C, comme vous l'avez noté, mais pas pour le C++.

0 votes

@hvd, merci pour la clarification. Mon exposition au C pur est malheureusement limitée ces jours-ci.

9voto

sjtupuzhao Points 109

Vous pouvez utiliser #define comme solution alternative, qui n'introduit pas vector et malloc, et vous utilisez toujours la même syntaxe pour définir un tableau.

#define row 8
#define col 8

int main()
{
int array_name[row][col];
}

5voto

arrdem Points 707

Lorsque vous déclarez une variable comme ici

int a[10][10];

vous dites au compilateur C++ que vous voulez que 100 entiers consécutifs soient alloués dans la mémoire du programme au moment de l'exécution. Le compilateur fera alors en sorte que votre programme dispose de cette quantité de mémoire et tout ira pour le mieux dans le meilleur des mondes.

Si toutefois vous indiquez au compilateur

int x = 9001;
int y = 5;
int a[x][y];

le compilateur n'a aucun moyen de savoir de quelle quantité de mémoire vous aurez réellement besoin au moment de l'exécution sans effectuer un grand nombre d'analyses très complexes pour retrouver le moindre endroit où les valeurs de x et y ont changé [le cas échéant]. Plutôt que de prendre en charge de tels tableaux de taille variable, le C++ et le C suggèrent fortement, voire exigent carrément, que vous utilisiez malloc() pour allouer manuellement l'espace dont vous avez besoin.

TL;DR

int x = 5;
int y = 5;
int **a = malloc(x*sizeof(int*));
for(int i = 0; i < y; i++) {
    a[i] = malloc(sizeof(int*)*y);
}

a est maintenant un tableau 2D de taille 5x5 et se comportera de la même manière que int a[5][5]. Comme vous avez alloué manuellement de la mémoire, le C++ et le C exigent que vous la supprimiez aussi manuellement...

for(int i = 0; i < x; i++) {
    free(a[i]); // delete the 2nd dimension array
}
free(a); // delete a itself

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X