Chapter 6: Functions
Sections 6.16.13
Textbooks: Y. Daniel Liang, Introduction to Programming with C++, 3rd Edition
© Copyright 2016 by Pearson Education, Inc. All Rights Reserved.
These slides were adapted by Prof. Gheith Abandah from the Computer Engineering Department of the University
of Jordan for the Course: Computer Skills for Engineers (0907101)
Updated by Dr. Ashraf Suyyagh (Spring 2021) 1
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
2
Introduction
Find the sum of integers from 1 to 10, from
20 to 37, and from 35 to 49, respectively.
3
Introduction
int sum = 0; Write 3 loops
for (int i = 1; i <= 10; i++)
sum += i;
cout << "Sum from 1 to 10 is " << sum << endl;
sum = 0;
for (int i = 20; i <= 37; i++)
sum += i;
cout << "Sum from 20 to 37 is " << sum << endl;
sum = 0;
for (int i = 35; i <= 49; i++)
sum += i;
cout << "Sum from 35 to 49 is " << sum << endl;
4
Introduction
int sum = 0; Very similar 3
for (int i = 1; i <= 10; i++) loops
sum += i;
cout << "Sum from 1 to 10 is " << sum << endl;
sum = 0;
for (int i = 20; i <= 37; i++)
sum += i;
cout << "Sum from 20 to 37 is " << sum << endl;
sum = 0;
for (int i = 35; i <= 49; i++)
sum += i;
cout << "Sum from 35 to 49 is " << sum << endl;
5
Introduction
Functions can be used to define reusable
code and organize and simplify code.
int sum(int i1, int i2)
{
int sum = 0;
for (int i = i1; i <= i2; i++)
sum += i;
return sum;
}
int main()
{
cout << "Sum from 1 to 10 is " << sum(1, 10) << end
cout << "Sum from 20 to 37 is " << sum(20, 37) <<
endl;
cout << "Sum from 35 to 49 is " << sum(35, 49) <<
endl; 6
return 0;
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
7
Defining a Function
• A function is a collection of statements that
are grouped together to perform an
operation.
• A function definition consists of its function
name, parameters, return value type, and
body.
8
Defining Functions,
cont.
Function signature is the combination
of the function name and the
parameter list.
The variables defined in the function
header are known as formal
parameters.
When a function is invoked, you pass
a value to the parameter. This value is
referred to as actual parameter or
argument. 9
Defining Functions,
cont.
A Function may return a value.
The return value type is the data type
of the value the function returns.
If the function does not return a value,
the return value type is the keyword
void.
10
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
11
Calling a Function
This program demonstrates calling a
Function max to return the largest of
the int values
TestMax Run
12
animation
Trace Function
Invocation
i is now 5
13
animation
Trace Function
Invocation
j is now 2
14
animation
Trace Function
Invocation
invoke max(i, j)
15
animation
Trace Function
Invocation
invoke max(i, j)
Pass the value of i to num1
Pass the value of j to num2
16
animation
Trace Function
Invocation
declare variable result
17
animation
Trace Function
Invocation
(num1 > num2) is true since num1
is 5 and num2 is 2
18
animation
Trace Function
Invocation
result is now 5
19
animation
Trace Function
Invocation
return result, which is 5
20
animation
Trace Function
Invocation
return max(i, j) and assign the
return value to k
21
animation
Trace Function
Invocation
Execute the print statement
22
Call Stacks
• Each time a function is invoked, the
system creates an activation record.
• The activation record is placed in an
area of memory known as a call
stack.
23
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
24
void Functions
A void function does not return a value.
Want to print the grade for a given
score.
Two solutions:
1. printGrade prints the grade
2. getGrade prints the grade
TestVoidFunction Run
TestReturnGradeFunction Run
25
void Functions
void printGrade(double score) char getGrade(double score)
{ {
if (score >= 90.0) if (score >= 90.0)
cout << 'A' << endl; return 'A';
else if (score >= 80.0) else if (score >= 80.0)
cout << 'B' << endl; return 'B';
else if (score >= 70.0) else if (score >= 70.0)
cout << 'C' << endl; return 'C';
else if (score >= 60.0) else if (score >= 60.0)
cout << 'D' << endl; return 'D';
else else
cout << 'F' << endl; return 'F';
} }
int main() int main()
{ {
cout << "Enter a score: "; cout << "Enter a score: ";
double score; double score;
cin >> score; cin >> score;
cout << "The grade is "; cout << "The grade is ";
printGrade(score); cout << getGrade(score) <<
return 0; endl; 26
} return 0;
Terminating a Program
void printGrade(double score)
• You can terminate
{
a program at if (score < 0 || score > 100)
{
abnormal
cout << "Invalid score" << endl;
conditions by exit(1);
}
calling exit(n).
if (score >= 90.0)
• Select the integer n cout << 'A';
else if (score >= 80.0)
to specify the error
cout << 'B';
type. else if (score >= 70.0)
cout << 'C';
else if (score >= 60.0)
cout << 'D';
else
cout << 'F';
} 27
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
28
Passing Arguments by
Value
• By default, the
arguments are passed by
value to parameters
when invoking a
function. void nPrint(char ch, int n)
• When calling a function, {
you need to provide for (int i = 0; i < n; i+
arguments, which must +)
be given in the same cout << ch;
order as their respective }
parameters in the
function signature. nPrint('a', 3);
• The shown code prints a
character 3 times. aaa
29
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
30
Modularizing Code
• Modularizing makes the code easy to maintain
and debug and enables the code to be reused.
• These two examples use functions to reduce
complexity.
GreatestCommonDivisorFunction Run
PrimeNumberFunction Run
31
GreatestCommonDivisorFunctio
n.cpp
int gcd(int n1, int n2)
{
int gcd = 1; // Initial gcd is 1
int k = 2; // Possible gcd
while (k <= n1 && k <= n2)
{
if (n1 % k == 0 && n2 % k == 0)
gcd = k; // Update gcd
k++;
}
return gcd; // Return gcd
}
int main()
{
...
cout << "The greatest common divisor for " << n1 <<
" and " << n2 << " is " << gcd(n1, n2) << endl;
return 0;
}
32
PrimeNumberFunction.cpp 1/3
#include <iostream>
#include <iomanip>
using namespace std;
// Check whether number is prime
bool isPrime(int number)
{
for (int divisor = 2; divisor <= number / 2; divisor+
+)
{
if (number % divisor == 0)
{
// If true, number is not prime
return false; // number is not a prime
}
}
return true; // number is prime
} 33
PrimeNumberFunction.cpp 2/3
void printPrimeNumbers(int numberOfPrimes)
{
int count = 0; // Count the number of prime numbers
int number = 2; // A number to be tested for primeness
// Repeatedly find prime numbers
while (count < numberOfPrimes)
{
// Print the prime number and increase the count
if (isPrime(number))
{
count++; // Increase the count
if (count % 10 == 0) // 10 numbers per line
{
// Print the number and advance to the new line
cout << setw(4) << number << endl;
}
else
cout << setw(4) << number;
}
number++; // Check if the next number is prime
} 34
}
PrimeNumberFunction.cpp 3/3
int main()
{
cout << "The first 50 prime numbers are \n";
printPrimeNumbers(50);
return 0;
}
35
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
36
Overloading Functions
Overloading functions enables you to
define functions with the same name as
long as their signatures are different.
• The max function that was used earlier works
only with the int data type.
• We can define and use other max functions
that accept different parameter counts and
types.
TestFunctionOverloading Run
37
TestFunctionOverloading
#include <iostream>
.cpp 1/2
using namespace std;
// Return the max between two int values
int max(int num1, int num2)
{
if (num1 > num2)
return num1;
else
return num2;
}
// Find the max between two double values
double max(double num1, double num2)
{
if (num1 > num2)
return num1;
else
return num2;
} 38
TestFunctionOverloading
.cpp
// Return the max among 2/2
three double values
double max(double num1, double num2, double num3)
{
return max(max(num1, num2), num3);
}
int main()
{
// Invoke the max function with int parameters
cout << "The max between 3 and 4 is " << max(3, 4) <<
endl;
// Invoke the max function with the double parameters
cout << "The maximum between 3.0 and 5.4 is "
<< max(3.0, 5.4) << endl;
// Invoke the max function with three double
parameters
cout << "The maximum between 3.0, 5.4, and 10.14 is "
<< max(3.0, 5.4, 10.14) << endl;
39
Ambiguous Invocation
Sometimes there may be two or more
possible matches for an invocation of
a function, but the compiler cannot
determine the most specific match.
This is referred to as ambiguous
invocation. Ambiguous invocation is a
compilation error.
40
Ambiguous Invocation
#include <iostream>
using namespace std;
int maxNumber(int num1, double num2)
{
if (num1 > num2)
return num1;
else
return num2;
}
double maxNumber(double num1, int num2)
{
if (num1 > num2)
return num1; maxNumber(1.0, 2)
else And
return num2; maxNumber(1, 2.0)
} Are OK
int main()
{
cout << maxNumber(1, 2) << endl; // Compilation
error
return 0; 41
}
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
42
Function Prototypes
• Before a function is called, it must be declared first.
• One way to ensure it is to place the declaration
before all function calls.
• Another way to approach it is to declare a function
prototype before the function is called.
• A function prototype is a function declaration
without implementation.
• The implementation can be given later in the
program.
TestFunctionPrototype Run
43
TestFunctionPrototype.c
pp
#include <iostream>
using namespace std;
// Function prototype
int max(int num1, int num2);
double max(double num1, double num2);
double max(double num1, double num2, double num3);
int main()
{
// Invoke the max function with int parameters
cout << "The maximum between 3 and 4 is " <<
max(3, 4) << endl;
...
}
// Return the max between two int values
int max(int num1, int num2)
{ Or simply:
if (num1 > num2) int max(int, int);
return num1; double max(double, double);
else double max(double, double,
return num2; double);
}
... 44
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
45
Default Arguments
You can define default values for
parameters in a function.
The default values are passed to the
parameters when a function is invoked
without the arguments.
DefaultArgumentDemo Run
46
DefaultArgumentDemo.c
pp
#include <iostream>
using namespace std;
// Display area of a circle
void printArea(double radius = 1)
{
double area = radius * radius * 3.14159;
cout << "area is " << area << endl;
}
int main()
{
printArea();
printArea(4);
return 0;
}
47
Default Arguments
• When a function contains a mixture of
parameters with and without default
values, those with default values must be
declared last.
• When an argument is left out of a function,
all arguments that come after it must be
left out as well.
48
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
49
Inline Functions
C++ provides inline functions for improving
performance for short functions.
• Inline functions are not called; rather, the
compiler copies the function code in line at
the point of each invocation.
• To specify an inline function, precede the
function declaration with the inline
keyword.
• Inline functions are desirable for short
functions but not for long ones.
InlineDemo Run
InlineExpandedDemo
50
InlineDemo.cpp
#include <iostream>
using namespace std;
inline void f(int month, int year)
{
cout << "month is " << month << endl;
cout << "year is " << year << endl;
}
int main()
{
int month = 10, year = 2008;
f(month, year); // Invoke inline function
f(9, 2010); // Invoke inline function
return 0;
}
51
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
52
Scope of Variables
• Scope: the part of the program where the
variable can be referenced.
• The scope of a variable starts from its
declaration and continues to the end of the
block that contains the variable.
• A variable can be declared as a local, a
global, or a static local.
• A local variable: a variable defined inside a
function.
• You can declare a local variable with the
same name in different blocks.
53
Scope of Local
Variables
• A variable declared in the initial action part of
a for loop has its scope in the entire loop.
• A variable declared inside a for loop body has
its scope limited the rest of the loop body.
54
Scope of Local
Variables, cont.
• It is acceptable to declare a local variable with
the same name in different non-nesting
blocks.
• Avoid using same variable name in nesting
blocks to minimize making mistakes.
55
Global Variables
• Global variables are declared outside all
functions and are accessible to all
functions in their scope.
• Local variables do not have default values,
but global variables are defaulted to zero.
VariableScopeDemo Run
56
VariableScopeDemo.cpp
#include <iostream>
using namespace std;
void t1(); // Function void t1()
prototype {
void t2(); // Function int x = 1;
prototype cout << "x is " << x << endl;
cout << "y is " << y << endl;
int main() x++;
{ y++;
t1(); }
t2();
void t2()
return 0; {
} int x = 1;
cout << "x is " << x << endl;
int y; // Global variable cout << "y is " << y << endl;
// default to 0 }
57
Unary Scope Resolution
If a local variable name is the same as a global
variable name, you can access the global
variable using ::globalVariable. The :: operator
is known as the unary scope resolution.
#include <iostream>
using namespace std;
int v1 = 10;
int main()
{
int v1 = 5;
cout << "local variable v1 is " << v1 << endl;
cout << "global variable v1 is " << ::v1 << endl;
return 0;
} local variable v1 is 5
global variable v1 is
10 58
Static Local Variables
• After a function completes its execution, all its local
variables are destroyed.
• To retain the value stored in local variables so that
they can be used in the next call, use static local
variables.
• Static local variables are permanently allocated in
the memory for the lifetime of the program.
• To declare a static variable, use the keyword static.
StaticVariableDemo Run
59
StaticVariableDemo.cpp
#include <iostream>
using namespace std;
void t1(); // Function prototype
int main()
{
t1();
t1();
return 0;
}
void t1()
{
static int x = 1; // Static local
int y = 1; // Local, not static
x++;
y++;
cout << "x is " << x << endl;
cout << "y is " << y << endl;
60
}
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
61
Pass by Value
• When you invoke a function with a
parameter, the value of the
argument is passed to the
parameter. This is referred to as
pass-by-value.
• The variable is not affected,
regardless of the changes made to
the parameter inside the function.
Increment Run
62
Increment.cpp
#include <iostream>
using namespace std;
void increment(int n)
{
n++;
cout << "\tn inside the function is " << n << endl;
}
int main()
{
int x = 1;
cout << "Before the call, x is " << x << endl;
increment(x);
cout << "after the call, x is " << x << endl;
return 0;
}
63
Reference Variables
• A reference variable can be used as a function
parameter to reference the original variable.
• A reference variable is an alias for another
variable.
• Any changes made through the reference
variable are actually performed on the original
variable.
• To declare a reference variable, place the
ampersand (&) in front of the name. Run
TestReferenceVariable
64
TestReferenceVariable.cp
p
#include <iostream>
using namespace std;
int main()
{
int count = 1;
int& r = count;
cout << "count is " << count << endl;
cout << "r is " << r << endl;
r++;
cout << "count is " << count << endl;
cout << "r is " << r << endl;
count = 10;
cout << "count is " << count << endl;
cout << "r is " << r << endl;
return 0;
65
}
Pass By Reference
Parameters can be passed by reference,
which makes the formal parameter an alias
of the actual argument. Thus, changes
made to the parameters inside the function
also made to the arguments.
SwapByReference Run
66
SwapByReference.cpp
1/2
#include <iostream>
using namespace std;
// Swap two variables
void swap(int& n1, int& n2)
{
cout << "\tInside the swap function" << endl;
cout << "\tBefore swapping n1 is " << n1 <<
" n2 is " << n2 << endl;
// Swap n1 with n2
int temp = n1;
n1 = n2;
n2 = temp;
cout << "\tAfter swapping n1 is " << n1 <<
" n2 is " << n2 << endl;
} 67
SwapByReference.cpp
2/2
int main()
{
// Declare and initialize variables
int num1 = 1;
int num2 = 2;
cout << "Before invoking the swap function, num1 is "
<< num1 << " and num2 is " << num2 << endl;
// Invoke the swap function to attempt to swap two
variables
swap(num1, num2);
cout << "After invoking the swap function, num1 is "
<< num1
<< " and num2 is " << num2 << endl;
return 0; 68
}
Pass-by-Value vs. Pass-
by-Reference
• In pass-by-value, the actual parameter and
its formal parameter are independent
variables.
• In pass-by-reference, the actual parameter
and its formal parameter refer to the same
variable.
• Pass-by-reference is more efficient than
pass-by-value. However, the difference is
negligible for parameters of primitive types
such as int and double.
• So, if a primitive data type parameter is not
changed in the function, you should declare69
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
70
Constant Reference Parameters
You can specify a constant reference
parameter to prevent its value from being
changed by accident.
// Return the max between two numbers
int max(const int& num1, const int& num2)
{
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
71
Outline
• Introduction
• Defining a Function
• Calling a Function
• void Functions
• Passing Arguments by Value
• Modularizing Code
• Overloading Functions
• Function Prototypes
• Default Arguments
• Inline Functions
• Local, Global, and Static Local Variables
• Passing Arguments by Reference
• Constant Reference Parameters
72