SlideShare a Scribd company logo
By: Asaye Chemeda Email: asayechemeda@yahoo.com 1
CHAPTER ONE
FUNCTIONS
Introduction
C++ programs are a collections of functions. Functions
are entities in C++ programs which are used to write
statements. You may have declarations without functions.
However, you can’t make a C++ program to execute
certain statements unless you have a function. For
instance, the following C++ program is intended to
display the sum of two numbers. But, the result will not
be displayed since the program doesn’t have the entity
where you can write C++ statements. In short, since the
program doesn’t have a function, you can’t get outputs.
Program 1.1[Incorrect].cpp
Thus, in C++ program, you need to define functions to
write statements and to get results.
Defining Functions
If you understand the importance of functions, the next
question will be how functions are defined in a C++
program. To define functions, you need three mandatory
and three optional components. The mandatory
components of a function are function name, closed
brackets, and closed braces where are the optional
components are return type, parameters (or arguments)
and return statement. These components will be
discussed as bellows.
Function name. Every function in a C++ program
should have its own name. The name can be any
combination of characters provided that the function
name is not among the reserved C++ words, nor it
doesn’t begin with numbers, nor it doesn’t contain some
reserved C++ characters.
Closed Brackets. The function name should be followed
by closed brackets. These brackets will serve as a gateway
to the function.
Closed Braces. The closed braces should be written next
to the closed brackets. They are used to contain the body
of the function.
Return Type. C++ functions may just execute certain
statements without returning a value or they may return
some values to the entity which called them. Thus,
depending on whether they return values or not, C++
functions can be categorized into value retuning functions
and void functions. The return type for value returning
functions is the same as the data type of the value which
is returned by the function. This can be int, double, float,
char, String, short, long. If a function doesn’t return a
value, its return type will be void. Mentioning the return
type while defining a function is optional. However, if
there is no return type which is explicitly stated, the C++
program assumes the return type is int. While defining
functions, the return type is stated in front of the function
name.
Parameters (or arguments). A function may use inputs
to execute the statements in the body. For instance, if the
task of a certain function is to give the sum of two
numbers which are passed to it, the function needs to take
those values which will be added as an input to give their
sum. Those input which are passed to a function are called
parameters or arguments. Since the closed brackets are
the gateway to the function, the parameters are passed to
the function through the closed brackets. The number of
parameters which a function can take is not limited to
only one parameter. You can pass a number of parameters
with different data type to a function. If a function takes
parameters, the data type of the parameters should also
be stated. Otherwise, the program will assume that the
data type is an integer.
Return statement. If a function returns a value, there
should be a return statement in the function. The return
statement should be the last statement in the function. A
return statement has two components. The first
component is the return word. The other component is
the value which is returned. The value which is returned
may be an expression but should match the return type.
A complete C++ function definition for value returning
functions is shown below.
A complete C++ function definition for void functions is
shown below.
The function name and the parameter lists are together
called signature of a function. The signature doesn’t
By: Asaye Chemeda Email: asayechemeda@yahoo.com 2
include the return type. A signature of a typical C++
function is shown below.
At this point, you are convinced that, any C++ program
should have a function in order to execute statements.
Thus, having function is a necessary condition to execute
statements in C++. One question may be raised here: is
having a function a sufficient condition for C++
programs to be executed? Let us have a look at the
following program which is intended to display “Hello
World!” on the console.
Program 1.2 [Unexecuted].cpp
This program fulfils the conditions that functions are
required to execute statements. It has return type (void),
a function name (helloWorld), the closed brackets, the
closed braces and the function body (the cout
statement). If you run the above program, will it display
the message “Hello World!” on the console? The answer
is no. The above program lacks one thing which every
C++ should have - which is the main function. If you
want to execute statements in C++, the program must
have a main function.
The main function
A C++ program will not be executed unless it has a main
function. One important thing to note here is that the
main function is always the function where a program
starts execution. The main function has a function name
of the word main and a return type of int. The main
function returns a value of int data type to the operating
system. By convention, the return value 0 is used to
indicate the program is executed successfully and other
integer values indicating the opposite. The main function
may or may not take arguments. When the main function
takes arguments, the arguments are two. The first
argument is an integer while the second one is a point to
an array of character pointers. Thus, the signature of the
main function may have one of the following two types.
If a C++ program has main function, it will be executed.
Program 1.2 can now display the “Hello World!” message
if it is corrected to Program 1.3 which is shown below as
it fulfills the two conditions that a program should at least
has one function and that any C++ program should have
main function.
When the above program is run, the function body
between the braces (the cout statement) will be executed
and the “Hello World!” message will be displayed.
The function body may contain any number of statements
and you can put every statement which is required to
perform a certain programming task inside the main
function body. If so, what is the importance of defining
other functions than main function? There are two
reasons for this. The first one is that some programs may
require several lines of codes and it may be unwise to put
all the code in only the main function. Thus, you will
divide the code into a number of manageable pieces and
you will put them in different functions. For instance,
assume you want to write a C++ program to build a
simple calculator. This requires building the user
interface, taking values which will be added or multiplied
or any other operation to be done on, calculating the
result of the operation and displaying the results. If a
program for a simple calculator has all these tasks, each
with a number of lines of codes, why do put all the code
in the main statement? It is unmanageable. For instance,
if you want to improve any of the above tasks you have
to go through the whole main function. The best way to
avoid this is to have different functions performing
manageable pieces of codes.
The second reason to have other functions than main is
to avoid repetition of codes. For instance, in the simple
calculator program mentioned above, the way in which
the output is displayed may be the same whether you
added or multiplied two numbers. So, why do you write
separate statements for displaying results for the addition
and multiplication? Isn’t it better if you have only one
output display function which can be accessed by all the
operations? Doesn’t this avoid repetition of many lines of
codes? Doesn’t this save time, which is a very important
factor if you are a programmed with many projects? If so,
you will definitely agree that other functions than main
may be necessary to attain the above two benefits –
breaking the code into manageable pieces and avoiding
repetition of codes.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 3
When a program has more than one function, how do the
functions interact with one another? If one function
wants to interact with another, it calls the other function.
This may be for one or a combination of the following
three reasons. A function may call another function to get
a certain result or to change the value of some variable or
to print (or display) something. Whichever reason it is, if
a function wants to call another function, it just writes the
signature of the function without the data type of the
arguments at the place where it wants to interact with the
other function. When you write the signature of certain
function, it means that you are interacting with that
function.
You may ask, are there any rules when functions interact
with one another? The answer is yes. One of the rules is
the called function should be written before the calling
function or there should be a prototype of the called
function before the calling function. Before looking into
the details of this rule, let us understand which one the
called function is and which one the calling function is.
This will be illustrated with the following program.
Program 1.4[Correct].cpp
The above program is intended to print the sum of two
values which are entered from the console. In the
program, there are two functions: the mandatory main
function and the add function. The return type of the
add function is double and having a return statement is
mandatory for this function. The function takes any two
arguments which are of double data type. Thus,
whenever it is desired to interact with this function, the
function name (add) must be explicitly stated and two
double values separated by a coma should be passed as
arguments between closed brackets. The identifiers used
for the arguments (a and b) may not be the same as the
identifiers which is defined in the function which wants
to interact with this function. The required return
statement for this function is stated on line 6 of the
program. This line of the function returns the sum of any
two double type values which are passed to the function
as arguments. One this to note here is that, in the return
statement, you can write expressions after the return
word.
The main function has an int return type and takes no
arguments. The body of the function, the part of the
function within the braces, starts with defining statement
of three variables a, b and c which are of double data
type. This is the first statement which will be executed in
the program as execution of statements in C++ programs
from the main function. The next statement is taking the
values of a and b respectively as an input from the
console by using cin. Line 13 of the program is the place
where the main function interacts with the add
function. In this line the value c is assigned with the
signature of the add function. Since the add function
returns the sum of two double values which are passed to
it and since on the signature of the add function on line
13, the values or a and b are passed, the value of c will
be assigned with the return value the add function. In
other words, on line 13, the main function has called the
add function to assign the value of c with the sum of a
and b. Thus, the main function is the calling function
as it is calling another function and the add function is
the called function as it is called by another function.
If you run the above program, you will be prompted to
enter two values on the console and their sum will be
displayed after entering the second number.
Now, any doubts regarding the calling and the called
function are cleared and let us proceed to the details of
the rule mentioned above. Before that, try to run Program
1.4 by placing all the components of the add function
after the main function. Did you get the result which you
expected? Did the program even pass the compilation?
The answer is no. Mind you, you just only place the add
function after the main function and you didn’t remove
or add anything to the existing functioning program. So,
why is the program not free of compilation errors? If you
remember the rule, it says you can’t put the called function
after the calling function unless there is a prototype of the
called function before the calling function. There is a
compilation error now because the called function (add)
is placed after the calling function (main) and there is no
prototype of the called function (add) before the calling
function (main). If there are more than one interacting
functions, there are two available options for having a
working program. The first option is to place the called
function before the calling function.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 4
The second option is to put the prototype of the called
function before the calling function and you can put the
called function after the calling function. The first option
may sometimes create ambiguities for the person who
came up in dealing with a program written by another
person as it often happens in programming work places.
Imagine you are dealing with a program written by
another person. What you normally do is you will go
through the program from the top to down and if the
program is written by the first of the above mentioned
two options, you will first encounter the called functions,
which can be several of them, and you don’t know when
and why they are called. So, you will get confused. To
avoid this, the second option is frequently used in
programming community. As mentioned earlier, the
second option requires putting the prototype of the called
function before the calling function. This is called
prototyping. So, what prototyping is and how it is done
will be the next topic.
Function Prototyping
Function prototyping is declaring a function without
including the body of the function. Thus, a function
prototype includes the return type of the function, the
function name and the argument lists. A function
prototype ends with a semi-colon like other C++
statements. When a functions is declared by prototyping,
the identifiers used for the arguments are dummy
variables (can take any appropriate variable identifier) and
they can be omitted. A complete function prototype will
have one of the following forms without any change in
the outcome.
Program 1.4 can now be modified to the following
program without any change in the outcome of the
program.
Program 1.5[Correct].cpp
Program 1.5 can be compiled without any errors even if
the called function (add) is placed after the calling
function (main). This is because the prototype of the
add function is placed before the main function on line
5. In the prototype of the function on line 5, the return
type, the function name and the data type of the
arguments match to that of the actual add function given
in line 16 as it should be. In the prototype, the identifiers
of the arguments are omitted as any identifier can be used.
Let us try to add one additional function to Program 1.5.
The task of this function will be displaying a message that
says the sum of a and b is c. The name of the function
will be printSum and it will not return any value, it just
prints. As a result it should be of void return type. The
function will replace line 12 of Program 1.5. Thus, the
printSum function will be called from line 12 of the
main function. Since a, b, and c are defined in the main
function and since this function doesn’t make any
calculations, why should this function take any
arguments? If you say so, the function will be defined with
empty parameters. Of course, don’t forget to put either
the function or the prototype before the calling function.
Now the program appears to be:
Program 1.6[Incorrect].cpp
In this program, a new function printSum is defined
and it is called from line 12 of the main function. Now,
try to compile the program and see if there are any errors.
Of course there are. Specifically on line 21 of the program.
Oh, did I forget to put the prototype before the calling
function? No! It is already on line 6. Did I miss any semi-
colon? No! Then, why are the errors occurring although
the program seems faultless. The errors occurred due to a
concept known as scope in C++.
Scope of Variables
Scope means the limit which a piece of code at one place
of the program has in order to access and use a piece of
code at another place. In C++, variables which are
defined inside a function can only be accessed and used
By: Asaye Chemeda Email: asayechemeda@yahoo.com 5
by a code inside that function. Thus, the scope of the
variables declared inside a function is only within the
function itself. Note that there may be exception to this
rule and that exception will not be dealt in this chapter.
Variables which are defined within a method and which
have a scope within the function itself are termed as local
variables. There are also variables which are defined
outside functions. The scope of these variables is not
limited to any function and such variables can be accessed
from anywhere within a given program. These type of
variables are termed as global variables.
At this point, what you have to note is, unless additional
key words are used, the scope of a variable defined in a
function is within the function itself. Which means that
the add function cannot directly access and use the
variables a,b and c in the main function and the same is
true for the printSum function. I see! Apparently, the
printSum function which dared to print a message that
the sum of a and b is c can’t actually access neither of
these variables. Now, you understand what line 21 of
Program 1.6 was trying to do. It was just like printing an
undefined variable c which is presumed to be the sum of
two undefined numbers a and b. Can you use variables
without defining them in C++? Of course not! That is
why the error occurred. What could be a solution for this?
There are a number of solutions and one of them is to
pass the variables a,b and c to the printSum function
as arguments. The following program will be perform the
intended task in program 1.6 without any compilation
errors.
Program 1.7[Correct].cpp
Note the changes on line 6, line 12 and line 21. Another
thing to note is when the main function calls the
printSum function on line 12, it passed a,b and c
respectively as arguments but the printSum function
accepted x,y and z respectively as arguments. This
doesn’t have any problem. Because, what the printSum
function does is printing the sum of the first argument
which is defined as x in the printSum function (but
which can be defined as any name in the calling function)
and second argument which is defined as y in the
printSum function (but which can be defined as any
name in the calling function) is third argument which is
defined as z in the printSum function (but which can
be defined as any name in the calling function). So, when
you pass arguments to another function, the name of the
arguments don’t matter. It is their order which matters.
To understand this, let us have a close look at line 12 and
line 20 of the program. These lines are extracted and put
as follows:
When a call to the printSum function is made on line
12, the first place where the call goes to is the prototype
on line 6. The prototype checks whether the data type of
the arguments passed on line 12 actually match those
stated in the printSum function. If the matching is
successful, the call goes to the implemented function
which is on line 20 of the code. At this point, the
printSum function will assign its variables (x,y and z)
with the corresponding variables in the call. For instance,
the first argument in the call (line 12) is a and the
printSum function will assign the first variable in its
argument list (x) by a. The same is true for the other
arguments. In other words, the first thing which
printSum function does is implicitly assigning its
arguments as follows:
As a result, even if the variable names used in the calling
and the called function are different, the outcome will be
the same. Try to switch the places of a, b and c on line
12 and see the printed message.
At this point, you understand that one way to grant access
for other function to use variables defined in a given class
is by passing them as arguments. Now, let us have more
fun by writing another program and let us grab a new
concept. The program which we are going to write takes
two values a and b from the console and swaps the values
of a and b and prints the swapped values. The variables
will be defined and their values will be read in the main
function while the swapping will be done by another
function. Let use call the function swap. But, C++
already has a built-in function called swap which
performs a similar task to what we are going to do. By the
way, C++ has several built in functions which perform
By: Asaye Chemeda Email: asayechemeda@yahoo.com 6
some specific tasks which can be used at the user’s
convenience. Nice! This simplifies your job as a
programmer since you don’t have to write everything to
write a functioning program. Let us get back to our
program and to avoid any confusion let us give a name of
swapValues for our function. The values of a and b
will be passed to the swapValues function as
arguments in order to grant access for this function to use
the variables. The swapValues function just swaps the
values of a and b without returning any value. Hence, its
return type will be void. Here is the program:
Program 1.8[CannotSwap].cpp
In the above program, the swapValues function takes
two values of double data type and swaps their values i.e.
it gives the value of a to b and the value of b to a.
Another variable x is also defined to take the original
value of a so as not to lose the value of a in the process
when the value of b is assigned to a. In the main
function, there are two cout statements. The first one
displays the values of a and b before swapping. The
second cout statement comes after the swapValues
function is called. Thus, it is expected that the values
printed by this statement will be the reverse of the first
cout statement. For instance, if you enter the value of a
as 1 and the value of b as 2, you will expect that the first
cout statement prints “ …1 and 2” and the second
cout statement prints “… 2 and 1”. Run the program
and see the result. Did you get the result which you
expected? Surely not! Check the swap function again. Isn’t
it swapping the values of the arguments which are passed
to it? Of course it does! So, where did it go wrong?
Apparently, there is nothing wrong with the program.
But, one detail is missing. When you passed the value of
a and b (which are defined in the main function) to the
swapValues function, you just passed the values of the
variables to the function. Again, when the swapValues
function accepted the values of a and b, it just accepted
the values of the variables. In such cases, whatever the
swapValues function does, has no reference to the
main function. This is called passing parameters by
values. If a calling function passed parameters to the
called function by value, then the called function cannot
change the original values of the parameters in the calling
function.
Now, you have got the clue why the values of a and b
were not swapped. Even if the swapValues function
swapped the values of the arguments which are passed to
it, it doesn’t actually swap the original values in the main
function. The swapping only remains in the
swapValues function. This is because the values are
passed by values. Can we do anything to change the values
of parameters in a calling function from a called function?
Of course, we can! C++ has the facility to do this. It is
called passing by reference or calling a function by
reference.
Call by Reference
C++ has a facility in which two identifiers can be used to
refer to the same variable. Such variables are termed as
reference variables. To create a reference variable, an
original variable should be first defined. The reference
variable and the original variable refer to the same data
object in the memory. The C++ syntax used for creating
reference variable is as follows.
To understand how reference variables work, look at the
following program.
Program 1.9[Correct].cpp
In the above program, a variable named a was defined on
line 6 and it was initialized with a value of 10. On line 7, a
reference variable to a was defined as b. Note the &
operator which was used while defining b. On line 8, the
value of b was doubled. On line 9, the value of a was
printed. What do you think will the displayed value be? If
you are not familiar with reference variables, your answer
will be 10. You are reasonable to say so because there is
no any statement which directly changes the value of a.
Run the program and see the result. It is 20. How come?
By: Asaye Chemeda Email: asayechemeda@yahoo.com 7
This is because after b is defined as a reference variable
to a on line 7, both variables (a and b) refer to the same
memory location. As a result, whatever operation you
perform on either of them, the other one will also pass
through the same operation. If you double the value of b,
the value of a will also be doubled automatically. Since
the value of the reference variable (b) is doubled on line
8, the value of the original value (a) will also be doubled.
You will also get the same result if you double the value
of a and print the value of b. Now, it is pretty clear what
reference variables are.
After understanding the concept of reference variables,
did you get any idea on how you can alter the value of
variables in the calling function from the called function?
Remember, if you define a reference variable to a variable,
you can alter the value of the original variable by altering
the value of the reference variable. If so, to alter the value
a variable in a calling function from the called function,
why don’t you define a reference variable in the called
function referring to the original variable in the calling
function? Will there be any problem if you try do so?
There might be. The problem is the called function should
get access to the original variables in the calling function.
Of course, you know the solution for this problem. The
solution is you can pass the variables as arguments. Right?
Now, you understand the framework about how variables
in the calling function can be altered from the called
function. Let us go to the details.
First, let us see the available options in which a reference
variable in the called function is created and their
feasibility. For this, we will refer back Program 1.8. To
define a reference variable to a and b in the
swapValues functions, there are three options.
The first option is if we can call the swapValues
function from the line 11 of the main function as below:
This is possible. But, understanding the detail requires a
concept which will be discussed in chapter three.
Therefore, we will skip this option for the time being.
The second option is the pass the values of the original
variables when the swapValues function is called in
the main function. This means, line 11 of the program will
not be changed. Again when the swapValues function
takes the variable from the main function, let it take the
actual values of the variables. Then, in the swapValues
function, let us define reference variables to a and b and
let us swap their values. What do you think of this second
option? It is just like back to square one. Right? Because,
this is no different from the Program 1.8, which failed to
swap the original values in the main function. To
understand this better, go back to Program 1.7 and revise
what we said about how the called function creates its
own new variables and assigns the values of these
variables with those of the calling function according to
their sequence. There will be no reference made to the
calling function variable. Thus, if a value is passed to the
called function, the changes which are made in the called
function will remain in the called function. Even if you
define reference variables in the swapValues function,
the defined reference variables will refer only to the new
variables which are defined in the signature of the
function; not to the values in the calling function. As a
result, the second option is not feasible.
Let us see the third option. If you understand, the
drawback of the second option, it is easy to guess what
the third option might be. The main drawback of the
second option is that, the called function will not have
control over the calling function variables once they
passed the gateway into the body of the function. What
can we do then? To answer what we could do, once again
refer back to Program 1.7. Specifically, note how the
called function implicitly assigns its variables in the
argument list with the variables passed to it. This one
concept. Also, refer back to how reference variables are
defined. Another concept! Do you see a common point
in these two concepts? Of course you do. What if you
define a reference variable to the calling function on the
signature of the called function itself? Doesn’t this solve
all of our problems which we had?
Defining a reference variable on the signature of the called
function to the original variables in the calling function
will make it possible to alter the values of the variables in
the calling function from the called function. This is what
is called passing by reference or calling a function by
reference. Now, Program 1.8 can be modified as follows.
Note that changes are made only on line 5 and line 16 of
program 1.8.
Program 1.10[Correct].cpp
By: Asaye Chemeda Email: asayechemeda@yahoo.com 8
What this program does which is different from program
1.8 is that the swapValues function defines reference
variables of the original variables in the main function in
its signature. As a result, the variables in the main
function and in the swapValues function refer to the
same memory location. Therefore, whatever the
swapValues function does to its arguments, the
changes will persist to the original variables in the main
function. When the arguments of the swapValues is
changed, its prototype on line 5 should also be changed.
Now, run the program and see the result. Now, when the
values of a and b are printed before and after calling the
swapValues function, they are actually swapped.
The advantage of passing by reference is three fold. The
first one is to alter values of variables from an outside
function. The second one is to return more than one
variable from a function. Value returning functions return
only one value through their return statements. However,
if calling by reference approach is used, a function can
return more than one value. In Program 1.10, the program
actually returned two values – the swapped values of a
and b. The third advantage of passing by reference is
saving memory space. Since the original variables and the
reference variables refer to the same memory location, a
lot of memory space which could have been wasted by
defining two separate variables in each of the functions
can be saved.
Let us raise an interesting question here based on the
three advantages of passing by reference. Say, within a
program, you want to save memory by using pass by
reference but you want to restrict any changes to the
reference variable. Can we do this in C++? The answer is
yes. What we need to do is put a qualifier const before
the data type of the reference variable in the argument list
of the function and in the prototype. However, when you
add the qualifier const in front of the data type of a
reference variable any attempt to change it, will result in
compilation error.
For instance, you can change the signature, and of course
the prototype, of the swapValues function in Program
1.10 as follows.
This restricts any change to reference variable a (and
therefore the original variable a in the main function)
within the function. When you try to run the program you
will get an error message on line 18. Because on that line
you tried to change the value of the reference variable.
Isn’t this reference concept interesting? Indeed it is! But,
have we covered what we have to know regarding
reference at least for this chapter? A little more remains.
A function can take reference of another variable as
arguments. This enables a function to alter the values of
the variables to which the reference is made. Interesting!
Let us think both ways and ask this question: is it possible
to get reference of the variables returned by a function?
Thanks to the C++ developers, the answer is yes. If you
think of the potential effects of this possibility, you will
realize that C++ program is indeed versatile. If a function
returns values which you can’t have reference, then the
function is returning by value. You can also have
reference to what is returned by a function. This is the
concept which has to be covered before concluding the
reference concept for this chapter.
Return by Reference
If a function returns the reference the return value, the
function is said to be returning by reference. At this
point, you are expected to know how reference variables
are defined. It was easy, right? If you have any doubt, go
through the topic of calling by reference. That is how
things work, if you want to be good at programming, you
will deal with it till you understand it completely. No
giving up!
To understand the concept of return by reference, we will
try to solve one mathematical problem. Are you expecting
some calculations? Not really. We will just write a
program to solve it. The problem is as follows. Assume in
a certain mathematical problem, the value of a certain
variable can have a value from 0 up to 3 only. If part of
the calculation results in a value to the variable outside
this range, the variable takes the maximum value, i.e. 3. If
the variable is x and you express it with a mathematical
equation, it appear like:
‫ݔ‬ = ൜
|‫|ݔ|	݂݅		|ݔ‬ ≤ 3
			3			݂݅|‫|ݔ‬ > 3
What we are going to do next is writing a program which
gives the value of x for any value entered from the
console. C++ has built-in absolute value function, but we
will write our own absolute value function since it is very
easy. The absolute value function which we are going to
define will have a function name of abs. Just to recall
what an absolute value function will do, it gives the value
of the number if the number is positive or zero or the
negative of the number if the number is negative. As the
negative of a negative number is positive, you will always
have a positive value of a number after passing through
the absolute value function. The program is given below.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 9
Program 1.11[Correct].cpp
In the above program, a global variable absValue is
defined on line 4. Who can access this variable then?
Every piece of code in the program can access this
variable. Because the scope of global variables is not
limited to any function or any piece of code. The abs
function is placed before the calling main function. Do
you have to define a prototype for the abs function? Of
course, you don’t have to. The abs function takes
arguments by reference. Do you remember what this will
do? If the abs function takes an argument by reference,
it can change the value of the variable use as an argument
in the calling function as it wants. As a result, when the
variable value is changed in the abs function, the
variable x in the main function will be changed in the
same manner. If you want this not happen, i.e. if you want
the abs function not to change the value of x in the main
function and if you just want to use the return value of
the abs function, you know what to do. Just avoid the &
character from the signature of the abs function.
By putting the & character from the signature of the abs
function, you have made the x variable of the main
function to have whatever the value variable of the
abs function gets. In the abs function, the value
variable is changed on line 11 only. What if you remove
this line from the program? The function still returns an
absolute value of any value passed to it but the value of x
in the main function will not be changed. Confusing? Just
understand the following and it will no longer be
confusing.
The reference variable to the x variable in the abs
function is the value variable which is defined on the
signature. Do you understand this? Good. If a variable has
a reference variable when will it change? It will be changed
when the original variable is changed or when the
reference variable is changed. Right? If neither of them
were changed, then there will be no change in the original
or reference variable. Since the only reference variable in
the abs function to the x variable in the main function
is value, the value of x will be changed only when the
value of the value variable is changed. In the abs
function, the value variable is assigned with a new value
only on line 11. If this line of the program is removed,
then there will be no change to the value variable and
there will be no change to the x variable either.
Here comes the question which is relevant to this topic.
Can you change the value of the value variable from the
main function? Not directly, but you can. If you want a
local variable to be changed outside the function return
that local variable and make the function to return by
reference. Do you know the reason why you can’t directly
change the value variable from the abs function? It is
because of scope issue. The value variable is a local
variable and it cannot be accessed from outside of the
abs function. And since the value variable is not the
return value of the abs function, you cannot change its
value at all from outside the function even if you make
the function to return by reference.
To make a function return by reference put the &
character in front of the function name. The reason why
the & character is put in front of the abs function is to
make the function return by reference and you will have
reference to what is returned by that function. By putting
the & character in front of the abs function, we now have
the reference to the absValue global variable and we
can change its value as we want by calling the function.
That is what we did on line 19 of the program. We
assigned the return value of the abs function by a value
which wanted. In the program, an abs(x) value is
compared with 3 on line 18 and assigned with 3 if it results
in a value greater than 3 on line 19. That is what the
problem statement of the program said. After that, there
is a cout statement on line 21 of the main function. It
will display the value of x and absValue respectively
along with other characters. Now, run the program and
enter -10 as an input. The message which you are be
expecting on the display console might be this one:
You are reasonable to expect this. Because when you pass
-10 as an argument and call the abs function for the first
time on line 18, the value of x will be changed to the
absolute value of -10, which is 10. You know why the
value of x is changed. It is because the function call is
made by reference and the reference variable to x
(value) is changed inside the abs function. Therefore
expecting the displayed value of x as 10 is reasonable and
By: Asaye Chemeda Email: asayechemeda@yahoo.com 10
right. But what about the displayed value of absValue?
Is the displayed value what you expected? It is again
reasonable to expect its to have the same value as x.
because there is no statement where its value explicitly is
changed in the main function. However, when you run
the program, the message which you will get is this one.
You are correct about the displayed value of x. it is indeed
10. But the displayed value of absValue is 3. If you
understand the concept of returning by reference, you will
know why. Since there is & character in front of the abs
function name, you can change the return value of the
function by calling and assigning the function to any value
which you want. That is what line 19 of the program did.
It assigned a maximum value of 3 to the return value of
the abs function. This wouldn’t have been possible, had
the abs function returned by value. To understand a little
bit more, let us answer the following string of questions.
What is the return value of the abs function? It is
absValue. Look at line 12 of the program. What type
of return method is used by the abs function? It is return
by reference. Look at the & character on line 5 in front of
the function name. What happens when a function
returns by reference? You can change the return value (i.e.
absValue) by calling and assigning a value to the
function. Where, in the program, did you call and assign
a value to the abs function? On line 19. Which means
that, on line 19, you set the maximum value to the
absValue variable to 3 by using if statement.
Therefore, if the absolute value of a number is greater
than 3, the abaValue variable will have a value of 3.
Since the absolute value of -10 is greater than 3, the
displayed value of absValue is 3. By the way, you could
have also limited the value of absValue to 3 in the main
function itself without calling the abs function. Because,
the absValue variable is global and you can access it
and change its value from anywhere in the program. The
desired value of x which is stated in the problem
statement is obtained from absValue variable not x.
That is what returning by reference means. There you go.
Are you bored? You might be because we spent much
time on the same topic. But, it was worth. Right? You
grabbed some interesting and basic concepts in C++. By
the way, if you understand about functions, it means that
you have understood one of the core concepts of the
C++ language. To make it interesting again, let us switch
to another concept regarding functions.
This time, let us deal about function names, return types
and argument lists in detail. When we say argument list,
we mean the argument variables and their data types
altogether. Can you guess what will happen if you define
two functions with the same function name, with the
same number and data type of arguments and try to
compile it? The compiler will send an error message even
if their return type is different. For instance, look at the
following program.
Program 1.12[Incorrect].cpp
In the above program, there are two functions other than
the main function. The functions have the same function
name (print), the same number of arguments (one) and the
same data type of the arguments (double). Since the number
of arguments is the same, the sequence of the data types of the
argument list is also the same. Therefore, the functions
have the same signature. If the functions vary by any of
these four highlighted factors, they no longer have the
same signature. But, one of the print functions takes a
local variable named a while the other takes b as an
argument. If so, why are their signatures the same? As we
said earlier, the names which you give to the arguments
are dummy variables and you can give it whatever name
you want without affecting the outcome. As a result, these
dummy variables will not be used as a criteria to compare
whether two functions have the same signature or not.
If a program contains, two or more functions with the
same signature, it will have compilation errors if you try
to compile it. When a function call is made, you only write
the signature of the called function. If a program has two
functions with the same signature, which function will the
compiler invoke when the function is called? The
program will get confused. The program is logical here. It
is us who are trying to confuse the program. To stop
confusing the program, let us make only one change in
Program 1.12. Let us change the data type of the
argument of the second print function from double to
int. If you do so, by the criteria stated above, the two
print functions will no longer have the same signature.
Right? Because, the data type of the only argument which
they take is different. This makes them to have different
By: Asaye Chemeda Email: asayechemeda@yahoo.com 11
signatures. Have a look at line 8 of the changed program
below.
Program 1.13[Correct].cpp
Note that the print functions take an arguments and
print its value. The value is printed as “ …value of
a…” in the first print function and “…value of
b…” in the second. The print function is called on line
13 of the program from the main function and the value
of variable x is passed to the function as a parameter. The
variable x has double data type and is initialized with a
value of 100. If you run the program, there will be no
compilation error now. Because the only cause for the
compilation error in Program 1.12 is now gone. If you
remember the cause, it was having two functions with the
same signature within the program. As stated above, the
two print functions in program 1.13 are not identical
any more.
When a function call is made on line 13, is the program
now confused to which print function will he go to?
Not anymore. It goes to the print function which has
the same argument data type as the data type of the
variable passed to it. You see how smart the program is!
The data type of x is double and when the print
function is called, the program directs the call to
whichever print function which takes a double value
as an argument. It is the first print function which takes
double value as an argument. Therefore, the value of x is
printed as “… value of a…”. Have a look at the
message below which results when the program is run.
See what happens when the data type of x is changed to
int. in addition try to call the function by passing different
data types directly. For instance, change line 13 of the
program with print(10.0);, print(10);and
print(‘x’); and see what happens. Repeat these
changes after changing the data type of the argument of
the second print function to float. If you notice some
interesting results, why those results occurred will be
reasoned out in the next topic when another interesting
concept in C++ is discussed. When you deal about
object-oriented programming in C++, you often need
functions to have the same name but different signature.
This happens if the functions take different number or
data type or sequence of data type of the arguments. If
you define functions having the same name but different
signature in a program, then you are over-loading that
function. Since we are discussing about functions now, it
is worth dealing about this concept in detail here.
Function overloading
In C++, especially in object-oriented programming, the
name of functions may be restricted but you may want to
call those functions by passing distinct parameter lists. In
those situations, you have to define the functions with the
same name but different signatures. Defining two or more
functions in a program with the same name but different
signature is called function overloading. We have
already seen how function overloading is done in Program
1.13. However, to understand some rules regarding which
overloaded function is invoked by the compiler during a
function call, we will write another program. For this,
eight overloaded functions will be defined. Is that too
many? You will see it will be worth the number. We will
try to call the function by passing different parameters and
we will note which function is invoked. When a function
gets invoked, it prints a message which has the function’s
rank number in the vertical order. So, we know which
function was really invoked from the output message.
Here is the program.
Program 1.14[Correct].cpp
By: Asaye Chemeda Email: asayechemeda@yahoo.com 12
As you can notice in the above program, all the functions
other than main have a function name of print. But all
the functions have different signature i.e. some of them
have distinct data type of arguments, some of them have
different numbers of argument and the others have
distinct sequence of data type of arguments. But all of
them have a unique signature. Thus, we can say that they
are overloaded functions.
We will call the print function by passing different
parameters from line 29 of the main function and run it
each time. If you run the program as it is, the output is:
The first print function invoked.
This result is displayed because on line 29 of the program,
the print function is called with empty parameters. As
a result, the compiler invokes the print function which
takes no parameters. In the vertical order, this particular
print function is the first one in the program. If you see
the body of the function, it has a cout statement which
prints the above message. Therefore, when an overloaded
function is called with empty parameters, the compiler
invokes the overloaded function which doesn’t take any
parameters.
Now let us change line 29 of the program with the
statement below and run the program. i.e. let the function
call passes a value of 10 (with no decimal point).
print(10);
If you look at the output, it is:
The second print function invoked.
If you find out which print function displays the above
message when invoked, it is the print function which
takes int parameter. Do you see the reason why the
complier invoked this particular print function? It is
because the compiler considers a value of 10 without a
decimal point as an integer and it invokes the overloaded
print function which takes a similar data type argument
as the passed argument data type.
Rule 1: when a function call is made to an overloaded function, the
compiler will first try to find and invoke the function which takes the
same data type and the same sequence of data types of arguments as
those of the arguments passed from the calling function.
Which means, if an int data type is passed as an argument
from the calling function, it is the overloaded function
which takes argument with int data, if there is, which will
be invoked.
Let us make what we are doing more interesting by
replacing line 29 of the program with the following.
print(10.0);
Now, we added a decimal point to the number 10 which
was passed in our previous attempt. If you run the
program again and have a look at the output, it is:
The fourth print function invoked.
This output message will be displayed by the print
function which take a double data type argument.
Reasonable. Right? If a number has a decimal point, it is
considered as a floating point number. And when a
floating point number is passed, the compiler will invoke
the overloaded function which takes an argument which
matches this data type. You can raise an interesting
question here. In addition to the double data type, the
float data type is also used for floating point data types
like 10.0 and there is a print function which takes float
data type as an argument. If so, why did the compiler
prefer the function with double data type argument list?
Before answering this question, let us see how the C++
data types are classified.
In C++, data types are classified into simple, structured
and pointers. Since their significance for this topic is
minimal, we will not discuss about the latter two here. The
simple data types are further classified into three
categories as integral, floating-point and enumeration.
The integral category can only deal with numbers and
variables without decimal places. The int, char and bool
data types fall in the integral data type category. In this
category, the int data type has higher level than the other
two. The floating-point category can deal with any
numbers with or without decimal places. The floating-
point category contains float and double data types.
Among these two, double has higher level than float.
When we go back to our question and reason out why the
compiler preferred double over float, it is because double
is at higher level than float.
Rule 2: if function call is made to an overloaded function and the
compiler has the option to choose between different data types in the
same category, without data type conversion, the compiler will invoke
the function which takes arguments with a higher level data type
among the list of options.
Therefore, if two overloaded functions exist one of them
taking argument with float data type and the other taking
with double data type, and if a floating-point number
(not variable) is passed as an argument, the compiler
invokes the function which takes an argument with
double data type. However, if a variable is passed, the
compiler will invoke the function which takes the same
data type as the variable, whether it is double or float. To
understand this more, define a variable with double or
float data type, initialize it and pass it as an argument and
see which function will be invoked.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 13
Now, have a look at all the print functions and their
argument lists. Is there any one of them which takes an
argument with char data type? None, right? But let us
pass a parameter of char data type and make a function
call and see what happens. Just change line 29 with the
following and run the program.
print(‘c’);
The following message will be displayed.
The second print function invoked.
If you note which print function was invoked, it is the
one which takes an int data type argument. The passed
argument is of char data type and the invoked function
takes int data type. Why so?
When a char data type is passed, the compiler will look
for the overloaded function which takes a char data type
argument (Rule 1). If the compiler couldn’t find any, the
compile will invoke the function which takes int data type
(since int is at higher level in this group, see Rule 2).
Rule 3: if function call is made to an overloaded function and Rule
1, which is stated above, failed, the compiler will look for and invoke
the function which takes a data type which is at higher level in the
same category as the data type of the passed argument.
Read Rule 2 in detail first and a basic point regarding Rule
2 should be discussed at this point in accordance with
Rule 3. If there is a data conversion, for instance, from int
to double or float, Rule 2 is not valid anymore and the
compiler will result in an error.
While trying to invoke an overloaded function, if all the
above three rules fail and the compiler finds it ambiguous
to choose between two functions, the compiler will send
an error message. For instance, try to replace line 29 of
the program with the following and run it.
print(10.0,10.0);
When you run the program, the compiler will get
difficulty in choosing between the seventh and eighth
print functions. Because with the above three rules,
you cannot justify which one the compiler should have
invoked. But try to make the data types of both the
arguments of the last print function double and run
the program. Now, you will see that this changed print
function will be invoked because of Rule 2.
Do you think that sequence of data types also matters in
selecting which function to invoke? Of course it does. If
you see the fifth and sixth print functions closely, both
take a double and string data type but with a different
sequence. Which print function will be invoked if you
change line 29 with the following statement and run the
program?
print(10.0,”C++”);
It is the fifth print function, right? Because, this
particular print function has the same sequence of data
type of arguments as the passed arguments. Therefore, its
invocation is not a surprise. This concludes our discussion
on function overloading.
Before proceeding to the last topic of this chapter, let us
see some real world C++ functions. Suppose you are a
programmer in a bank and you are given a task of writing
a piece of code by your boss. The piece of code which you
have to write is a function which calculates the current
amount of money for the bank’s customers. Obviously,
the current amount is dependent on the principal amount
of money (the value at the previous current amount), the
period between the previous and this current amount
calculation and the interest rate. In short, the current
amount is dependent three variables: principal amount,
period and interest rate.
Based on what we discussed so far, you will tend to define
a function which takes three parameters. Or do you have
another approach? Unless one or more of the three
variables is defined as a global variable or unless you
obtain their values by calling another function or other
object-oriented programming approach, the function
which you are going to write should take the values of
these variables as parameters.
Let us say your function takes these three variables as
parameters. As employee of the bank, say, you know that
the interest rate of the bank changes only in rare
conditions. Therefore, it may be unwise to create a
function which always takes the value of this variable as
an argument. At the same time, if you remove it from the
argument list, your function will not work in those rare
conditions where the interest rate might change. So, what
would you do?
There is another approach which you can do. It wasn’t
discussed in this chapter but it will solve your problem.
Here is the solution. You will still make your function to
take three variables but you will initialize the interest rate
variable on the signature of your function with the rarely
changed interest rate value. You have to also make this
variable, the right-most variable in the argument list. What
will happen if you do so? Your function can be invoked
by passing only the other two variables. If your function
is called with only two parameters, by default, it takes the
initialized value the interest rate from the signature and
calculates the current amount. If the bank changes its
interest rate, your function can be called with three
parameters, the third parameter being the new interest
rate value. When your function is called with three
By: Asaye Chemeda Email: asayechemeda@yahoo.com 14
parameter, it will not use the initialized interest rate value.
It will use the new one. Problem solved!
By the way, do you know what such kind of parameters,
like that of the interest rate, are called? They are called
default parameters in C++. If you initialize parameters, in
the signature of the function, those parameters are called
default parameters. Default parameters should always
be written on the right hand side of the argument list.
When you call the function, you can omit passing the
values of default parameters. In a function having more
than one default variable, if you omit a default variable, all
the default parameters on the right hand side of the
omitted default parameter should also be omitted. During
function call, if the default parameter is omitted, the
function uses the default values in the signature. If you
pass the values of the default parameters during a function
call, the passed values will override the default values.
Interesting! Isn’t it? The default parameters concept made
your function to be dynamic. Let us see if there are ways
by which a function can be made more dynamic in C++.
Now consider another scenario than your bank
assignment. What if you want to make a single function
take unlimited numbers of arguments with unlimited data
type? Is there a possibility? Of course, there is. Didn’t we
say, C++ is versatile? You can also define a function
which takes unlimited number of arguments in C++. To
define such a function, two conditions are mandatory
though. The first one is, the function should have at least
one defined argument. The second one is you have to put
three dots after a coma on the right hand side of the
signature of the function. That is it. If you define a
function fulfilling these two conditions, the function can
now take any number and data type of arguments. In this
case the function is said to take variable-length
argument lists.
To understand the concept of default parameters and
variable-length argument lists, have a look at the following
program.
Program 1.15[Correct].cpp
In the above program, the print function has one
default parameter (a) which is initialized with a default
value of 1. On the right hand side of the signature, there
are three dots after a coma. Therefore, we expect the
function to take any number and data type of arguments.
When this function is invoked, it will display two
messages which you can see from the body of the
function. One of them is printing the value of the default
parameter.
The print function is called from the main function
three times by passing different number and data type of
arguments. All of these invoked the print function. The
first call with empty parameter invoked the print
function only because the only mandatory argument in
the print function is a default parameter. If you remove
the initialization from the signature of the print
function, there will be compilation error. Because when
you call functions with variable-length argument lists, you
have to at least pass one argument unless that argument
is a default parameter.
The displayed message when you run the program is
shown below.
From the output message we can notice that the print
function is invoked three times. During the first
invocation, the value of a was not passed and the default
value is printed. During the second and the third
invocations, the passed values of a were printed
overriding the default value.
We have almost covered what we have to discuss in this
chapter. Only one topic is remaining. The concept which
we are going to discuss in this last topic will help us
understand a way by which we can reduce the
computation time while working with frequently called
functions. When normal functions are called there are
overhear (regular) function call procedures. These
procedures might take a considerable computation time
and under certain programming circumstances, every
nanosecond might be precious. At the compiler’s will,
however, there is a way by which we can avoid these
overhead function call procedures, by using special types
of functions. These special functions will be the last topic
of this chapter.
Inline functions
In an environment where computation time is very
precious, avoiding the overhead function call procedures
might be very useful. C++ has the facility to avoid these
By: Asaye Chemeda Email: asayechemeda@yahoo.com 15
procedures, at the compiler’s will, by using special
functions called inline functions. When inline functions
are called in a program, the compiler will replace the call
by the corresponding code of the functions. In other
words, the body of the inline functions acts as if it is
expanded at the place where the function is call is made.
Because of this, those overhead function call procedures
will be avoided.
To make functions inline, putting the inline keyword in
front of the function definition is sufficient. Putting the
keyword will request the compiler to expand the function
inline while it is invoked. The compiler will not take this
as a command and the functions will be expanded only if
the compiler accepts the request. If the compiler finds the
function to be too complicated, it may reject the request
and consider it as a normal function even if there is an
inline key word in front of the function definition. It is
advisable not to have prototype of inline functions.
Because if an inline function has a prototype, the compiler
will consider it just as a normal function.
There may also be a drawback associated with inline
functions. As one of the benefits of having functions is to
save memory, when the compiler expands the inline
function at the place of the function call, this benefit may
be lost.
The following program shows an example of an inline
function.
Program 1.16[Correct].cpp
In the above program, the maximum function is an inline
function. If the compiler expands the function during the
function call. The above program is equivalent to the
program shown below.
Program 1.17[Correct].cpp
Our discussion about one of the fundamental concepts in
C++, function, is now over? It was interesting, right?
Hopefully, you have grasped the basic knowledge about
functions. There is a lot more to grab and let us go for it.

More Related Content

What's hot (20)

Assignment2
Assignment2Assignment2
Assignment2
 
Ch02
Ch02Ch02
Ch02
 
Ch04
Ch04Ch04
Ch04
 
Constants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya JyothiConstants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya Jyothi
 
Assignment5
Assignment5Assignment5
Assignment5
 
Cpu-fundamental of C
Cpu-fundamental of CCpu-fundamental of C
Cpu-fundamental of C
 
Strings-Computer programming
Strings-Computer programmingStrings-Computer programming
Strings-Computer programming
 
Ch08
Ch08Ch08
Ch08
 
Getting Started with C++
Getting Started with C++Getting Started with C++
Getting Started with C++
 
Python Objects
Python ObjectsPython Objects
Python Objects
 
Overview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya JyothiOverview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya Jyothi
 
Computer experiments 1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branch
Computer experiments   1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branchComputer experiments   1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branch
Computer experiments 1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branch
 
Assignment4
Assignment4Assignment4
Assignment4
 
C intro
C introC intro
C intro
 
Functions-Computer programming
Functions-Computer programmingFunctions-Computer programming
Functions-Computer programming
 
Conditional Statements
Conditional StatementsConditional Statements
Conditional Statements
 
Ch05
Ch05Ch05
Ch05
 
Function
FunctionFunction
Function
 
Lab6: I/O and Arrays
Lab6: I/O and ArraysLab6: I/O and Arrays
Lab6: I/O and Arrays
 
Ch03
Ch03Ch03
Ch03
 

Similar to Functions in c++

Functions assignment
Functions assignmentFunctions assignment
Functions assignmentAhmad Kamal
 
Presentation 2 (1).pdf
Presentation 2 (1).pdfPresentation 2 (1).pdf
Presentation 2 (1).pdfziyadaslanbey
 
Introduction to c programming
Introduction to c programmingIntroduction to c programming
Introduction to c programmingAMAN ANAND
 
c_programming.pdf
c_programming.pdfc_programming.pdf
c_programming.pdfHome
 
Book management system
Book management systemBook management system
Book management systemSHARDA SHARAN
 
Amit user defined functions xi (2)
Amit  user defined functions xi (2)Amit  user defined functions xi (2)
Amit user defined functions xi (2)Arpit Meena
 
Functions in c language
Functions in c languageFunctions in c language
Functions in c languageTanmay Modi
 
Functions in c language
Functions in c language Functions in c language
Functions in c language tanmaymodi4
 
Sample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.SivakumarSample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.SivakumarSivakumar R D .
 
unit3 part2 pcds function notes.pdf
unit3 part2 pcds function notes.pdfunit3 part2 pcds function notes.pdf
unit3 part2 pcds function notes.pdfJAVVAJI VENKATA RAO
 
Tutorial basic of c ++lesson 1 eng ver
Tutorial basic of c ++lesson 1 eng verTutorial basic of c ++lesson 1 eng ver
Tutorial basic of c ++lesson 1 eng verQrembiezs Intruder
 

Similar to Functions in c++ (20)

Function
FunctionFunction
Function
 
Functions assignment
Functions assignmentFunctions assignment
Functions assignment
 
Chapter 1.ppt
Chapter 1.pptChapter 1.ppt
Chapter 1.ppt
 
Presentation 2.pptx
Presentation 2.pptxPresentation 2.pptx
Presentation 2.pptx
 
C functions
C functionsC functions
C functions
 
Presentation 2 (1).pdf
Presentation 2 (1).pdfPresentation 2 (1).pdf
Presentation 2 (1).pdf
 
Functions in c++
Functions in c++Functions in c++
Functions in c++
 
Project two c++ tutorial
Project two c++ tutorialProject two c++ tutorial
Project two c++ tutorial
 
Introduction to c programming
Introduction to c programmingIntroduction to c programming
Introduction to c programming
 
Unit-III.pptx
Unit-III.pptxUnit-III.pptx
Unit-III.pptx
 
c_programming.pdf
c_programming.pdfc_programming.pdf
c_programming.pdf
 
Lecture 11 - Functions
Lecture 11 - FunctionsLecture 11 - Functions
Lecture 11 - Functions
 
Book management system
Book management systemBook management system
Book management system
 
[ITP - Lecture 12] Functions in C/C++
[ITP - Lecture 12] Functions in C/C++[ITP - Lecture 12] Functions in C/C++
[ITP - Lecture 12] Functions in C/C++
 
Amit user defined functions xi (2)
Amit  user defined functions xi (2)Amit  user defined functions xi (2)
Amit user defined functions xi (2)
 
Functions in c language
Functions in c languageFunctions in c language
Functions in c language
 
Functions in c language
Functions in c language Functions in c language
Functions in c language
 
Sample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.SivakumarSample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.Sivakumar
 
unit3 part2 pcds function notes.pdf
unit3 part2 pcds function notes.pdfunit3 part2 pcds function notes.pdf
unit3 part2 pcds function notes.pdf
 
Tutorial basic of c ++lesson 1 eng ver
Tutorial basic of c ++lesson 1 eng verTutorial basic of c ++lesson 1 eng ver
Tutorial basic of c ++lesson 1 eng ver
 

Recently uploaded

top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownloadvrstrong314
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILNatan Silnitsky
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfOrtus Solutions, Corp
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockSkilrock Technologies
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Krakówbim.edu.pl
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfkalichargn70th171
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAlluxio, Inc.
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1KnowledgeSeed
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEJelle | Nordend
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessWSO2
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfmbmh111980
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfMeon Technology
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandIES VE
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesKrzysztofKkol1
 

Recently uploaded (20)

top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning Framework
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdf
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 

Functions in c++

  • 1. By: Asaye Chemeda Email: asayechemeda@yahoo.com 1 CHAPTER ONE FUNCTIONS Introduction C++ programs are a collections of functions. Functions are entities in C++ programs which are used to write statements. You may have declarations without functions. However, you can’t make a C++ program to execute certain statements unless you have a function. For instance, the following C++ program is intended to display the sum of two numbers. But, the result will not be displayed since the program doesn’t have the entity where you can write C++ statements. In short, since the program doesn’t have a function, you can’t get outputs. Program 1.1[Incorrect].cpp Thus, in C++ program, you need to define functions to write statements and to get results. Defining Functions If you understand the importance of functions, the next question will be how functions are defined in a C++ program. To define functions, you need three mandatory and three optional components. The mandatory components of a function are function name, closed brackets, and closed braces where are the optional components are return type, parameters (or arguments) and return statement. These components will be discussed as bellows. Function name. Every function in a C++ program should have its own name. The name can be any combination of characters provided that the function name is not among the reserved C++ words, nor it doesn’t begin with numbers, nor it doesn’t contain some reserved C++ characters. Closed Brackets. The function name should be followed by closed brackets. These brackets will serve as a gateway to the function. Closed Braces. The closed braces should be written next to the closed brackets. They are used to contain the body of the function. Return Type. C++ functions may just execute certain statements without returning a value or they may return some values to the entity which called them. Thus, depending on whether they return values or not, C++ functions can be categorized into value retuning functions and void functions. The return type for value returning functions is the same as the data type of the value which is returned by the function. This can be int, double, float, char, String, short, long. If a function doesn’t return a value, its return type will be void. Mentioning the return type while defining a function is optional. However, if there is no return type which is explicitly stated, the C++ program assumes the return type is int. While defining functions, the return type is stated in front of the function name. Parameters (or arguments). A function may use inputs to execute the statements in the body. For instance, if the task of a certain function is to give the sum of two numbers which are passed to it, the function needs to take those values which will be added as an input to give their sum. Those input which are passed to a function are called parameters or arguments. Since the closed brackets are the gateway to the function, the parameters are passed to the function through the closed brackets. The number of parameters which a function can take is not limited to only one parameter. You can pass a number of parameters with different data type to a function. If a function takes parameters, the data type of the parameters should also be stated. Otherwise, the program will assume that the data type is an integer. Return statement. If a function returns a value, there should be a return statement in the function. The return statement should be the last statement in the function. A return statement has two components. The first component is the return word. The other component is the value which is returned. The value which is returned may be an expression but should match the return type. A complete C++ function definition for value returning functions is shown below. A complete C++ function definition for void functions is shown below. The function name and the parameter lists are together called signature of a function. The signature doesn’t
  • 2. By: Asaye Chemeda Email: asayechemeda@yahoo.com 2 include the return type. A signature of a typical C++ function is shown below. At this point, you are convinced that, any C++ program should have a function in order to execute statements. Thus, having function is a necessary condition to execute statements in C++. One question may be raised here: is having a function a sufficient condition for C++ programs to be executed? Let us have a look at the following program which is intended to display “Hello World!” on the console. Program 1.2 [Unexecuted].cpp This program fulfils the conditions that functions are required to execute statements. It has return type (void), a function name (helloWorld), the closed brackets, the closed braces and the function body (the cout statement). If you run the above program, will it display the message “Hello World!” on the console? The answer is no. The above program lacks one thing which every C++ should have - which is the main function. If you want to execute statements in C++, the program must have a main function. The main function A C++ program will not be executed unless it has a main function. One important thing to note here is that the main function is always the function where a program starts execution. The main function has a function name of the word main and a return type of int. The main function returns a value of int data type to the operating system. By convention, the return value 0 is used to indicate the program is executed successfully and other integer values indicating the opposite. The main function may or may not take arguments. When the main function takes arguments, the arguments are two. The first argument is an integer while the second one is a point to an array of character pointers. Thus, the signature of the main function may have one of the following two types. If a C++ program has main function, it will be executed. Program 1.2 can now display the “Hello World!” message if it is corrected to Program 1.3 which is shown below as it fulfills the two conditions that a program should at least has one function and that any C++ program should have main function. When the above program is run, the function body between the braces (the cout statement) will be executed and the “Hello World!” message will be displayed. The function body may contain any number of statements and you can put every statement which is required to perform a certain programming task inside the main function body. If so, what is the importance of defining other functions than main function? There are two reasons for this. The first one is that some programs may require several lines of codes and it may be unwise to put all the code in only the main function. Thus, you will divide the code into a number of manageable pieces and you will put them in different functions. For instance, assume you want to write a C++ program to build a simple calculator. This requires building the user interface, taking values which will be added or multiplied or any other operation to be done on, calculating the result of the operation and displaying the results. If a program for a simple calculator has all these tasks, each with a number of lines of codes, why do put all the code in the main statement? It is unmanageable. For instance, if you want to improve any of the above tasks you have to go through the whole main function. The best way to avoid this is to have different functions performing manageable pieces of codes. The second reason to have other functions than main is to avoid repetition of codes. For instance, in the simple calculator program mentioned above, the way in which the output is displayed may be the same whether you added or multiplied two numbers. So, why do you write separate statements for displaying results for the addition and multiplication? Isn’t it better if you have only one output display function which can be accessed by all the operations? Doesn’t this avoid repetition of many lines of codes? Doesn’t this save time, which is a very important factor if you are a programmed with many projects? If so, you will definitely agree that other functions than main may be necessary to attain the above two benefits – breaking the code into manageable pieces and avoiding repetition of codes.
  • 3. By: Asaye Chemeda Email: asayechemeda@yahoo.com 3 When a program has more than one function, how do the functions interact with one another? If one function wants to interact with another, it calls the other function. This may be for one or a combination of the following three reasons. A function may call another function to get a certain result or to change the value of some variable or to print (or display) something. Whichever reason it is, if a function wants to call another function, it just writes the signature of the function without the data type of the arguments at the place where it wants to interact with the other function. When you write the signature of certain function, it means that you are interacting with that function. You may ask, are there any rules when functions interact with one another? The answer is yes. One of the rules is the called function should be written before the calling function or there should be a prototype of the called function before the calling function. Before looking into the details of this rule, let us understand which one the called function is and which one the calling function is. This will be illustrated with the following program. Program 1.4[Correct].cpp The above program is intended to print the sum of two values which are entered from the console. In the program, there are two functions: the mandatory main function and the add function. The return type of the add function is double and having a return statement is mandatory for this function. The function takes any two arguments which are of double data type. Thus, whenever it is desired to interact with this function, the function name (add) must be explicitly stated and two double values separated by a coma should be passed as arguments between closed brackets. The identifiers used for the arguments (a and b) may not be the same as the identifiers which is defined in the function which wants to interact with this function. The required return statement for this function is stated on line 6 of the program. This line of the function returns the sum of any two double type values which are passed to the function as arguments. One this to note here is that, in the return statement, you can write expressions after the return word. The main function has an int return type and takes no arguments. The body of the function, the part of the function within the braces, starts with defining statement of three variables a, b and c which are of double data type. This is the first statement which will be executed in the program as execution of statements in C++ programs from the main function. The next statement is taking the values of a and b respectively as an input from the console by using cin. Line 13 of the program is the place where the main function interacts with the add function. In this line the value c is assigned with the signature of the add function. Since the add function returns the sum of two double values which are passed to it and since on the signature of the add function on line 13, the values or a and b are passed, the value of c will be assigned with the return value the add function. In other words, on line 13, the main function has called the add function to assign the value of c with the sum of a and b. Thus, the main function is the calling function as it is calling another function and the add function is the called function as it is called by another function. If you run the above program, you will be prompted to enter two values on the console and their sum will be displayed after entering the second number. Now, any doubts regarding the calling and the called function are cleared and let us proceed to the details of the rule mentioned above. Before that, try to run Program 1.4 by placing all the components of the add function after the main function. Did you get the result which you expected? Did the program even pass the compilation? The answer is no. Mind you, you just only place the add function after the main function and you didn’t remove or add anything to the existing functioning program. So, why is the program not free of compilation errors? If you remember the rule, it says you can’t put the called function after the calling function unless there is a prototype of the called function before the calling function. There is a compilation error now because the called function (add) is placed after the calling function (main) and there is no prototype of the called function (add) before the calling function (main). If there are more than one interacting functions, there are two available options for having a working program. The first option is to place the called function before the calling function.
  • 4. By: Asaye Chemeda Email: asayechemeda@yahoo.com 4 The second option is to put the prototype of the called function before the calling function and you can put the called function after the calling function. The first option may sometimes create ambiguities for the person who came up in dealing with a program written by another person as it often happens in programming work places. Imagine you are dealing with a program written by another person. What you normally do is you will go through the program from the top to down and if the program is written by the first of the above mentioned two options, you will first encounter the called functions, which can be several of them, and you don’t know when and why they are called. So, you will get confused. To avoid this, the second option is frequently used in programming community. As mentioned earlier, the second option requires putting the prototype of the called function before the calling function. This is called prototyping. So, what prototyping is and how it is done will be the next topic. Function Prototyping Function prototyping is declaring a function without including the body of the function. Thus, a function prototype includes the return type of the function, the function name and the argument lists. A function prototype ends with a semi-colon like other C++ statements. When a functions is declared by prototyping, the identifiers used for the arguments are dummy variables (can take any appropriate variable identifier) and they can be omitted. A complete function prototype will have one of the following forms without any change in the outcome. Program 1.4 can now be modified to the following program without any change in the outcome of the program. Program 1.5[Correct].cpp Program 1.5 can be compiled without any errors even if the called function (add) is placed after the calling function (main). This is because the prototype of the add function is placed before the main function on line 5. In the prototype of the function on line 5, the return type, the function name and the data type of the arguments match to that of the actual add function given in line 16 as it should be. In the prototype, the identifiers of the arguments are omitted as any identifier can be used. Let us try to add one additional function to Program 1.5. The task of this function will be displaying a message that says the sum of a and b is c. The name of the function will be printSum and it will not return any value, it just prints. As a result it should be of void return type. The function will replace line 12 of Program 1.5. Thus, the printSum function will be called from line 12 of the main function. Since a, b, and c are defined in the main function and since this function doesn’t make any calculations, why should this function take any arguments? If you say so, the function will be defined with empty parameters. Of course, don’t forget to put either the function or the prototype before the calling function. Now the program appears to be: Program 1.6[Incorrect].cpp In this program, a new function printSum is defined and it is called from line 12 of the main function. Now, try to compile the program and see if there are any errors. Of course there are. Specifically on line 21 of the program. Oh, did I forget to put the prototype before the calling function? No! It is already on line 6. Did I miss any semi- colon? No! Then, why are the errors occurring although the program seems faultless. The errors occurred due to a concept known as scope in C++. Scope of Variables Scope means the limit which a piece of code at one place of the program has in order to access and use a piece of code at another place. In C++, variables which are defined inside a function can only be accessed and used
  • 5. By: Asaye Chemeda Email: asayechemeda@yahoo.com 5 by a code inside that function. Thus, the scope of the variables declared inside a function is only within the function itself. Note that there may be exception to this rule and that exception will not be dealt in this chapter. Variables which are defined within a method and which have a scope within the function itself are termed as local variables. There are also variables which are defined outside functions. The scope of these variables is not limited to any function and such variables can be accessed from anywhere within a given program. These type of variables are termed as global variables. At this point, what you have to note is, unless additional key words are used, the scope of a variable defined in a function is within the function itself. Which means that the add function cannot directly access and use the variables a,b and c in the main function and the same is true for the printSum function. I see! Apparently, the printSum function which dared to print a message that the sum of a and b is c can’t actually access neither of these variables. Now, you understand what line 21 of Program 1.6 was trying to do. It was just like printing an undefined variable c which is presumed to be the sum of two undefined numbers a and b. Can you use variables without defining them in C++? Of course not! That is why the error occurred. What could be a solution for this? There are a number of solutions and one of them is to pass the variables a,b and c to the printSum function as arguments. The following program will be perform the intended task in program 1.6 without any compilation errors. Program 1.7[Correct].cpp Note the changes on line 6, line 12 and line 21. Another thing to note is when the main function calls the printSum function on line 12, it passed a,b and c respectively as arguments but the printSum function accepted x,y and z respectively as arguments. This doesn’t have any problem. Because, what the printSum function does is printing the sum of the first argument which is defined as x in the printSum function (but which can be defined as any name in the calling function) and second argument which is defined as y in the printSum function (but which can be defined as any name in the calling function) is third argument which is defined as z in the printSum function (but which can be defined as any name in the calling function). So, when you pass arguments to another function, the name of the arguments don’t matter. It is their order which matters. To understand this, let us have a close look at line 12 and line 20 of the program. These lines are extracted and put as follows: When a call to the printSum function is made on line 12, the first place where the call goes to is the prototype on line 6. The prototype checks whether the data type of the arguments passed on line 12 actually match those stated in the printSum function. If the matching is successful, the call goes to the implemented function which is on line 20 of the code. At this point, the printSum function will assign its variables (x,y and z) with the corresponding variables in the call. For instance, the first argument in the call (line 12) is a and the printSum function will assign the first variable in its argument list (x) by a. The same is true for the other arguments. In other words, the first thing which printSum function does is implicitly assigning its arguments as follows: As a result, even if the variable names used in the calling and the called function are different, the outcome will be the same. Try to switch the places of a, b and c on line 12 and see the printed message. At this point, you understand that one way to grant access for other function to use variables defined in a given class is by passing them as arguments. Now, let us have more fun by writing another program and let us grab a new concept. The program which we are going to write takes two values a and b from the console and swaps the values of a and b and prints the swapped values. The variables will be defined and their values will be read in the main function while the swapping will be done by another function. Let use call the function swap. But, C++ already has a built-in function called swap which performs a similar task to what we are going to do. By the way, C++ has several built in functions which perform
  • 6. By: Asaye Chemeda Email: asayechemeda@yahoo.com 6 some specific tasks which can be used at the user’s convenience. Nice! This simplifies your job as a programmer since you don’t have to write everything to write a functioning program. Let us get back to our program and to avoid any confusion let us give a name of swapValues for our function. The values of a and b will be passed to the swapValues function as arguments in order to grant access for this function to use the variables. The swapValues function just swaps the values of a and b without returning any value. Hence, its return type will be void. Here is the program: Program 1.8[CannotSwap].cpp In the above program, the swapValues function takes two values of double data type and swaps their values i.e. it gives the value of a to b and the value of b to a. Another variable x is also defined to take the original value of a so as not to lose the value of a in the process when the value of b is assigned to a. In the main function, there are two cout statements. The first one displays the values of a and b before swapping. The second cout statement comes after the swapValues function is called. Thus, it is expected that the values printed by this statement will be the reverse of the first cout statement. For instance, if you enter the value of a as 1 and the value of b as 2, you will expect that the first cout statement prints “ …1 and 2” and the second cout statement prints “… 2 and 1”. Run the program and see the result. Did you get the result which you expected? Surely not! Check the swap function again. Isn’t it swapping the values of the arguments which are passed to it? Of course it does! So, where did it go wrong? Apparently, there is nothing wrong with the program. But, one detail is missing. When you passed the value of a and b (which are defined in the main function) to the swapValues function, you just passed the values of the variables to the function. Again, when the swapValues function accepted the values of a and b, it just accepted the values of the variables. In such cases, whatever the swapValues function does, has no reference to the main function. This is called passing parameters by values. If a calling function passed parameters to the called function by value, then the called function cannot change the original values of the parameters in the calling function. Now, you have got the clue why the values of a and b were not swapped. Even if the swapValues function swapped the values of the arguments which are passed to it, it doesn’t actually swap the original values in the main function. The swapping only remains in the swapValues function. This is because the values are passed by values. Can we do anything to change the values of parameters in a calling function from a called function? Of course, we can! C++ has the facility to do this. It is called passing by reference or calling a function by reference. Call by Reference C++ has a facility in which two identifiers can be used to refer to the same variable. Such variables are termed as reference variables. To create a reference variable, an original variable should be first defined. The reference variable and the original variable refer to the same data object in the memory. The C++ syntax used for creating reference variable is as follows. To understand how reference variables work, look at the following program. Program 1.9[Correct].cpp In the above program, a variable named a was defined on line 6 and it was initialized with a value of 10. On line 7, a reference variable to a was defined as b. Note the & operator which was used while defining b. On line 8, the value of b was doubled. On line 9, the value of a was printed. What do you think will the displayed value be? If you are not familiar with reference variables, your answer will be 10. You are reasonable to say so because there is no any statement which directly changes the value of a. Run the program and see the result. It is 20. How come?
  • 7. By: Asaye Chemeda Email: asayechemeda@yahoo.com 7 This is because after b is defined as a reference variable to a on line 7, both variables (a and b) refer to the same memory location. As a result, whatever operation you perform on either of them, the other one will also pass through the same operation. If you double the value of b, the value of a will also be doubled automatically. Since the value of the reference variable (b) is doubled on line 8, the value of the original value (a) will also be doubled. You will also get the same result if you double the value of a and print the value of b. Now, it is pretty clear what reference variables are. After understanding the concept of reference variables, did you get any idea on how you can alter the value of variables in the calling function from the called function? Remember, if you define a reference variable to a variable, you can alter the value of the original variable by altering the value of the reference variable. If so, to alter the value a variable in a calling function from the called function, why don’t you define a reference variable in the called function referring to the original variable in the calling function? Will there be any problem if you try do so? There might be. The problem is the called function should get access to the original variables in the calling function. Of course, you know the solution for this problem. The solution is you can pass the variables as arguments. Right? Now, you understand the framework about how variables in the calling function can be altered from the called function. Let us go to the details. First, let us see the available options in which a reference variable in the called function is created and their feasibility. For this, we will refer back Program 1.8. To define a reference variable to a and b in the swapValues functions, there are three options. The first option is if we can call the swapValues function from the line 11 of the main function as below: This is possible. But, understanding the detail requires a concept which will be discussed in chapter three. Therefore, we will skip this option for the time being. The second option is the pass the values of the original variables when the swapValues function is called in the main function. This means, line 11 of the program will not be changed. Again when the swapValues function takes the variable from the main function, let it take the actual values of the variables. Then, in the swapValues function, let us define reference variables to a and b and let us swap their values. What do you think of this second option? It is just like back to square one. Right? Because, this is no different from the Program 1.8, which failed to swap the original values in the main function. To understand this better, go back to Program 1.7 and revise what we said about how the called function creates its own new variables and assigns the values of these variables with those of the calling function according to their sequence. There will be no reference made to the calling function variable. Thus, if a value is passed to the called function, the changes which are made in the called function will remain in the called function. Even if you define reference variables in the swapValues function, the defined reference variables will refer only to the new variables which are defined in the signature of the function; not to the values in the calling function. As a result, the second option is not feasible. Let us see the third option. If you understand, the drawback of the second option, it is easy to guess what the third option might be. The main drawback of the second option is that, the called function will not have control over the calling function variables once they passed the gateway into the body of the function. What can we do then? To answer what we could do, once again refer back to Program 1.7. Specifically, note how the called function implicitly assigns its variables in the argument list with the variables passed to it. This one concept. Also, refer back to how reference variables are defined. Another concept! Do you see a common point in these two concepts? Of course you do. What if you define a reference variable to the calling function on the signature of the called function itself? Doesn’t this solve all of our problems which we had? Defining a reference variable on the signature of the called function to the original variables in the calling function will make it possible to alter the values of the variables in the calling function from the called function. This is what is called passing by reference or calling a function by reference. Now, Program 1.8 can be modified as follows. Note that changes are made only on line 5 and line 16 of program 1.8. Program 1.10[Correct].cpp
  • 8. By: Asaye Chemeda Email: asayechemeda@yahoo.com 8 What this program does which is different from program 1.8 is that the swapValues function defines reference variables of the original variables in the main function in its signature. As a result, the variables in the main function and in the swapValues function refer to the same memory location. Therefore, whatever the swapValues function does to its arguments, the changes will persist to the original variables in the main function. When the arguments of the swapValues is changed, its prototype on line 5 should also be changed. Now, run the program and see the result. Now, when the values of a and b are printed before and after calling the swapValues function, they are actually swapped. The advantage of passing by reference is three fold. The first one is to alter values of variables from an outside function. The second one is to return more than one variable from a function. Value returning functions return only one value through their return statements. However, if calling by reference approach is used, a function can return more than one value. In Program 1.10, the program actually returned two values – the swapped values of a and b. The third advantage of passing by reference is saving memory space. Since the original variables and the reference variables refer to the same memory location, a lot of memory space which could have been wasted by defining two separate variables in each of the functions can be saved. Let us raise an interesting question here based on the three advantages of passing by reference. Say, within a program, you want to save memory by using pass by reference but you want to restrict any changes to the reference variable. Can we do this in C++? The answer is yes. What we need to do is put a qualifier const before the data type of the reference variable in the argument list of the function and in the prototype. However, when you add the qualifier const in front of the data type of a reference variable any attempt to change it, will result in compilation error. For instance, you can change the signature, and of course the prototype, of the swapValues function in Program 1.10 as follows. This restricts any change to reference variable a (and therefore the original variable a in the main function) within the function. When you try to run the program you will get an error message on line 18. Because on that line you tried to change the value of the reference variable. Isn’t this reference concept interesting? Indeed it is! But, have we covered what we have to know regarding reference at least for this chapter? A little more remains. A function can take reference of another variable as arguments. This enables a function to alter the values of the variables to which the reference is made. Interesting! Let us think both ways and ask this question: is it possible to get reference of the variables returned by a function? Thanks to the C++ developers, the answer is yes. If you think of the potential effects of this possibility, you will realize that C++ program is indeed versatile. If a function returns values which you can’t have reference, then the function is returning by value. You can also have reference to what is returned by a function. This is the concept which has to be covered before concluding the reference concept for this chapter. Return by Reference If a function returns the reference the return value, the function is said to be returning by reference. At this point, you are expected to know how reference variables are defined. It was easy, right? If you have any doubt, go through the topic of calling by reference. That is how things work, if you want to be good at programming, you will deal with it till you understand it completely. No giving up! To understand the concept of return by reference, we will try to solve one mathematical problem. Are you expecting some calculations? Not really. We will just write a program to solve it. The problem is as follows. Assume in a certain mathematical problem, the value of a certain variable can have a value from 0 up to 3 only. If part of the calculation results in a value to the variable outside this range, the variable takes the maximum value, i.e. 3. If the variable is x and you express it with a mathematical equation, it appear like: ‫ݔ‬ = ൜ |‫|ݔ| ݂݅ |ݔ‬ ≤ 3 3 ݂݅|‫|ݔ‬ > 3 What we are going to do next is writing a program which gives the value of x for any value entered from the console. C++ has built-in absolute value function, but we will write our own absolute value function since it is very easy. The absolute value function which we are going to define will have a function name of abs. Just to recall what an absolute value function will do, it gives the value of the number if the number is positive or zero or the negative of the number if the number is negative. As the negative of a negative number is positive, you will always have a positive value of a number after passing through the absolute value function. The program is given below.
  • 9. By: Asaye Chemeda Email: asayechemeda@yahoo.com 9 Program 1.11[Correct].cpp In the above program, a global variable absValue is defined on line 4. Who can access this variable then? Every piece of code in the program can access this variable. Because the scope of global variables is not limited to any function or any piece of code. The abs function is placed before the calling main function. Do you have to define a prototype for the abs function? Of course, you don’t have to. The abs function takes arguments by reference. Do you remember what this will do? If the abs function takes an argument by reference, it can change the value of the variable use as an argument in the calling function as it wants. As a result, when the variable value is changed in the abs function, the variable x in the main function will be changed in the same manner. If you want this not happen, i.e. if you want the abs function not to change the value of x in the main function and if you just want to use the return value of the abs function, you know what to do. Just avoid the & character from the signature of the abs function. By putting the & character from the signature of the abs function, you have made the x variable of the main function to have whatever the value variable of the abs function gets. In the abs function, the value variable is changed on line 11 only. What if you remove this line from the program? The function still returns an absolute value of any value passed to it but the value of x in the main function will not be changed. Confusing? Just understand the following and it will no longer be confusing. The reference variable to the x variable in the abs function is the value variable which is defined on the signature. Do you understand this? Good. If a variable has a reference variable when will it change? It will be changed when the original variable is changed or when the reference variable is changed. Right? If neither of them were changed, then there will be no change in the original or reference variable. Since the only reference variable in the abs function to the x variable in the main function is value, the value of x will be changed only when the value of the value variable is changed. In the abs function, the value variable is assigned with a new value only on line 11. If this line of the program is removed, then there will be no change to the value variable and there will be no change to the x variable either. Here comes the question which is relevant to this topic. Can you change the value of the value variable from the main function? Not directly, but you can. If you want a local variable to be changed outside the function return that local variable and make the function to return by reference. Do you know the reason why you can’t directly change the value variable from the abs function? It is because of scope issue. The value variable is a local variable and it cannot be accessed from outside of the abs function. And since the value variable is not the return value of the abs function, you cannot change its value at all from outside the function even if you make the function to return by reference. To make a function return by reference put the & character in front of the function name. The reason why the & character is put in front of the abs function is to make the function return by reference and you will have reference to what is returned by that function. By putting the & character in front of the abs function, we now have the reference to the absValue global variable and we can change its value as we want by calling the function. That is what we did on line 19 of the program. We assigned the return value of the abs function by a value which wanted. In the program, an abs(x) value is compared with 3 on line 18 and assigned with 3 if it results in a value greater than 3 on line 19. That is what the problem statement of the program said. After that, there is a cout statement on line 21 of the main function. It will display the value of x and absValue respectively along with other characters. Now, run the program and enter -10 as an input. The message which you are be expecting on the display console might be this one: You are reasonable to expect this. Because when you pass -10 as an argument and call the abs function for the first time on line 18, the value of x will be changed to the absolute value of -10, which is 10. You know why the value of x is changed. It is because the function call is made by reference and the reference variable to x (value) is changed inside the abs function. Therefore expecting the displayed value of x as 10 is reasonable and
  • 10. By: Asaye Chemeda Email: asayechemeda@yahoo.com 10 right. But what about the displayed value of absValue? Is the displayed value what you expected? It is again reasonable to expect its to have the same value as x. because there is no statement where its value explicitly is changed in the main function. However, when you run the program, the message which you will get is this one. You are correct about the displayed value of x. it is indeed 10. But the displayed value of absValue is 3. If you understand the concept of returning by reference, you will know why. Since there is & character in front of the abs function name, you can change the return value of the function by calling and assigning the function to any value which you want. That is what line 19 of the program did. It assigned a maximum value of 3 to the return value of the abs function. This wouldn’t have been possible, had the abs function returned by value. To understand a little bit more, let us answer the following string of questions. What is the return value of the abs function? It is absValue. Look at line 12 of the program. What type of return method is used by the abs function? It is return by reference. Look at the & character on line 5 in front of the function name. What happens when a function returns by reference? You can change the return value (i.e. absValue) by calling and assigning a value to the function. Where, in the program, did you call and assign a value to the abs function? On line 19. Which means that, on line 19, you set the maximum value to the absValue variable to 3 by using if statement. Therefore, if the absolute value of a number is greater than 3, the abaValue variable will have a value of 3. Since the absolute value of -10 is greater than 3, the displayed value of absValue is 3. By the way, you could have also limited the value of absValue to 3 in the main function itself without calling the abs function. Because, the absValue variable is global and you can access it and change its value from anywhere in the program. The desired value of x which is stated in the problem statement is obtained from absValue variable not x. That is what returning by reference means. There you go. Are you bored? You might be because we spent much time on the same topic. But, it was worth. Right? You grabbed some interesting and basic concepts in C++. By the way, if you understand about functions, it means that you have understood one of the core concepts of the C++ language. To make it interesting again, let us switch to another concept regarding functions. This time, let us deal about function names, return types and argument lists in detail. When we say argument list, we mean the argument variables and their data types altogether. Can you guess what will happen if you define two functions with the same function name, with the same number and data type of arguments and try to compile it? The compiler will send an error message even if their return type is different. For instance, look at the following program. Program 1.12[Incorrect].cpp In the above program, there are two functions other than the main function. The functions have the same function name (print), the same number of arguments (one) and the same data type of the arguments (double). Since the number of arguments is the same, the sequence of the data types of the argument list is also the same. Therefore, the functions have the same signature. If the functions vary by any of these four highlighted factors, they no longer have the same signature. But, one of the print functions takes a local variable named a while the other takes b as an argument. If so, why are their signatures the same? As we said earlier, the names which you give to the arguments are dummy variables and you can give it whatever name you want without affecting the outcome. As a result, these dummy variables will not be used as a criteria to compare whether two functions have the same signature or not. If a program contains, two or more functions with the same signature, it will have compilation errors if you try to compile it. When a function call is made, you only write the signature of the called function. If a program has two functions with the same signature, which function will the compiler invoke when the function is called? The program will get confused. The program is logical here. It is us who are trying to confuse the program. To stop confusing the program, let us make only one change in Program 1.12. Let us change the data type of the argument of the second print function from double to int. If you do so, by the criteria stated above, the two print functions will no longer have the same signature. Right? Because, the data type of the only argument which they take is different. This makes them to have different
  • 11. By: Asaye Chemeda Email: asayechemeda@yahoo.com 11 signatures. Have a look at line 8 of the changed program below. Program 1.13[Correct].cpp Note that the print functions take an arguments and print its value. The value is printed as “ …value of a…” in the first print function and “…value of b…” in the second. The print function is called on line 13 of the program from the main function and the value of variable x is passed to the function as a parameter. The variable x has double data type and is initialized with a value of 100. If you run the program, there will be no compilation error now. Because the only cause for the compilation error in Program 1.12 is now gone. If you remember the cause, it was having two functions with the same signature within the program. As stated above, the two print functions in program 1.13 are not identical any more. When a function call is made on line 13, is the program now confused to which print function will he go to? Not anymore. It goes to the print function which has the same argument data type as the data type of the variable passed to it. You see how smart the program is! The data type of x is double and when the print function is called, the program directs the call to whichever print function which takes a double value as an argument. It is the first print function which takes double value as an argument. Therefore, the value of x is printed as “… value of a…”. Have a look at the message below which results when the program is run. See what happens when the data type of x is changed to int. in addition try to call the function by passing different data types directly. For instance, change line 13 of the program with print(10.0);, print(10);and print(‘x’); and see what happens. Repeat these changes after changing the data type of the argument of the second print function to float. If you notice some interesting results, why those results occurred will be reasoned out in the next topic when another interesting concept in C++ is discussed. When you deal about object-oriented programming in C++, you often need functions to have the same name but different signature. This happens if the functions take different number or data type or sequence of data type of the arguments. If you define functions having the same name but different signature in a program, then you are over-loading that function. Since we are discussing about functions now, it is worth dealing about this concept in detail here. Function overloading In C++, especially in object-oriented programming, the name of functions may be restricted but you may want to call those functions by passing distinct parameter lists. In those situations, you have to define the functions with the same name but different signatures. Defining two or more functions in a program with the same name but different signature is called function overloading. We have already seen how function overloading is done in Program 1.13. However, to understand some rules regarding which overloaded function is invoked by the compiler during a function call, we will write another program. For this, eight overloaded functions will be defined. Is that too many? You will see it will be worth the number. We will try to call the function by passing different parameters and we will note which function is invoked. When a function gets invoked, it prints a message which has the function’s rank number in the vertical order. So, we know which function was really invoked from the output message. Here is the program. Program 1.14[Correct].cpp
  • 12. By: Asaye Chemeda Email: asayechemeda@yahoo.com 12 As you can notice in the above program, all the functions other than main have a function name of print. But all the functions have different signature i.e. some of them have distinct data type of arguments, some of them have different numbers of argument and the others have distinct sequence of data type of arguments. But all of them have a unique signature. Thus, we can say that they are overloaded functions. We will call the print function by passing different parameters from line 29 of the main function and run it each time. If you run the program as it is, the output is: The first print function invoked. This result is displayed because on line 29 of the program, the print function is called with empty parameters. As a result, the compiler invokes the print function which takes no parameters. In the vertical order, this particular print function is the first one in the program. If you see the body of the function, it has a cout statement which prints the above message. Therefore, when an overloaded function is called with empty parameters, the compiler invokes the overloaded function which doesn’t take any parameters. Now let us change line 29 of the program with the statement below and run the program. i.e. let the function call passes a value of 10 (with no decimal point). print(10); If you look at the output, it is: The second print function invoked. If you find out which print function displays the above message when invoked, it is the print function which takes int parameter. Do you see the reason why the complier invoked this particular print function? It is because the compiler considers a value of 10 without a decimal point as an integer and it invokes the overloaded print function which takes a similar data type argument as the passed argument data type. Rule 1: when a function call is made to an overloaded function, the compiler will first try to find and invoke the function which takes the same data type and the same sequence of data types of arguments as those of the arguments passed from the calling function. Which means, if an int data type is passed as an argument from the calling function, it is the overloaded function which takes argument with int data, if there is, which will be invoked. Let us make what we are doing more interesting by replacing line 29 of the program with the following. print(10.0); Now, we added a decimal point to the number 10 which was passed in our previous attempt. If you run the program again and have a look at the output, it is: The fourth print function invoked. This output message will be displayed by the print function which take a double data type argument. Reasonable. Right? If a number has a decimal point, it is considered as a floating point number. And when a floating point number is passed, the compiler will invoke the overloaded function which takes an argument which matches this data type. You can raise an interesting question here. In addition to the double data type, the float data type is also used for floating point data types like 10.0 and there is a print function which takes float data type as an argument. If so, why did the compiler prefer the function with double data type argument list? Before answering this question, let us see how the C++ data types are classified. In C++, data types are classified into simple, structured and pointers. Since their significance for this topic is minimal, we will not discuss about the latter two here. The simple data types are further classified into three categories as integral, floating-point and enumeration. The integral category can only deal with numbers and variables without decimal places. The int, char and bool data types fall in the integral data type category. In this category, the int data type has higher level than the other two. The floating-point category can deal with any numbers with or without decimal places. The floating- point category contains float and double data types. Among these two, double has higher level than float. When we go back to our question and reason out why the compiler preferred double over float, it is because double is at higher level than float. Rule 2: if function call is made to an overloaded function and the compiler has the option to choose between different data types in the same category, without data type conversion, the compiler will invoke the function which takes arguments with a higher level data type among the list of options. Therefore, if two overloaded functions exist one of them taking argument with float data type and the other taking with double data type, and if a floating-point number (not variable) is passed as an argument, the compiler invokes the function which takes an argument with double data type. However, if a variable is passed, the compiler will invoke the function which takes the same data type as the variable, whether it is double or float. To understand this more, define a variable with double or float data type, initialize it and pass it as an argument and see which function will be invoked.
  • 13. By: Asaye Chemeda Email: asayechemeda@yahoo.com 13 Now, have a look at all the print functions and their argument lists. Is there any one of them which takes an argument with char data type? None, right? But let us pass a parameter of char data type and make a function call and see what happens. Just change line 29 with the following and run the program. print(‘c’); The following message will be displayed. The second print function invoked. If you note which print function was invoked, it is the one which takes an int data type argument. The passed argument is of char data type and the invoked function takes int data type. Why so? When a char data type is passed, the compiler will look for the overloaded function which takes a char data type argument (Rule 1). If the compiler couldn’t find any, the compile will invoke the function which takes int data type (since int is at higher level in this group, see Rule 2). Rule 3: if function call is made to an overloaded function and Rule 1, which is stated above, failed, the compiler will look for and invoke the function which takes a data type which is at higher level in the same category as the data type of the passed argument. Read Rule 2 in detail first and a basic point regarding Rule 2 should be discussed at this point in accordance with Rule 3. If there is a data conversion, for instance, from int to double or float, Rule 2 is not valid anymore and the compiler will result in an error. While trying to invoke an overloaded function, if all the above three rules fail and the compiler finds it ambiguous to choose between two functions, the compiler will send an error message. For instance, try to replace line 29 of the program with the following and run it. print(10.0,10.0); When you run the program, the compiler will get difficulty in choosing between the seventh and eighth print functions. Because with the above three rules, you cannot justify which one the compiler should have invoked. But try to make the data types of both the arguments of the last print function double and run the program. Now, you will see that this changed print function will be invoked because of Rule 2. Do you think that sequence of data types also matters in selecting which function to invoke? Of course it does. If you see the fifth and sixth print functions closely, both take a double and string data type but with a different sequence. Which print function will be invoked if you change line 29 with the following statement and run the program? print(10.0,”C++”); It is the fifth print function, right? Because, this particular print function has the same sequence of data type of arguments as the passed arguments. Therefore, its invocation is not a surprise. This concludes our discussion on function overloading. Before proceeding to the last topic of this chapter, let us see some real world C++ functions. Suppose you are a programmer in a bank and you are given a task of writing a piece of code by your boss. The piece of code which you have to write is a function which calculates the current amount of money for the bank’s customers. Obviously, the current amount is dependent on the principal amount of money (the value at the previous current amount), the period between the previous and this current amount calculation and the interest rate. In short, the current amount is dependent three variables: principal amount, period and interest rate. Based on what we discussed so far, you will tend to define a function which takes three parameters. Or do you have another approach? Unless one or more of the three variables is defined as a global variable or unless you obtain their values by calling another function or other object-oriented programming approach, the function which you are going to write should take the values of these variables as parameters. Let us say your function takes these three variables as parameters. As employee of the bank, say, you know that the interest rate of the bank changes only in rare conditions. Therefore, it may be unwise to create a function which always takes the value of this variable as an argument. At the same time, if you remove it from the argument list, your function will not work in those rare conditions where the interest rate might change. So, what would you do? There is another approach which you can do. It wasn’t discussed in this chapter but it will solve your problem. Here is the solution. You will still make your function to take three variables but you will initialize the interest rate variable on the signature of your function with the rarely changed interest rate value. You have to also make this variable, the right-most variable in the argument list. What will happen if you do so? Your function can be invoked by passing only the other two variables. If your function is called with only two parameters, by default, it takes the initialized value the interest rate from the signature and calculates the current amount. If the bank changes its interest rate, your function can be called with three parameters, the third parameter being the new interest rate value. When your function is called with three
  • 14. By: Asaye Chemeda Email: asayechemeda@yahoo.com 14 parameter, it will not use the initialized interest rate value. It will use the new one. Problem solved! By the way, do you know what such kind of parameters, like that of the interest rate, are called? They are called default parameters in C++. If you initialize parameters, in the signature of the function, those parameters are called default parameters. Default parameters should always be written on the right hand side of the argument list. When you call the function, you can omit passing the values of default parameters. In a function having more than one default variable, if you omit a default variable, all the default parameters on the right hand side of the omitted default parameter should also be omitted. During function call, if the default parameter is omitted, the function uses the default values in the signature. If you pass the values of the default parameters during a function call, the passed values will override the default values. Interesting! Isn’t it? The default parameters concept made your function to be dynamic. Let us see if there are ways by which a function can be made more dynamic in C++. Now consider another scenario than your bank assignment. What if you want to make a single function take unlimited numbers of arguments with unlimited data type? Is there a possibility? Of course, there is. Didn’t we say, C++ is versatile? You can also define a function which takes unlimited number of arguments in C++. To define such a function, two conditions are mandatory though. The first one is, the function should have at least one defined argument. The second one is you have to put three dots after a coma on the right hand side of the signature of the function. That is it. If you define a function fulfilling these two conditions, the function can now take any number and data type of arguments. In this case the function is said to take variable-length argument lists. To understand the concept of default parameters and variable-length argument lists, have a look at the following program. Program 1.15[Correct].cpp In the above program, the print function has one default parameter (a) which is initialized with a default value of 1. On the right hand side of the signature, there are three dots after a coma. Therefore, we expect the function to take any number and data type of arguments. When this function is invoked, it will display two messages which you can see from the body of the function. One of them is printing the value of the default parameter. The print function is called from the main function three times by passing different number and data type of arguments. All of these invoked the print function. The first call with empty parameter invoked the print function only because the only mandatory argument in the print function is a default parameter. If you remove the initialization from the signature of the print function, there will be compilation error. Because when you call functions with variable-length argument lists, you have to at least pass one argument unless that argument is a default parameter. The displayed message when you run the program is shown below. From the output message we can notice that the print function is invoked three times. During the first invocation, the value of a was not passed and the default value is printed. During the second and the third invocations, the passed values of a were printed overriding the default value. We have almost covered what we have to discuss in this chapter. Only one topic is remaining. The concept which we are going to discuss in this last topic will help us understand a way by which we can reduce the computation time while working with frequently called functions. When normal functions are called there are overhear (regular) function call procedures. These procedures might take a considerable computation time and under certain programming circumstances, every nanosecond might be precious. At the compiler’s will, however, there is a way by which we can avoid these overhead function call procedures, by using special types of functions. These special functions will be the last topic of this chapter. Inline functions In an environment where computation time is very precious, avoiding the overhead function call procedures might be very useful. C++ has the facility to avoid these
  • 15. By: Asaye Chemeda Email: asayechemeda@yahoo.com 15 procedures, at the compiler’s will, by using special functions called inline functions. When inline functions are called in a program, the compiler will replace the call by the corresponding code of the functions. In other words, the body of the inline functions acts as if it is expanded at the place where the function is call is made. Because of this, those overhead function call procedures will be avoided. To make functions inline, putting the inline keyword in front of the function definition is sufficient. Putting the keyword will request the compiler to expand the function inline while it is invoked. The compiler will not take this as a command and the functions will be expanded only if the compiler accepts the request. If the compiler finds the function to be too complicated, it may reject the request and consider it as a normal function even if there is an inline key word in front of the function definition. It is advisable not to have prototype of inline functions. Because if an inline function has a prototype, the compiler will consider it just as a normal function. There may also be a drawback associated with inline functions. As one of the benefits of having functions is to save memory, when the compiler expands the inline function at the place of the function call, this benefit may be lost. The following program shows an example of an inline function. Program 1.16[Correct].cpp In the above program, the maximum function is an inline function. If the compiler expands the function during the function call. The above program is equivalent to the program shown below. Program 1.17[Correct].cpp Our discussion about one of the fundamental concepts in C++, function, is now over? It was interesting, right? Hopefully, you have grasped the basic knowledge about functions. There is a lot more to grab and let us go for it.