Functions are your first foray into making programs of real substance. In their simplest form (they only take about two forms that I know of), they are code repositories; you can use functions to call on a block of code of any size any time you want instead of having to retype that code every time you want to use it.
When making a function, you must first decide whether or not it will return any values. This is because, like variables, all functions have data types. If you are returning a value, the function must take that value's data type. If you return nothing, you'll use the data type "void." Then you'll decide the function's name. Like variables, they can contain alphanumeric characters and underscores, but can only begin with underscores or letters. With that information, you're ready to create your first function, which will look something like this.
void myFirstFunction()
{
}
Whenever you want to use this function, you'd just rewrite the function name and the parentheses when you want to use the code it contains. Obviously, the code will go inbetween the curly brackets of the function, as I'll demonstrate shortly. While this is all well and good for welcome messages or menu printouts, it is not exactly as versatile as we need it to be. This is where parameters come in; they are pieces of data that you can pass to a function. Contained within the parentheses of the function declaration, you can use as few or as many as you need, but you must use all of them every time you call the function, even if half of it ends up being garbage data just to satisfy that requirement. Each individual declaration within the parameters is also called an argument. But I digress, they act like normal variable declarations.
int mySecondFunction(int number1, int number2)
{
int sum = number1 + number2;
return sum;
}
I introduce two new things in this example: using a real data type for the function declaration (i.e., returning a value) and, of course, function parameters. As you can see, the data type returned has to be the same data type as was declared in the function. There must be a return statement if the function has a data type other than void; doing otherwise will cause the compiler to throw a warning. The parameters, as you can also see, are simply sets of data type/variable names delimited by commas. You obviously don't have to use one in order to use the other, though.
Anyways, the variables created from the parameters will only exist within the function that created them, which brings up a fact that was of little importance before now: variable scope. Variables created within a block of code will only exist within that block of code and its children (i.e., blocks of code within that block of code) whose code is explicitly written within the parent (i.e., not functions). These are called local variables, and you've already had experience with them in for loops. There are also those variables that are declared outside of any functions; they're called global variables, and they exist everywhere. If you use global variables (or even a for loop), be careful to avoid naming conflicts. If one exists, the program will always use the most local of the conflicting variables, which may not be your intention, so avoid it altogether.
Back to functions. In order to call a function with parameters, you simply fill each parameter "slot" with a variable or piece of data with an identical data type. The variables you use when you call the function will not be modified in any way. To catch the value that a function returns, simply set a variable of an identical data type equal to the function. If the function returns a value but you do not care to catch it, there is no need to. And yes, the return 0 statement at the end of the main() function is basically telling the program that it is allowed to shut itself down. Here is an example which assumes the previous example has already executed.
int a = mySecondFunction(3,5); mySecondFunction(a, 2);
If you hadn't already guessed, variable a will contain the value 8 after this code executes, and the program will compute the second function call but do nothing with it. This is because there was no variable in place to receive the value it returned.
Before you go out writing functions willy nilly, there is one last piece of information whose absence will be your downfall: the function prototype. Placed at the top of the program right after your includes (they can go anywhere but it would be stupid to do so), without them all of your functions would have to be declared above the main() function so that the compiler would cache them before possibly making a call to one of them. Don't worry; prototypes are simple. They are basically copies of the header of the function. That is, the first line which contains the function's data type, name and parameters followed by a semicolon. Here is mySecondFunction's prototype, which again would be placed right below all of your includes.
int mySecondFunction(int number1, int number2);
With this, the compiler can create a cache of all of the functions in the program without you having to place all of the code for them at the top of the file. It also prevents the vexing problem of calling a function that hasn't been declared yet within another function. Simply put, you can curtail the prototype and place all of your functions at the top of the file if you wish, but only if you wish to encounter problems down the road. More on functions next lesson!