C++ Beginner's Tutorial: Sorting Vectors

This is a recent C++ tutorial that I did that came out very well. The full tutorial is 30 minutes of High Definition video. You can view the whole tutorial here: http://djere.com/node/19

Here is the source code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// cpp.vectors.0: Creating and Sorting a Vector
// This program creates a vector of doubles.
// It prompts the user to fill the vector.
// It then sorts the vector from lowest to highest.
// Written by Rex Djere.
// This source code will be maintained at http://djere.com/node/19

#include<vector> // include this for vector support
#include<algorithm> // include this for the sorting algorithm
#include<iostream> // include this for input and output support

using namespace std;

// function prototypes - these are templates of functions that we will define later
void printVector(vector<double> &,  int );
int getVectorSize(vector<double> & );


int main()
{

   // I organize my variables and vector here at the beginning of the main function.
   bool addMoreNumbers = 1; // boolean value acts as a choice to continue filling the vector or not
   double numberAdded; // this variable stores the value added by the user
   vector<double> myVector (0); // I create my vector, give it the name "myVector", and initialize it with a size of 0.

   // Welcome and explanatory messages
   cout << "Welcome to the vector creator and sorter." << endl;
   cout << "I will create and sort a vector of numbers that you enter." << endl;

   // start getting input from user
   cout << "Enter a number (decimals and negative numbers are okay): ";
   cin >> numberAdded;
   myVector.push_back(numberAdded);

   cout << "Enter another number: ";
   cin >> numberAdded;
   myVector.push_back(numberAdded);

    while (addMoreNumbers == 1)
    {
       cout << "Enter another number or enter 0 to quit: ";
       cin >> numberAdded;
       if (numberAdded != 0) myVector.push_back(numberAdded);

       if (numberAdded == 0)
       {
           addMoreNumbers = 0;
           break;
       }
    }

   // Input is complete. It's time to sort the vector.
   cout << endl << "Here are the non-zero numbers that you entered, sorted from lowest to highest: " << endl;
   sort (myVector.begin(),myVector.end()); // here is the actual sort


   printVector(myVector, getVectorSize(myVector)); // print the vector

   return 0; // the main function is of integer type, so it MUST return an integer such as 0
}


// below, I actually define the printVector and getVectorSize functions
void printVector(vector<double> & vector, int size)
{
    int index;
 for(index=0; index < size; index++)
   {
       cout << vector.at(index) << endl;
   }

}

int getVectorSize(vector<double> & vector)
{
 return vector.size();
}
Last edited on
What is the advantage of calling getVectorSize(myVector) instead of just myVector.size()?

The printVector function takes the size as argument. Why is that? Is it so that we don't have to print the whole vector if we don't want to for some reason?
Last edited on
@Peter87 good catch! I noticed too that that was unnecessary as I was posting the code. Since the .size function is built into vectors, I could have just called it directly in the main function.
// I organize my variables and vector here at the beginning of the main function.

Bad idea which smells of twice-obsolete 1989 revision of the C language.

while (addMoreNumbers == 1)
Another breath of 1989. Back then, C had no booleans, and such code made sense. In C++, it's just a very convoluted way of writing "while(addMoreNumbers)"

1
2
addMoreNumbers = 0;
           break;

Beside the unnecessary conversion from int to bool, this break; makes the whole while loop meaningless, as the loop controlling condition is never allowed to become false.

1
2
int index;
 for(index=0; 

Another hello from 1989?

Not even mentioning redundant flushes, unnecessary bounds checks, questionable conversions (why is size cast to a signed integer?), lack of error handling. This wouldn't even pass a code review, let alone be used as a tutorial.
@Peter87, that is just how I was always taught to do a print function, by passing the boundaries of the array or vector to the function. What do you recommend? @Cubbi, I respectfully disagree with your assessment. This is a BASIC tutorial. It compiles, runs, and works. It took a reasonably short amount of time to write. It is fine fine tutorial to teach basic concepts.

Message to young people learning C++: you will ALWAYS meet people that have nothing positive to say. Don't let them intimidate or discourage you. The important thing is to continuously learn and get better at your craft.
Last edited on
DjereUniversity wrote:
I was always taught to do a print function, by passing the boundaries of the array or vector to the function. What do you recommend?

It makes sense for arrays because there is no other way to get the size. With vectors you can always call the size() function so there is no need to pass the size as a function argument.
@Peter87 Thanks for the tip!
It is fine fine tutorial to teach basic concepts.


I suppose. But the main problem is that the newbies learning C++ won't understand why you have these random casts, etc in your code. At best, it will simply confuse them. At worst, they'll think they are needed and try to copy, which is bad.

To be honest, it seems like you wrote this code once and then posted it. That's fine, but you probably shouldn't be trying to teach other people good practices if you haven't gone over your code several times and had it reviewed by others first.
DjereUniversity wrote:
Message to young people learning C++: you will ALWAYS meet people that have nothing positive to say. Don't let them intimidate or discourage you. The important thing is to continuously learn and get better at your craft.
You posted this on a public forum and didn't expect any criticism? I dont see anyone trying to intimidate or discourage you, and the points the others have made are valid. The suggestions/criticism is given so you can make your product better. I have a couple suggestions as well, for one maybe avoid using namespace std, since this is a beginner tutorial steer users into good habits. Also, for a vector tutorial I think it would be a good idea to show use of vector iterators.
Last edited on
Thank you all for the feedback. I understand what you are saying: I should submit my code for a peer review process before posting it as a tutorial. I am still pretty new to C++, but I am learning. Could one of you please post an improved version of my code so I can see how I should have done it?
You posted this on a public forum and didn't expect any criticism?
You're absolutely right. I was being way too sensitive. I won't get better if I don't absorb and learn from criticism. I am still a pretty new coder so I still just look at it as solving the problem, getting the output that I'm looking for. I still have to learn all of the nuances. It would be very helpful to see improvements to this code to see how I should have done it.
Last edited on
// I organize my variables and vector here at the beginning of the main function.


Bad idea which smells of twice-obsolete 1989 revision of the C language.


It's still not a bad way to do things, in C. The code part of a function will be "cleaner".
I agree that in C++ it does make a difference, because there's a hidden cost for creating some variables - the constructor function call.

return 0; // the main function is of integer type, so it MUST return an integer such as 0
Not really. main() is an exception from that rule. Try removing that return 0; and see what happens.
Also...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// vector_sort.cpp
// C++03

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    std::vector<double> v;
    double temp;

    std::cout << "Enter some numbers, or a non-number to stop." << std::endl;

    while (std::cin >> temp)
        v.push_back(temp);

    std::sort(v.begin(), v.end());
    std::cout << "\nInput complete. Sorted vector is:" << std::endl;

    for (std::vector<double>::const_iterator it = v.begin();
        it != v.end();
        ++it
        )
        std::cout << *it << ' ';

    std::cout << std::endl;
}
@Catfish2:
return 0; // the main function is of integer type, so it MUST return an integer such as 0
Not really. main() is an exception from that rule. Try removing that return 0; and see what happens.


I thought that was only with certain compilers. Also, I thought some compilers have the statement built in, which is why you sometimes don't need it.

I mean if the code compiles and runs successfully, isn't a 0 returned?
Last edited on
DjereUniversity wrote:
I am still a pretty new coder so I still just look at it as solving the problem, getting the output that I'm looking for

Those are the goals of a single-use throwaway program, which is a fine thing to create, but it is not a tutorial.

If you posted this program stating that you're "a pretty new coder" and asking what could be improved and why, you wouldn't get so much negativity (at least not from me). But you claimed to be teaching C++, and that's a whole different story.
Not really. main() is an exception from that rule. Try removing that return 0; and see what happens.


I thought this was compiler dependent? And against standards?

Well, that second question I'm almost certain is true, but the first I'm not.
I thought this was compiler dependent? And against standards?

In the C++11 draft N3242 that I have, the wording is clear: the lack of a return statement in main() means an implied return 0;.
int main() has had the implied return 0; in C++ as far back as C++98 ($3.6.1[basic.start.main]/5) and in C as far back as C99 ($5.1.2.2.3/1).

It doesn't matter at all when it comes to program execution, but educational materials that say 'must return' there raise concern (as in "what else did they get wrong?")
Last edited on
Ah this is good to know. Like you said, it doesn't really make a huge difference, but I like having correct info :D
Topic archived. No new replies allowed.