Какова разница в инициализации вектора v (n) между следующими двумя случаями - PullRequest
1 голос
/ 12 апреля 2020

У меня есть следующий фрагмент кода,

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int input,n;
    cin >> n;
    vector<int> v(n);
    for(int i=0;i<n;i++){
       cin>>input;
       v.push_back(input);
    }   
   for(int i=0; i<v.size();i++){
       cout << v[i] << endl;
   }
   cout << v.size() << endl;
   return 0;
}

и

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int input,n;
    vector<int> v(n);
    cin >> n;
    for(int i=0;i<n;i++){
       cin>>input;
       v.push_back(input);
    }

   for(int i=0; i<v.size();i++){
       cout << v[i] << endl;
   }
   cout << v.size() << endl;
   return 0;
}

для следующего ввода, n=5, 1 2 3 4 5, первая программа выдает вывод

0
0
0
0
0
1
2
3
4
5
10

и вторая программа дает результат

1
2
3
4
5
5

Я не понимаю, почему vector инициализирует 0 в первом, удваивая размер, но не во втором

Ответы [ 2 ]

3 голосов
/ 12 апреля 2020

На самом деле, ни то, ни другое не подходит для того, что вы хотите (я при условии, что здесь вам нужно пять элементов, которые вы вводите, и ничего более - что может быть неверным предположением, но мне кажется, что это хорошая ставка).


В первом у вас есть (добавлены комментарии, чтобы объяснить, что происходит):

int input,n;       // n has arbitrary value.
cin >> n;          // overwritten with 5.
vector<int> v(n);  // initial vector has five zeros.

Это означает, что ваш вектор будет создан с пятью (при условии, что вы введете это для n) записями по умолчанию. Затем вы go и вставляете еще пять, поэтому вы получаете пять нулей, за которыми следуют ваши фактические данные.


У вашего второго:

int input,n;       // n has arbitrary value.
vector<int> v(n);  // initial vector of that arbitrary value (probably).
cin >> n;          // overwritten with five but it's too late anyway.

Это на самом деле неопределенное поведение, так как вы не представляете, что будет n, когда создадите вектор такого размера. В вашем случае он кажется равным нулю, но это просто счастливое совпадение.

Обратите внимание на использование слова «вероятно» выше. Хотя существует вероятность, что вектор будет создан с произвольным числом записей, неопределенное поведение означает именно это - на него вообще не следует полагаться. По праву, он может довольно легко удалить все ваши файлы при воспроизведении derisive_laughter.wav через вашу звуковую систему: -)

Наиболее вероятный случай, однако, будет одним из:

  • это будет работать так, как вы думали, потому что n равно нулю;
  • будет иметь произвольное количество нулей в начале, аналогично вашему первому фрагменту кода;
  • это вызовет исключение нехватки памяти, потому что n смехотворно велик; или
  • это вызовет исключение, поскольку n является отрицательным.

В любом случае, вы обычно либо предварительно выделяете и просто установите уже существующие значения:

vector<int> v(2);
v[0] = 7;
v[1] = 42;

или , а не с предварительным выделением, используя push_back для расширения вектора по требованию:

vector<int> v;
v.push_back(7);
v.push_back(42);
0 голосов
/ 12 апреля 2020

Надеюсь, можно написать первый случай написания программы в вопросе следующим образом, чтобы получить правильный результат

1
2
3
4
5
5 

для ввода, указанного в вопросе

#include <iostream>
#include <vector>
using namespace std;

int main()
{
   int n;
   cin>>n;
   vector<int> v(n);

   for(int i=0;i<n;i++){
       cin>>v.at(i);           
   }
   for(int i=0;i<v.size();i++){
       cout << v[i] << endl;
   }
   cout << v.size() << endl;
   return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...