A Function is a set of actions designed to be executed at various times. This set of actions is defined inside braces { }. Before the set of braces there should be an identifier. The identifier works like the label we saw with goto. It allows the computer to later refer to this set of actions so you can tell it to do them. Here is the general format of a function:
{
various actions
}
The identifier (in blue) is the name you give to your function. It follows the saming naming conventions as variable names. All legal names are valid. The other elements of the above format will be explained as we go along. This format together is called the function definition.
Where are you supposed to write the function definition? Everything we have done up to now has been written inside the braces that follow main(). The function definition is an exception. You write it before the main()
For example here is a function named print_hello. Notice that we write it before the main() section:
This program may seem like it does not do anything special. We could have just written our cout command in the main body of our program and not really needed to write the function. Well, this function is just to show how to write a function, not to do anything really useful. It just shows us the structure of a function.
If I wanted to use this function in a program I need to call the function from the main. He is an example to do just that.
void print_hello() { cout<<"hello "; } main() { print_hello(); }
(Notice how the function is written before the braces which follow the main.)
The line in bold above is called the function call. What it does is to tell the computer to jump over to the function named print_hello and do the actions listed there. Upon completing this, the computer returns to where it was in the main section of the program and continues executing whatever commands are there. Now that we have completed an overview of what a function is, we can examine each element of a function in more detail.
We saw in the function format above something called the parameter list.
Here it is again for you (in blue)
In the parameter list we list all the pieces of information we want our function to be given, the parameters. Each parameter is written exactly like a variable declaration. So if we wanted the function to get 2 integers, our parameter list would look like this:
Notice that each parameter is separated by a comma. Also notice that even though I have two ints, I still need to write the word int twice:
Let's see an implementation of my previously mentioned idea of printing "hello" as many times as the function is told to.
If a function has more than one parameter then when the function is called, as many values as there are parameters must be sent. Each parameter is assigned one value as determined by the order of the variables.
We have seen that when we call a function we can pass values into the function. We can also get a value back out of the function. This value we get back can be stored in a variable where the function is called. If a function returns some value when it is done, this is called a return value. Functions can return only one value. After the functions does its job, the value it returns will be placed exactly in the place where the function call is written. Thus, assuming we have a function called myAverageFunction, a statement like:
int a = myAverageFunction ( 3,4,5);after the function finishes running will actually be translated to this:
int a = 4;The variable a will be assigned the value that the function myAverageFunction() returns. In other words, the return value is sent back to the place where the function was called. If, for example, there was an assignment operator there then the variable being assigned will get the value the function returns.
If you look at the definition of a function you will see that in the
general structure of a function there is something called the
return type. This is where you will define what type of value
your function will return, if any.
If you want your function to
return a value of type int then write int here.
If you want your function to
return a value of type float then write float here, etc.
Here is an example of a function whose return type (in blue) is defined to
be a float:
float myAverageFunction
(int a, int b, int c )
{
float average;
etc.
return average;
}
Defining the function to return a specific type of value is just the first step. Next you have to actually return that value in the body of the function. See the above line in green for where this function actually returns the value it is defined to return.
When returning a value, we use the key-word return followed by the value we wish to return. This
statement occurs inside the function. In addition to returning the value,
this return command also causes the function to exit
(i.e. finish immediately). This is true even if there are statements written
after the return command. For example,
float myAverageFunction
(int a, int b, int c )
{
float average;
etc.
return average;
cout<< "hello"; // this line will not execute
}
Even if a function returns a value, I can theoretically choose not to store the returned value. I can let the value "drop". It is as though a player would throw the baseball back to the pitcher at the end of the play, but the pitcher would just watch it fall to the ground. He just lets the ball drop. In the same way, a function can return a value to the caller, but the caller may or may not choose to store the value in a variable. For example I could call myAverageFunction like this:
myAverageFunction(4,67,89);In this case the function will get run as usual, but the return value has no place to go. It will be lost. Generally it is a good idea to store the return value in a variable so that you can use it in the future. But you can also choose not to store it and let it drop as above. One occasion where it might make sense not to store the return value is when you need to print the return value once and then do not need it any more. To do this you could write something like this:
cout<<myAverageFunction(4,67,89);Here, although I do not store the return value, I am able to see what it is. But after that I have lost the value.
Functions can also return nothing. In this case we have the function return void. If I want to write a function that does not return any value I must declare the function like this:
void myFunction (int a ) { return; }Notice that the return type is void. Also notice that the return statement is not followed by any value. I simply write return; .
If you want to write a function without any return value, write the word void> in place of the return type like this:
void myfunction() { cout<<"hello"; return; }Notice that I used the word return to show the end of the program but did not follow it with any value. This is because I am returning void, not an actual value. You may also choose to leave out the return line altogether.
When I call such a function in the main I cannot store the return value since there is no return value. I simply call the function:
int main() { myFunction(7); }
Some functions are built-in ( like rand(), see below ), but the programmer may write his own functions (as I did in the above examples). To do this, he must define the function. That is, he must define what return value type he intends to return, what paramenters he can accept, and of course what the function will actually do with the values it receives when it is called.
A function is defined according to the following format:
return-type functionName( type parameter1, type parameter2, ....)
{
statement;
statement;
statement;
:
:
return return-type;
}
The return-type is the type of the value that the function will return.
It can be an int, a float, a char etc. If the function has no return value,
then write void for the
return-type.
The parameters (parameter1, ...) are the data
inputs to the function. There is only ever one returned value but there can be any
number of
inputs. If there are multiple parameters they are seperated by commas.
Each parameter must be composed of a type and a valid identifier.
If the function has no inputs, then leave the parameter list blank or write the word
void between the parenthesis.
Each parameter acts as a variable which can be used inside the function.
It is as though I have defined several variables (in my parameter list) so that I
can then use them inside my function { }.
Here is an example of a function definition:
float myAverageFunction
(int a ,
int b , int c )
{
float average;
average = ( (
float )
a + ( float )
b + (float ) c / 3 );
return average;
}
This function takes 3 parameters all of type int. It then computes the
average of the 3 numbers and returns that value to the caller as a float.
If the calling function had a line like this, for example:
float a = myAverageFunction( 95, 80 , 80 ) ;
Then "a" would get the value 85 (the average of the 3 numbers).
Once I have written the function definitition, I can then use the function to
compute averages as many times as I wish. Furthermore, I can use it without
worrying how it does its job. I can treat the function as a black box.
The function call is when
I try to run the function. To do this I simply write the name of the function
followed by ( ). Inside the ( ) I place the list of values I want to
pass to the function parameters. This is called a function call.
When I do this, the values I input are assigned to the variables in the
parameter list.
The order of the list determines which values are assigned to which variables.
The function will then be able to access these values by using the variables
defined in its parameter list.
When we call a function we pass values into the function.
As I have stated, parameters are the list of comma deliniated variables which are used as inputs to the function. We can have as many parameters (inputs) as we want. Although it is true that these variables are defined locally ( i.e. within a function ) the values they get are equal to the values the caller supplies in his argument list.
For example:
float myAverageFunction( int a, int b, int c )
has three parameters. All three are ints. If I were to pass the values 1 , 2, and 7 in my call to the function like this
myFunction( 1, 2, 7 )
then "a" would get the value 1, "b" would get the value 2, and "c" would
get the value 7. The order of the numbers determines which value is assigned to which variable.
Furthermore, if my function is defined as using 3 parameters then I must pass it 3
values whenever I call the function. I cannot ignore any of the required inputs.
It is a good idea to write a function proto-type at the start of your
program for each function you plan to define. A function proto-type is
a way of telling the compiler what functions you plan to define later on.
This is useful when you have one function using another function.
The funtion proto-type looks just like the first line of the function definition
with the addition of a semi-colon ; at the end.
return-type functionName( type parameter1, type parameter2, ....);
So all you need to do is cut and paste the first line of your function definition
to the top of your program file and then add a semi-colon.
You are then permitted to write the functions after
the main() function. This syntax style is generally preferred.
Here is an example of a trivial function with a proto-type, the function
proto-type is in blue:
Ii is a general rule that variables are only recognized inside the block of code where they are defined. Thus, a variable defined within a nested block of code is not known outside the inner nest. The same holds true for functions. Variables defined inside one function are not known to the code of other functions. So too, the variables defined in the parameter list of a function are known to that function, but nowhere else. It is as though the parameters were defined inside the function braces. The variables defined by the function (inside the function) are not known to the calling function and variables defined by the calling function are not known to the called function. So how does the called function get data inputs if it does not know about the calling function's variables? It does not know the variable names, but you can pass the values of these variables in the parameter list. When I call a function, copies of the values of the variables I pass are sent to the function, not the original variables. For example, if I call a function like this
int num1 = 95;then the values of num1, num2, and num3 are passed, not the actual variables. Practically what this means is that num1, num2, and num3 cannot be changed or affected in any way by the function. The function myAverageFunction will just get the values 95, 80 ,and 80 and assign them to its local variables a, b, and c and work with them. (Note: When we learn pointers we will learn how a function can affect the original variables it is passed. )
int num2 = 80;
int num3 = 80;
float a;
a = myAverageFunction( num1, num2, num3 ) ;
Let's see an example of a function which attempts to change a variable outside its scope. The function will obviously not succeed at doing this.
void changeMe(int a) { a++; return; }If this function were called in the main of a program like this
int var =9; changeMe(var);the variable (var) passed to the function would not actually change (var will still be 9). This is becasue var was not passed to the function, only its value ( 9 ) was passed. This value was then copied into the function's variable "a", and then "a", not "var" was incremented. "var" was never touched.
If I want to change the variable I will have to return a new value as an output and then store it in the variable in main. Here is an example of how I could really change the variable (notice, I changed the function name to more exactly describe its function):
int returnLargerValue(int a) { return (a++); } int main() { int var=9; var=returnLargerValue(var); return 0; }The above example will actually increase var by 1. Notice that I had to return a new larger value and then use the assignment operator (=) to reset var to this new value.
int global_a ; int changeme() { global_a++; } int main() { global_a=8; changeme(); return 0; }The function changeme() will change the variable global_a (the name is not significant) from 8 to 9. Both the main() and the function changeme have access to the variable global_a.
One function may call another function. To do this, simply call the desired function from within your function, just as you would from within the main() function. In order for your new function to recognize the other funtion, the other function's definition or proto-type must precede it.
The computer distinguishes between different functions not only based on their different names, but also based on their different parameter lists. This means that if you create two functions with the same name but different parameters, the computer will consider these functions as being different functions that just happen to have the same name. When you call the function, the compiler will decide which function you mean by checking how many and which parameters you passed. Depending on these parameters, the compiler will decide which function to actually call. For example the functions defined by these two function proto-types are different even though they have the same name.
float findArea(float size);
float findArea(float size, float width );
The first function has one parameter and the second function has two, so they are different functions even though they have the same name. The inner working of the two functions can be as different as night and day, or they can be quite similar. This depends on what the programmer writes in the function definitions of the two (or more) functions. Usually the functions will be written to have similar operations since, after all, the name is supposed to reflect what the function does and they have the same name.
When these functions are called, the compiler will choose the function definition that matches the parameters supplied. For example, if I write findArea(7.766, 3.456) then the second function will be called since only the second function has two parameters. When programmers write different functions with the same name we call it overloading a function since the function seems to have two or more different ways of workings. Despite the negative sound of the term, there is nothing wrong with function overloading.
Another interesting feature of functions is the possibility of providing
default parameters. What this means is that if the call to the function is missing some parameters, then the function will provide its own values for the
missing parameters.
Let me give an example. Lets say I want to write a function to compute the
circumference
of a circle given its radius. We know the formula c = 2 * Pi * r
where c is cirumference, Pi is the value of Pi , about 3.14 and
r is the radius.
I can write the function like this:
float circum(float radius, float Pi=3.14)
{
float total;
total = 2 * Pi * radius;
return total;
}
Now if I call the function with one parameter, it will assume that parameter
is radius and will use the value 3.14 for Pi, but if I provide two parameters
when I call the program it will use the second value for Pi in place of 3.14.
This makes sense in this example since the person using my function may want
to compute the circumference of the circle using a more precise value for Pi.
Here is an example of a complete program:
#include<iostream>
using namespace std;
float circum(float radius, float Pi=3.14);
int main()
{
float someFloat;
someFloat = circum (7.0);
cout <<"Circumference using Pi as 3.14 (default)" <<someFloat<<endl;
someFloat = circum (7.0, 3.1416);
cout<<"Circumference using Pi as 3.1416" <<someFloat<<endl;
return 0;
}
float circum(float radius, float Pi=3.14)
{
float total;
total = 2.0 * Pi * radius;
return total;
}
There are many functions already written by people which can be used. These functions are grouped together and are stored in what are called libraries. These different libraries are groups of functions somehow related to each other. In the math.h library there are functions like pwr to raise something to a power, and sqrt to find a square root of a number. There is also a standard library with many useful function. This library is abreviated either stdlib or cstdlib. One useful function in this library is the rand function. The rand function produces a random number. Use it like this:
float a = rand();The function will return a random decimal number between 0 and 1. To get it to produce numbers within a certain range use the modulus operator. Note that the remainder of a division operation will always be an integer between 0 and the number. Thus if I want a random number between 1 and 100 I should write this:
int a = rand()%100 + 1 ;You will notice that rand doesn't really produce random numbers. To get it to do so, you need to use the srand function which "seeds" the rand function so it will start at different points and produce truly random values. The rand function should be run only once in the whole program. Do not run it inside your functions since then it will be run every time your function is called. Also, the srand function takes a parameter by which it seeds. You will want to give it different numbers each time. The easiest way to do this is to use the time function. The time function is found in the time.h library. Here is how to use the srand with the rand function:
#include <iostream> #include <cstdlib> #include <time.h> using namespace std; int main() { int a; srand(time(0)); a = rand()%100 + 1 ; a = rand()%100 + 1 ; a = rand()%100 + 1 ; return 1; }Notice that I included two libraries in addition to the normal iostream library. You should do the same when using the rand and the time functions.
© Nachum Danzig November 2004 - November 2006