You are on page 1of 35

Functions

Calling a Function
int main()
{
double z = pow(2, 3);
}

Inputs:
parameter values

main calls the pow function


(main is the caller)
The main function is temporarily suspended.
The instructions of the pow function execute and
compute the result.
The pow function returns its result back to main,
and the main function resumes execution
2

Calling a Function

Execution flow
during a
function call

An Output Statement Does Not Return a Value


NOTE: output return
If a caller needs the result of a calculation done by
a function, the function must have a return statement.
cout <<
does not communicate with the caller

The Black Box Concept

How did the pow function do its job?


You dont need to know.
You only need to know its specification (name,

parameters and return type).

Implementing Functions

When writing this function, you need to:


Pick a good, descriptive name for the function
Give a type and a name for each parameter.
Specify the type of the return value
double cube_volume(double side_length)

Implementing Functions

Parameter Passing
1. In the calling function, the local variable result1

already exists. When the cube_volume function is


called, the parameter variable side_length is created.

double result1 = cube_volume(2);

Parameter Passing
2. The parameter variable is initialized with the value that
was passed in the call. In our case, side_length is set
to 2.
double result1 = cube_volume(2);

Parameter Passing
3. The function computes the expression side_length *

side_length * side_length, which has the value 8.


That value is stored in the local variable volume.

[inside the function]

double volume = side_length * side_length * side_length;

10

Parameter Passing
4. The function returns, at which point all of its variables
are removed.
The return value is transferred to the caller, that is, the
function calling the cube_volume function, and stored
in the variable in the body of that caller
double result1 = cube_volume(2);

8
The function executed: return volume;
which gives the caller the value 8
side_length and volume are gone.
11

Functions Without Explicit Return Values

Consider the task of writing a string with the wrap-format around it.
For example, the string "Hello" would produce:
------!Hello!
-------

12

Functions Without Return Values The void Type

void as a return type, indicates that a function


does not return an actual value (of any type) to the caller.

Two important things about functions of a void type:


1.In the body of the function, theres no need for a return statement
2.In the body of the caller, canNOT use an assignment statement
to invoke it;
- Hence, we simply invoke it by its name in a given line

13

Good Design Keep Functions Short


There is a certain cost for writing a function:
You

need to design, code, and test the function.


The function needs to be documented.
You need to spend some effort to make the function reusable
rather than tied to a specific context.

14

More Programming Considerations


When writing a larger program, it is not always feasible

to implement and test all functions at once.


You often need to test a function that calls another, but
the other function hasnt yet been implemented.
You can temporarily replace the body of function yet to be

implemented with a stub:

a function that returns a simple (dummy) value, but good enough for

testing another function.

15

Variable Scope
RULE: A variable or parameter that is defined within a given function, is
visible from the point at which it is defined until
the end of the block named by the function.
This area is called the scope of the variable.
The scope of a variable is the part of the program in which it is visible.
Because scopes do not overlap, a name in one scope cannot conflict with any
name in another scope.
A name in one scope is invisible in another scope

16

Variable Scope Example


double cube_volume(double side_len)
{
double volume = side_len * side_len * side_len;
return volume;
NOTE: Since the scopes do
}
NOT overlap,
int main()
theres no conflict for the
variable name volume (i.e.,
{
a variable in one scope is
double volume = cube_volume(2);
not visible within the other)
cout << volume << endl;
return 0;
}
Each volume variable is defined in a separate function,
no problem with this code.
17

More on Scopes

On the other hand:


The following is NOT legal:
int test(double volume)
{
double volume = cube_volume(2);
double volume = cube_volume(10);
// ERROR: cannot define another volume variable
// ERROR: or parameter in the same scope
...
}
18

More on Scopes Nested Blocks


One can define another variable
with the same name in a nested block.
double withdraw(double balance, double amount)
{
if (...)
{
double amount = 10;
...
}
...
}

amount local to the if block


amount is overridden inside the if block

19

Special Scope: Global Variables


Global variables are declared outside of the function definitions
in a cpp file
In general, they are not a good idea.
However, sometimes, we simply must

Since they are outside of every block they are

visible inside of each and every block available


for use in that block;

20

Global Variables
In some cases, this is a good thing:
The <iostream> header defines these global variables:
cin
cout

21

Global Variables Another Setting

int balance = 10000; // A global variable


Strictly speaking, not
void withdraw(double amount)
much of a problem here
{
because:
if (balance >= amount)
1.Function withdraw is
{
the only one that modifies
balance = balance - amount;
the global variable
}
balance
}
2.Function main only
int main()
uses it (no modifications/
{
withdraw(1000);
updates)
cout << balance << endl;
return 0;
HOWEVER, if multiple functions modify one
}
single global variable, can get ugly
22

Global Variables Breaking Open the Black Box

Programs with global variables are difficult to maintain because you can no
longer view each function as a black box that simply receives parameter
values and returns a result or does something.
When functions modify global variables, it becomes more difficult to understand
the effect of function calls.

avoid

You should
global
variables in your programs!
23

Another PROBLEM
Consider a function that simulates withdrawing a given amount of
money from a bank account, provided that sufficient funds are
available.
If the amount of money is insufficient, a $10 penalty is deducted
instead.
The function would be used as follows:
double harrys_account = 1000;
withdraw(harrys_account, 100);
// Now harrys_account is 900
withdraw(harrys_account, 1000);
// Insufficient funds.
// Now harrys_account is 890
24

void withdraw(double balance, double amount)


{
const int PENALTY = 10;
if (balance >= amount)
{
balance = balance - amount;
}
else
{
balance = balance - PENALTY;
}
}

double harrys_account = 1000;


withdraw(harrys_account, 100);
// Now harrys_account is 900
withdraw(harrys_account, 1000);
// Insufficient funds.
// Now harrys_account is 890

But this doesnt work!!! (why?)


25

What is actually happening?


Lets call the function passing in 100 to be taken
from harrys_account.
double harrys_account = 1000;
withdraw(harrys_account, 100);

26

The local variables, consts, and value parameters are initialized.


double harrys_account = 1000;

withdraw(harrys_account, 100);

void withdraw(double balance, double amount)


{
const int PENALTY = 10;

27

else
{
}

NOTHING happens to
harrys_balance because
balance = balance - PENALTY; it is a separate variable
(in a different scope)

28

The function call has ended.


Local names in the function are gone and
NOTHING happened to harrys_balance.

withdraw(harrys_account, 100);

29

Reference Parameters
A reference parameter refers to a variable
that is supplied in a function call.
refers means that during the execution of the function, the
reference parameter name is another name for the callers
variable.
This referring is how a function
can change non-local variables (i.e., ones that are defined and/
or used in the outer scope of the callee):
changes to its local parameters names cause changes to the
callers variables they refer to.

30

Reference Parameters
To indicate a reference parameter,
you place an & after the type name.

void withdraw(double& balance, double amount)

To indicate a usual (aka value) parameter,


you do not place an & after the type name.
31

Reference Parameters
The type double& is pronouned:
reference to double
or
double ref

32

Reference Parameters
The parameter name balance refers to the
callers variable named harrys_account so that
changing balance changes harrys_account.
withdraw(harrys_account, 100);

33

Reference Parameters
A reference parameter must always be called with a variable.
i.e., you cant pass a constant value for a reference parameter it would be an
error
withdraw(1000, 500);
// Error: reference parameter must be a variable
The reason is clearthe function modifies the reference parameter, but it is
impossible to change the value of a constant number.
For the same reason, you cannot supply an expression:

withdraw(harrys_account + 150, 500);


// Error: reference parameter must be a variable
34

When to use Reference Parameters???

Whenever a modification to more than one value is

desired via a single function (reason: return can


only return one single value)
Whenever there are LARGE objects that need to be
modified (passing them by-value will create an
overhead of a memory space usage)

35

You might also like