简体   繁体   中英

C++ : iterating the vector

I'm very new to C++ and I'm trying to learn the vector in C++..

I wrote the small program as below. I like to foreach(var sal in salaries) like C# but it doesn't allow me to do that so I googled it and found that I have to use iterator.. Im able to compile and run this program but I dont get the expected output.. I'm getting "0 0 0 0 0 0 1 2 3 4 5 6 7 8 9" instead of "0 1 2 3 4 5 6 7 8 9"..

Could anyone please explain me why? Thanks.

#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

void show(int i)
{
  cout << i << " ";
}

int main(){

    vector<int> salaries(5);

    for(int i=0; i < 10; i++){
        salaries.push_back(i);
    }

    for_each(salaries.begin(), salaries.end(), show);   
}

You created a vector with 5 elements, then you push 10 more onto the end. That gives you a total of 15 elements, and the results you're seeing. Try changing your definition of the vector (in particular the constructor call), and you'll be set. How about:

vector<int> salaries;

This code creates a vector with a size of 5, and with each of those 5 elements initialized to their default value (0):

vector<int> salaries(5);

push_back inserts a new element, so here, you insert 10 new elements, ending up with a vector with 15 elements:

for(int i=0; i < 10; i++){
    salaries.push_back(i);
}

You can create your vector like this instead:

vector<int> salaries;

and you'll get a vector with size 0.

Alternatively, you could initialize it with size 10, and then overwrite each element, instead of inserting new ones:

vector<int> salaries(10);

for(int i=0; i < 10; i++){
    salaries[i] = i;
}

In some cases, it may be more efficient to write something like this:

vector<int> salaries; // create a vector with size 0
// allocate space for 10 entries, but while keeping a size of 0
salaries.reserve(10); 

for(int i=0; i < 10; i++){
    // because we reserved space earlier, these new insertions happen without
    // having to copy the vector contents to a larger array.
    salaries.push_back(i); 
}

When you declare salaries(5), it's adding 5 entries into the vector with values of 0. Then your loop adds 0..9. Therefore you have 15 elements in your vector instead of just 10. Try declaring the vector without the 5.

vector<int> salaries;

vector<int> salaries(5); means, that you are creating the vector which contains 5 int objects from the start, and each int object is initialized with default constructor, and in the case of int contructor sets zero value. That's why you have 5 zero integers at the beginning of the vector container.

@Michael: Which book is that? I'd say it's wrong. Using resize() is a good practice if you know in advance how big you need the vector to be, but don't set the size at creation unless you need the vector to contain default-initialized values.

You can also reserve some capacity in the array in advance which is subtely different than re-size. Reserving simply reserves "at least" that much capacity for the vector (but does not change the size of the vector), while resize adds\\removes elements to\\from the vector to make it the requested size.

vector<int> salaries(5);

This creates a vector of 5 zeros for its elements. [0, 0, 0, 0, 0]

for(int i=0; i < 10; i++){
    salaries.push_back(i);
}

This adds 10 more elements at the end ranging from 0 to 9 [0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Finally, I don't recommend using foreach so much. Functional programming has the downside of decentralizing code. It is extremely useful in some cases, but for these cases, and especially considering how you're starting out, I'd recommend:

for (vector<int>::const_iterator it = salaries.begin(), end = salaries.end(); it != end; ++it){
    salaries.push_back(i);
}

Using this technique, you'll be able to iterate through any collection in the standard library without having to write separate functions or function objects for the loop body.

With C++0x you'll get a lot of goodies to make this easier:

for (int salary: salaries)
    cout << salary << endl;

There's also BOOST_FOR_EACH already which is almost as easy if you can use boost.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM