web-dev-qa-db-fra.com

Tableaux vs vecteurs: similitudes et différences introductives

Quelles sont les différences entre un tableau et un vecteur en C++? Un exemple des différences pourrait être les bibliothèques incluses, le symbolisme, les capacités, etc.

Tableau

Les tableaux contiennent un nombre spécifique d'éléments d'un type particulier. Pour que le compilateur puisse réserver la quantité d'espace nécessaire lors de la compilation du programme, vous devez spécifier le type et le nombre d'éléments que le tableau contiendra lors de sa définition. Le compilateur doit pouvoir déterminer cette valeur lors de la compilation du programme. Une fois qu'un tableau a été défini, vous utilisez l'identificateur pour le tableau avec un index pour accéder à des éléments spécifiques du tableau. [...] les tableaux sont indexés à zéro; c'est-à-dire que le premier élément est à l'index 0. Ce schéma d'indexation indique la relation étroite en C++ entre les pointeurs et les tableaux et les règles que le langage définit pour l'arithmétique de pointeur.

- Référence de poche C++

Vecteur

Un vecteur est une séquence d'objets de taille dynamique qui fournit un accès aléatoire de type tableau operator[]. La fonction membre Push_back copie ses arguments via le constructeur de copie, ajoute cette copie en tant que dernier élément du vecteur et incrémente sa taille de un. pop_back fait exactement le contraire, en supprimant le dernier élément. L'insertion ou la suppression d'éléments à la fin d'un vecteur prend un temps constant amorti, et l'insertion ou la suppression d'un autre emplacement nécessite un temps linéaire. Ce sont les bases des vecteurs. Il y a beaucoup plus pour eux. Dans la plupart des cas, un vecteur devrait être votre premier choix sur un tableau de style C. Tout d'abord, ils sont de taille dynamique, ce qui signifie qu'ils peuvent se développer au besoin. Il n'est pas nécessaire de faire toutes sortes de recherches pour déterminer une taille statique optimale, comme dans le cas des tableaux C; un vecteur se développe au besoin et il peut être redimensionné manuellement si vous en avez besoin. Deuxièmement, les vecteurs offrent des limites en vérifiant avec la fonction membre at (mais pas avec operator[]), de sorte que vous puissiez faire quelque chose si vous référencez un index inexistant au lieu de simplement regarder votre programme se bloquer ou, pire, poursuivre l'exécution. avec des données corrompues.

- Livre de recettes C++

101
Trancot

tableaux:

  • sont une construction de langage intégrée;
  • venir presque inchangé de C89;
  • fournit uniquement une séquence d'éléments indexables contigus ; pas de cloches et de sifflets;
  • sont de taille fixe; vous ne pouvez pas redimensionner un tableau en C++ (à moins qu'il s'agisse d'un tableau de POD et qu'il soit alloué avec malloc);
  • leur taille doit être une constante de compilation à moins d'être allouée de manière dynamique;
  • ils prennent leur espace de stockage en fonction de la portée où vous les déclarez;
  • si elles sont allouées dynamiquement, vous devez les désallouer explicitement;
  • s'ils sont alloués dynamiquement, vous obtenez juste un pointeur, et vous ne pouvez pas déterminer leur taille; sinon, vous pouvez utiliser sizeof (d'où l'idiome commun sizeof(arr)/sizeof(*arr), qui échoue toutefois silencieusement lorsqu'il est utilisé par inadvertance sur un pointeur);
  • se désintègre automatiquement en un pointeur dans la plupart des situations; en particulier, cela se produit lorsque vous les transmettez à une fonction, ce qui nécessite généralement de définir un paramètre distinct pour leur taille;
  • ne peut pas être retourné d'une fonction;
  • ne peut pas être copié/assigné directement;
  • les tableaux dynamiques d'objets nécessitent un constructeur par défaut, car tous leurs éléments doivent être construits en premier;

std::vector:

  • est une classe de modèle;
  • est une construction uniquement en C++;
  • est implémenté comme un tableau dynamique ;
  • croît et diminue dynamiquement;
  • gérer automatiquement leur mémoire, qui est libérée à la destruction;
  • peut être passé/retourné à des fonctions (par valeur);
  • peut être copié/assigné (ceci effectue une copie complète de tous les éléments stockés);
  • ne se dégrade pas en pointeurs, mais vous pouvez explicitement obtenir un pointeur sur leurs données (&vec[0] est garanti pour fonctionner comme prévu);
  • apporte toujours avec le tableau dynamique interne sa taille (combien d'éléments sont actuellement stockés) et sa capacité (combien d'éléments peut être stocké dans le bloc actuellement alloué);
  • le tableau dynamique interne n'est pas alloué à l'intérieur de l'objet lui-même (qui ne contient que quelques champs de "tenue de livre"), mais est alloué de manière dynamique par l'allocateur spécifié dans le paramètre de modèle correspondant; celui par défaut obtient la mémoire du freestore (le tas), indépendamment de la manière dont l'objet réel est alloué;
  • pour cette raison, ils peuvent être moins efficaces que les baies "régulières" pour les baies petites et de courte durée;
  • lors de la réallocation, les objets sont copiés (déplacés, en C++ 11);
  • ne nécessite pas de constructeur par défaut pour les objets stockés;
  • est mieux intégré au reste de la soi-disant LIST (il fournit les méthodes begin()/end(), le STL habituel typedefs, ...)

Pensez également à "l'alternative moderne" aux tableaux - std::array; J'ai déjà décrit dans autre réponse la différence entre std::vector et std::array, vous pouvez le consulter.

130
Matteo Italia

J'ajouterai que les tableaux sont des constructions de très bas niveau en C++ et vous devriez essayer de vous en éloigner le plus possible lorsque vous "apprenez les ficelles du métier" - même Bjarne Stroustrup le recommande (il est le concepteur du C++).

Les vecteurs ont des performances très proches de celles des tableaux, mais offrent de nombreuses commodités et caractéristiques de sécurité. Vous allez probablement commencer à utiliser des tableaux lors de l'interfaçage avec des API traitant des tableaux bruts ou lors de la création de vos propres collections.

23
John Källén

Ces références ont bien répondu à votre question. En termes simples, les longueurs des vecteurs sont dynamiques tandis que les tableaux ont une taille fixe. lorsque vous utilisez un tableau, vous spécifiez sa taille lors de la déclaration:

int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;

pour les vecteurs, il suffit de le déclarer et d'ajouter des éléments

vector<int> myVector;
myVector.Push_back(1);
myVector.Push_back(2);
myVector.Push_back(3);
...

parfois, vous ne connaîtrez pas le nombre d'éléments nécessaires, de sorte qu'un vecteur serait idéal pour une telle situation.

9
Nicolas Brown