web-dev-qa-db-fra.com

Comment changer un élément particulier d'un vecteur STL C ++

vector<int> l;
for(int i=1;i<=10;i++){
   l.Push_back(i);
}

Maintenant, par exemple, comment changer le 5th element Du vecteur en -1?

J'ai essayé l.assign(4, -1); Il ne se comporte pas comme prévu. Aucune des autres méthodes vectorielles ne semble convenir.

J'ai utilisé vector car j'ai besoin d'une fonctionnalité d'accès aléatoire dans mon code (en utilisant l.at(i)).

42
Moeb

at et operator[] les deux renvoient une référence à l'élément indexé, vous pouvez donc simplement utiliser:

l.at(4) = -1;

ou

l[4] = -1;
104
James McNellis

Même si la réponse de @JamesMcNellis est valide, je voudrais expliquer quelque chose sur la gestion des erreurs et également le fait qu'il existe une autre façon de faire ce que vous voulez.

Vous avez quatre façons d'accéder à un élément spécifique dans un vecteur:

  • Utilisation de l'opérateur []
  • Utilisation de la fonction membre at(...)
  • Utilisation d'un itérateur en combinaison avec un décalage donné
  • Utilisation de std::for_each À partir de l'en-tête algorithm de la bibliothèque C++ standard. C'est une autre façon que je peux recommander (il utilise en interne un itérateur). Vous pouvez en lire plus par exemple ici .

Dans les exemples suivants, j'utiliserai le vecteur suivant comme rat de laboratoire et expliquerai les trois premières méthodes:

static const int arr[] = {1, 2, 3, 4};
std::vector<int> v(arr, arr+sizeof(arr)/sizeof(arr[0]));

Cela crée un vecteur comme indiqué ci-dessous:

1 2 3 4

Voyons d'abord la façon de faire []. Cela fonctionne à peu près de la même manière que vous vous attendez lorsque vous travaillez avec un tableau normal. Vous donnez un index et éventuellement vous accédez à l'élément que vous souhaitez. Je dis éventuellement parce que l'opérateur [] Ne vérifie pas si le vecteur a réellement autant d'éléments. Cela conduit à un accès mémoire non valide silencieux. Exemple:

v[10] = 9;

Cela peut ou non entraîner un crash instantané. Le pire cas est bien sûr si ce n'est pas le cas et que vous obtenez réellement ce qui semble être une valeur valide. Semblable aux tableaux, cela peut entraîner une perte de temps à essayer de trouver la raison pour laquelle, par exemple, 1000 lignes de code plus tard, vous obtenez une valeur de 100 Au lieu de 234, Ce qui est quelque peu lié à cela. emplacement où vous récupérez un élément de votre vecteur.

Une bien meilleure façon est d'utiliser at(...). Cela vérifiera automatiquement le comportement de out of bounds Et interrompra le lancement d'un std::out_of_range. Donc, dans le cas où nous avons

v.at(10) = 9;

Nous obtiendrons:

terminate appelé après avoir lancé une instance de 'std :: out_of_range'
what (): vector :: _ M_range_check: __n (qui est 10)> = this-> size () (qui est 4)

La troisième méthode est similaire à l'opérateur [] Dans le sens où vous pouvez tout gâcher. Un vecteur comme un tableau est une séquence de blocs de mémoire continue contenant des données du même type. Cela signifie que vous pouvez utiliser votre adresse de départ en l'affectant à un itérateur, puis en ajoutant simplement un décalage à cet itérateur. Le décalage représente simplement le nombre d'éléments après le premier élément que vous souhaitez parcourir:

std::vector<int>::iterator it = v.begin(); // First element of your vector
*(it+0) = 9;  // offest = 0 basically means accessing v.begin()
// Now we have 9 2 3 4 instead of 1 2 3 4
*(it+1) = -1; // offset = 1 means first item of v plus an additional one
// Now we have 9 -1 3 4 instead of 9 2 3 4
// ...

Comme vous pouvez le voir, nous pouvons également le faire

*(it+10) = 9;

qui est encore un accès mémoire invalide. C'est fondamentalement la même chose que l'utilisation de at(0 + offset) mais sans la vérification d'erreur hors limites.

Je conseillerais d'utiliser at(...) autant que possible non seulement parce qu'il est plus lisible par rapport à l'accès à l'itérateur, mais en raison de la vérification d'erreur pour l'index invalide que j'ai mentionné ci-dessus pour l'itérateur avec combinaison de décalage et le [].

11
rbaleksandar

Cela devrait le faire:

l[4] = -1
6
Fred Larson

Vous pouvez utiliser opérateur d'indice

l[4] = -1
5
Tom

Je préfère

l.at(4)= -1;

tandis que [4] est votre index

1
codexaxor