I mean if returning itself is the problem in understanding, I think a function besides main() may help OP understand. It's really important to take a bird's eye view on this subject.

In general all functions that use return values use them to communicate information. What information? It depends. A lot of the time, the only good answer is "read the friendly manual." Once that is understood for one particular function, that concept needs to be extended to other functions, which are using return values to similar ends.

As a concrete example, I wrote a small program that solves the quadratic formula:

Code:

#include <iostream> // for cin, cout
#include <cerrno> // for errno
#include <cmath> // for sqrt
#include <algorithm> // for swap (C++ 98)
#include <utility> // for pair or swap
#include <limits> // for NaN
using namespace std;
/* Returns the solutions for a polynomial of degree 2 using the quadratic formula.
If the results are complex numbers, then the return value will be a pair of NaNs.
*/
pair<double, double> poly2zero(double a, double b, double c)
{
errno = 0;
double nan = numeric_limits<double>::quiet_NaN();
pair<double, double> r = make_pair(nan, nan);
double discriminant = sqrt(b * b - 4 * a * c);
if (errno != EDOM)
{
double denom = 2 * a;
r.first = ((-b) - discriminant) / denom;
r.second = ((-b) + discriminant) / denom;
if (min(r.first, r.second) != r.first)
{
// swap so the first root is always the lesser of the two:
swap(r.first, r.second);
}
}
return r;
}
int main()
{
double a, b, c;
cout << "This program will solve polynomials of degree 2 ax^2 + bx + c.\n";
cout << "Enter A: ";
cin >> a;
cout << "Enter B: ";
cin >> b;
cout << "Enter C: ";
cin >> c;
pair<double, double> answer = poly2zero(a, b, c);
cout << "Your solutions are " << answer.first << '\t';
cout << answer.second << '\n';
}

So the return value of poly2zero(a,b,c) is not meaningless, agreed? It is actually the two roots of the equation ax^{2} + bx + c = 0 in .first and .second.

One way you can use the program is to find the golden ratio:

Code:

This program will solve polynomials of degree 2 ax^2 + bx + c.
Enter A: 1
Enter B: -1
Enter C: -1
Your solutions are -0.618034 1.61803

Return values are one way to pass information along in a program. In more concrete terms, it works the same way you pass a baton in a race. The answer in this program is the baton, and the variables in the program hold the baton at different points during a run. Without them, it would actually be harder to write this, and use all sorts of other functions. main() is just one concrete example, for the use of the operating system, which communicates whether there was a problem or not.

The example I posted could even be amended to communicate errors the way main() does, because it returns NaNs if there wasn't a real number solution. It's:

Code:

if (answer.first == answer.first) { // NaNs are never equal to each other.
cout << "Your solutions are " << answer.first << '\t';
cout << answer.second << '\n';
} else {
cout << "The polynomial does not have a real number solution (NaN).\n";
}

HTH.