web-dev-qa-db-fra.com

Le vecteur a converti toutes les valeurs négatives en zéro

J'ai créé un vecteur de taille constante pour stocker les valeurs négatives, puis j'ai imprimé les valeurs que je n'ai obtenues que des zéros. Je veux juste savoir pourquoi il ne stocke pas de valeurs négatives.

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v(5);
    v.Push_back(-1);
    v.Push_back(-2);
    v.Push_back(-3);
    v.Push_back(-4);
    v.Push_back(-5);

    for (int i=0; i<5; i++)
       std::cout << v[i] << " ";  // All I got was zeroes
}
31
Suhail Akhtar

C'est parce que Push_back place nouvea éléments à la fin du vecteur.

Vous pouvez voir l'effet en exécutant i sur 9: les nombres négatifs occuperont v[5] à v[9].

L'écriture

std::vector<int> v{-1, -2, -3, -4, -5};

est plutôt une solution particulièrement élégante.

53
Bathsheba

Le constructeur que vous invoquez remplit les 5 premiers éléments avec des zéros, voir ici (# 3 dans la liste des surcharges):

Construit le conteneur avec le nombre d'instances de T insérées par défaut

(où "l'instance insérée par défaut" d'un int est 0). Ce que vous auriez pu vouloir c'est

std::vector<int> v;

v.reserve(5); /* Prevent unnecessary allocations as you know the desired size. */

v.Push_back(-1);
/* ... */

Une alternative utilisant l'appel constructeur d'origine est

#include <numeric>

std::vector<int> v(5);

std::iota(v.rbegin(), v.rend(), -v.size());

bien que cela fasse plus de travail que nécessaire car chaque élément est d'abord construit par défaut puis affecté à nouveau à une nouvelle valeur.

25
lubgr

C'est un cas où le principe SEC vous aiderait à comprendre votre erreur.

vector<int> v(5);

...

for(int i=0;i<5;i++)

Ici, vous créez un tableau pour lequel vous pensez réserver de l'espace pour 5 éléments. Ensuite, vous insérez ces 5 éléments. Après cela, vous vouliez imprimer le contenu de l'ensemble du tableau, mais au lieu d'écrire simplement v.size(), vous avez répété 5, pour que votre code se lise désormais comme "Imprimer les cinq premiers éléments de v", au lieu de "Imprimer tous les éléments de v".

Si vous écriviez à la place ce que vous voulez dire, vous verriez que le tableau a en fait 10 éléments, pas 5.

BTW, depuis C++ 11, vous pouvez parcourir tous les éléments d'une manière plus simple:

for(int x : v)

ou, si les éléments étaient d'un type plus coûteux en copie, vous pouvez utiliser des références aux éléments, même des références de type auto-:

for(auto& x : v)

Cette nouvelle syntaxe de boucle for- est appelée la boucle basée sur la plage for .

12
Ruslan

Vous pouvez considérer le vector comme une version flexible du tableau primitif en C/C++. Lorsque vous initialisez un vector avec une taille n, le vector construit a une taille de n (ou peut-être plus grande en mémoire, mais ce n'est pas le cas savoir car il est implicitement géré par le compilateur). Notez qu'ici n représente le nombre d'entrées, mais pas l'utilisation réelle de la mémoire (c'est-à-dire les octets). Si vous ne l'initialisez pas avec un paramètre de taille, le vector est vide avec la taille 0, mais dans la mémoire, il aurait une taille de mémoire implicite par défaut.

Disons que votre vector actuel a une taille 5. Et vous voulez Push_back() dans un autre élément, puis le vector en interne réallouera le tableau entier dans un nouvel emplacement mémoire qui pourrait conserver toutes ses anciennes entrées et la nouvelle. Vous n'avez donc pas besoin de réaffecter la mémoire manuellement par vous-même, comme ce que vous devez faire en C.

Ici, dans votre exemple, pour remplir ces 5 entiers négatifs dans votre vector, il y a deux façons.

1) Vous pouvez initialiser un vector sans spécifier la taille. Et puis insérez chaque élément souhaité.

vector<int> v;
for (int i = -1; i >= -5; --i) {
    v.Push_back(i);
}

2) Vous pouvez initialiser le vector à votre façon avec ce paramètre de taille. Et puis attribuez-leur de nouvelles valeurs.

vector<int> v(5);
for (int i = 0; i < v.size(); ++i) {
    v[i] = -i;
}

3) Vous pouvez également initialiser le vector avec ces entrées lors de sa construction.

    vector<int> v{-1, -2, -3, -4, -5};
or  vector<int> v = {-1, -2, -3, -4, -5};
5
hiimdaosui

Lorsque vous avez déclaré le vecteur avec

std::vector<int> v(5);

Vous avez fait v stocker cinq espaces de 4 octets en mémoire (en supposant un int = 4 octets sur votre système), et par défaut tous ces espaces de 4 octets stockent les bits représentant des 0. Ensuite, vous avez poussé 5 pouces supplémentaires (-1, -2, -3, -4, -5) à la fin du vecteur avec:

v.Push_back(-1);
v.Push_back(-2);
v.Push_back(-3);
v.Push_back(-4);
v.Push_back(-5);

À ce stade, le vecteur a 10 éléments, les cinq premiers étant les entiers inconnus qui se trouvent stocker des 0 sur l'instance où vous avez exécuté le programme. Puisque votre boucle for imprime les cinq premiers éléments du vecteur, c'est pourquoi elle a imprimé tous les 0.

0
Inertial Ignorance