How do I write a function?

First, do you know what you want it to do? Make sure that the task is a simple one with no easily subdivided parts. (i.e. one calculation, one input, one output, etc.)

For example, let's write a function to calculate the volume of a sphere. That is a single, simple calculation so we're fine there. But it does require a helper constant. Since this one is a generic mathematical constant — used in many geometry, trigonometric, and other situations — let's make it a global constant:

    const double PI = atan2(0.0, -1.0);    // remember it's y and then x for atan2!

Write the Body

Our first task is to write the body of the function. We look up the formula and make it look C++-ish:

    {
        4 * PI * pow(radius, 3.0) / 3
    }

But what do we want to do with this formula? We could store it in a local variable and return that:

    {
        double volume;
        volume = 4 * PI * pow(radius, 3.0) / 3;
        return volume;
    }

But, as we saw in our earlier discussions, that would waste memory space and time during the call/return. It is simpler and nicer to simply return the result of the calculation directly:

    {
        return 4 * PI * pow(radius, 3.0) / 3;
    }

Now our body needs a head...

Write the Head

The head of a function contains the type of information returned from the function, the function's name, and the list of any values the function needs from the caller (the part of the program that asked this function to evaluate). It looks like our function will be returning a floating point (with fractional parts) value (pow() is type double and so is our constant for π). I think a good name for our function would be 'sphere_vol' (long enough to be understandable and still short enough to type from time to time).

But what do we need from the caller? Let's look at our formula again:

        4 * PI * pow(radius, 3.0) / 3

We know 4, 3, 3.0, and PI. The pow() function knows its business. The only thing left is the radius of the sphere. It isn't our sphere, though — it would be the caller's sphere we're calculating for. So I'm thinking the caller needs to tell us the radius of their sphere.

Putting that all together we get a head like:

    double sphere_vol(double radius)

Now to put all this stuff together in a program framework.

Where do I put all the parts?

There are so far two parts to our function: the body and the head. The body tells the compiler exactly how the function does what it does. The head tells the compiler what to call the function, what needs to come in, and what is coming out.

The Prototype

Before the compiler will allow a call to the function, it needs to know that function's name, necessary input(s), and (usually) what kind of information is coming out. All of that is in the head. So, we place a copy of the head at the top of the program — after the #include's and using but before the main:

    #include < ... >
    using namespace std;

    double sphere_vol(double radius);

    int main(void)
    {
        // ...
        return 0;
    }

Note the semi-colon (;) added to the end of the head. The head by itself isn't a complete thought in C++. But with the semi-colon, the compiler knows that we are done with what we were trying to say. In this case, we were declaring the future existence of a function with the specified interface/head. Newer programmers may call this a function declaration (like a variable declaration). But traditionalists (older programmers) will know it as a function prototype. I will call it a prototype.

The Definition

Now we need to tell the compiler how the function works by showing it the body. This is placed under another copy of the head below the main program:

    int main(void)
    {
        // ...
        return 0;
    }

    double sphere_vol(double radius)
    {
        return 4*PI*pow(radius,3.0)/3;
    }

This is known (be ye' old or new) as the function definition. It defines how the function does its job.

The Call

The final piece of a function is the call. This can be thought of as a stripped version of the head — but that might not be a great thing to commit to mind. (It's almost as harmful in the long run as thinking of functions as 'little programs'.) The exact form varies from function to function, but one thing remains the same: there are NO data types in the call.

You can call a function from any other function. Certainly you can call functions from the main. But, as long as you don't call a function from within its own body, you may call it from anywhere.

For example, the sphere_vol() function might be called from another function which is dealing with water displacement when a ball is dropped into a bucket:

    ... ball_in_bucket_displacement( ... double ball_rad ... )
    {
        double ball_vol ...;
        // ...
        ball_vol = sphere_vol(ball_rad);
        // ...
        return ...;
    }

(Here the '...' portions are not relevant to our focus but would need to be filled in with appropriate parts in a full function.) So the displacement function receives the ball's radius as an input, makes a local variable for the ball's volume, and finally calls the sphere_vol() function to get the answer it so desperately needs.

Note how the ball's radius is placed in the parentheses after the name of the function. This is just like evaluation of a function in algebra:

             2
    f(x) = 4x  - 3x + 12      // definition

    y = f(4)                  // evaluate at (call with) x = 4

    y = f(a+2)                // evaluate at (call with) x = a + 2

So the current value of ball_rad will be copied into the sphere_vol() argument radius. Next, control of execution goes into the sphere_vol() body where the formula is evaluated and the result is returned. This return-value comes back to the right side of the assignment within the caller. There, the returned value is assigned into ball_vol.

What other kinds of call patterns are there?

Again, depending on the function's head, there are different ways the function may be called. The main distinguishing characteristic of the head for this purpose is the return type.

Functions Returning a Value

The above function (sphere_vol()) has a value returned from it. That means you can call it within a mathematical expression:

    sphere_vol(rad1) - 12

Or you could call it in a cout statement:

    cout << "...volume is " << sphere_vol(rad) ...;

Or even in an argument list for another function:

    total_volume( ... sphere_vol(Radius) ... )

(Recall from the srand(time(nullptr)) situation that 'nested' calls are evaluated first and their results are passed to the 'outer' function call.)

Returns? We Don't Need No Stinking Returns!

On the other hand, if a function doesn't use the return mechanism to send a value back to the caller (it may have no answer to report or, perhaps, uses the reference argument mechanism to 'return' multiple answers), it will have a prototype like this:

    void func_name( ... );

(But with a good function name and whatever argument's are necessary.) These functions cannot be called like those returning a value. If you tried to print their call, for instance, what would cout be trying to print? There is nothing (void)! cout doesn't know how to print 'void' and so would be terribly upset. Likewise, you cannot use them in calculations, assignments, or as a nested call.

Then how do you use them!? Well, you just call them as a statement by themselves:

    func_name( ... );

Any arguments would be provided as above, but there is nothing allowed before the function's name and a semi-colon should immediately follow the argument list.