-1
votes

C ++ Pourquoi les déclarations de tableau de non-const sont-elles mauvaises?

Si j'ai les deux déclarations suivantes:

// OK
const int ARRAYSIZE = 5;
int x[ARRAYSIZE];

// NOT OK
int ARRAYSIZEBAD = 5;
int y[ARRAYSIZEBAD];


7 commentaires

Ce n'est pas mauvais en soi, ce n'est tout simplement pas une fonctionnalité des offres de langue. La taille des choses doit être connue au moment de la compilation, ce qui signifie que vous avez besoin d'une valeur de compilation de la valeur connue pour la taille des matrices.


"Dans quelle situation serait-il préférable d'utiliser une allocation dynamique avec le nouvel opérateur?" Ceci est peut-être une question complètement différente. Connexe mais pas la même que le reste de votre question


En plus de ce que Nathanoliver a dit, si vous souhaitez créer de manière dynamique un tableau comme dans le deuxième exemple, vous pouvez utiliser int * y = neuf int [arysisatebad];


@ user463035818 c'est la même question cependant. Les réponses que je reçoivent est "parce que le compilateur le dit", mais c'est un argument circulaire. De plus, le compilateur GNU n'exige pas si vous avez utilisé le drapeau -ped-Errors.


@ user463035818 YEP C'est une dupe de cette question ...


@Joebass "parce que le compilateur le dit" n'est pas une bonne réponse. Une meilleure réponse est "parce que la langue le dit".


Vous n'avez pas besoin de modifier votre question pour pointer vers le duplicata. Une fois fermé comme dupliquer la question obtient un lien vers le dupe sur le dessus.


4 Réponses :


6
votes

C ++ Pourquoi les déclarations de tableau de non-const sont-elles mauvaises?

Parce que la longueur de la matrice doit être connue au moment de la compilation. Si une variable est non constituée, sa valeur pourrait alors changer au moment de l'exécution et ne serait donc pas connue au moment de la compilation. Seule une expression constante de temps de compilation peut être utilisée comme une longueur d'un tableau - Ainsi, une variable Const ne peut être utilisée que comme une longueur d'une matrice après observation de son initialisateur.

int [arrayate] est un type. L'exigence de la taille de la taille au moment de la compilation s'étend à tous les types que vous instaniez, pas seulement des types de réseau.

Dans quelle situation serait-il préférable d'utiliser une allocation dynamique ...

Vous avez besoin d'une allocation dynamique lorsque vous ne connaissez pas la longueur de la matrice au moment de la compilation.

Vous avez également besoin d'une allocation non automatique lorsque le tableau est grand. En effet, la mémoire réservée à une allocation automatique est souvent assez limitée.

... avec le nouvel opérateur?

Il est rarement préférable d'allouer une mémoire dynamique en utilisant une nouvelle expression. std :: vecteur est généralement utilisé lorsque la matrice dynamique est nécessaire.


0 commentaires

1
votes

La raison pour laquelle il est mauvais est que ce n'est pas valide C ++ Code. Certains compilateurs C ++ le compileront en raison de la prise en charge des tableaux de longueur variable (VLAS), mais ce n'est pas une fonction de langue C ++ prise en charge du noyau et ne fonctionnera pas sur tous les compilateurs conformes à la normale.

en C ++, si vous savez au moment de la compilée, la longueur d'un tableau, vous devez utiliser std :: Array , qui est un remplacement et une version strictement meilleure du "Array de style C", c'est-à-dire int arr [5]; . Si vous ne connaissez pas la longueur au moment de la compilée et que vous devez le déterminer au moment de l'exécution, vous devez utiliser std :: vecteur , qui est un remplacement pour int * arr = neuf int [5]; et qui a l'avantage supplémentaire que vous n'avez pas besoin de vous rappeler d'appeler Suppr [] plus tard, comme le Vecteur L'objet veillera à ce que le Delier est appelé correctement si l'objet sort de la pile.


1 commentaires

"Si vous savez au moment de la compilation, la longueur d'un tableau, vous devez utiliser STD :: Array " - Un commentaire: Ceci n'est vrai que si la longueur n'est pas trop grande parce que des tableaux trop importants (sur le pile) peut provoquer un débordement de pile.



-5
votes

N'oubliez pas: C et C ++ ne sont pas Java. Les tableaux, par exemple, sont juste un pointeur sur n morceaux de mémoire. Ce ne sont pas des objets où vous pourriez stocker des informations supplémentaires, telles que la taille de la matrice. Ainsi, le compilateur doit connaître la taille.

La raison n'est pas évidente pour les vecteurs. Après tout, vous pouvez utiliser Int * à la place, puis allouer la taille que vous souhaitez. P>

Mais si vous avez un tableau multidimensionnel, il devient plus évident pourquoi le compilateur doit connaître la taille. P>

int size = 10;
int myArray[size];

size = 20;


9 commentaires

"Les tableaux, par exemple, sont juste un pointeur sur n morceaux de mémoire" - non, ils ne sont pas. Les tableaux ne sont pas des pointeurs.


"Si vous avez besoin de tableaux dynamiques, utilisez des tableaux dynamiques." - sous la forme de std :: vecteur .


Neil Butterworth, lorsque vous passez un éventail d'entiers, que passez-vous? Quel mot préféreriez-vous avoir utilisé à la place? Manipuler? Cela me semble très oo. Si vous pouvez trouver une meilleure façon de la mettre, n'hésitez pas, et je peux modifier ma réponse.


Jepser Juhl, personnellement, je pense que cela vaut la peine de savoir comment faire votre propre utilisation dynamique de la mémoire plutôt que de toujours compter sur la STL. En outre, cela dépend simplement de la dynamique dont vous avez besoin de ces données. Si vous allez interroger une valeur de longueur une fois, renseignez-vous de ce qui n'est vraiment pas si dynamique, alors peut-être que de nouveau int [longueur] est parfaitement raisonnable. Tout dépend du contexte.


@Josephlarson Vous pouvez passer le tableau (par référence), un pointeur au tableau ou un pointeur sur le premier élément de la matrice.


Sergeya - Oui. Neil cueillait ma sémantique et je le défie de faire plus que de me dire que "tu as tort", mais de suggérer une meilleure sémantique. Mais la phrase "par référence" a une signification particulière en C ++. Cela signifie que vous utilisez le & symbole dans la déclaration, et ces sémantiques apporteraient de la confusion. Lorsque vous passez un tableau en C ou C ++, vous passez - comme vous l'avez dit - un pointeur au premier élément, ou un pointeur au tableau (même chose). Je ne pense pas qu'il y ait une différence sous la cagoule entre Void Foo (Int * PTR) et Void FOO (INT Array []). C'est un pointeur de toute façon.


La différence entre un tableau lui-même et le pointeur qu'elle décrit est assez importante dans le contexte de cette question particulière, qui concerne les matrices elles-mêmes et non sur l'utilisation des pointeurs.


@ Hegel5000 C'est aussi bien, mais personne n'a suggéré un meilleur terme à utiliser dans ma réponse originale. Ils continuent à la déclasser.


Un tableau est un bloc d'objets alloué de manière contiguë du même type . Vous avez à peu près dit que cela, mais vous avez ajouté le peu des pointeurs.



2
votes

Alors que quelques personnes de personnes ont signalé, C ++ détermine généralement des tailles de matrices à Compilation de l'heure , pas l'heure d'exécution.

Une variable a sa valeur définie au moment de l'exécution, il n'ya donc aucun moyen de déterminer la taille au moment de la compilation. C'est-à-dire sauf pour des variables constantes. Les variables constantes ont une valeur constante dans l'ensemble du programme et peuvent donc être déterminées à la compilation. P>

Si vous avez besoin d'une matrice qui a une taille dynamique, vous avez la possibilité de nouveau code> mot-clé: p>

std::vector<int> y; // replace int with any type of object you want


3 commentaires

Supprimer [] Y; ou mieux TANTEZ TOUJOURNEZ TOUJOURS TOUJOURS TOUJOURS TOUJOURNEZ TOUT LEUR TOUT POUR STD :: Vecteur Y (MYSIZE);


Ah. Grand point. Le vecteur est bien meilleur.


De plus, merci d'avoir souligné le Supprimer [] Y; chose. J'ai oublié lequel était le bon.