Chapter 6 - Functions
6.1 Modular Programming
- Modular programming: breaking a program up into smaller, manageable functions or modules
- Function: a collection of statements to perform a task
- Motivation for modular programming:
- Improves maintainability of programs
- Simplifies the process of writing programs
6.2 Defining and Calling Functions
- Function call: statement causes a function to execute
- Function definition: statements that make up a function
Function Definition
Definition includes:
- return type: data type of the value that function returns to the part of the program that called it
- name: name of the function. Function names follow same rules as variables
- parameter list: variables containing values passed to the function
- body: statements that perform the function’s task, enclosed in {}
Function Return Type
If a function returns a value, the type of the value must be indicated:
int main()
If a function does not return a value, its return type is void:
void printHeading()
{
cout << "Monthly Sales\n";
}
Calling a Function
To call a function, use the function name followed by () and ;
printHeading();
When called, program executes the body of the called function
After the function terminates, execution resumes in the calling function at point of call.
// Functions in Program 6-1
// This program has two functions: main and displayMessage
#include <iostream>
using namespace std;
//*****************************************
// Definition of function displayMessage *
// This function displays a greeting. *
//*****************************************
void displayMessage()
{
cout << "Hello from the function displayMessage.\n";
}
//*****************************************
//
Function
main
*
//*****************************************
int main()
{
cout << "Hello from main.\n";
displayMessage();
cout << "Back in function main again.\n";
return 0;
}
Calling Functions
- main can call any number of functions
- Functions can call other functions
- Compiler must know the following about a function before it is called:
- data type of each parameter
6.3 Function Prototypes
Ways to notify the compiler about a function before a call to the function:
Place function definition before calling function’s definition
Use a function prototype (function declaration) – like the function definition without the body
Header: void printHeading()
Prototype: void printHeading();
// Program 6.5
// This program has three functions: main, first, and second.
#include <iostream>
using namespace std;
// Function Prototypes
void first();
void second();
int main()
{
cout << "I am starting in function main.\n";
first(); // Call function first
second(); // Call function second
cout << "Back in function main again.\n";
return 0;
}
//*************************************
// Definition of function first. *
// This function displays a message. *
//*************************************
void first()
{
cout << "I am now inside the function first.\n";
}
//*************************************
// Definition of function second. *
// This function displays a message. *
//*************************************
void second()
{
cout << "I am now inside the function second.\n";
}
Prototype Notes
- Place prototypes near top of program
- Program must include either prototype or full function definition before any call to the function – compiler error otherwise
- When using prototypes, can place function definitions in any order in source file
6.4 Sending Data into a Function
Can pass values into a function at time of call:
c = pow(a, b);
Values passed to function are arguments
Variables in a function that hold the values passed as arguments are parameters
A Function with a Parameter Variable
void displayValue(int num)
{
cout << "The value is " << num << endl;
}
- The
integer variable num is a
parameter.
- It accepts any integer value passed to the function.
// Program 6.6
// This program demonstrates a function with a parameter.
#include <iostream>
using namespace std;
// Function Prototype
void displayValue(int);
int main()
{
cout << "I am passing 5 to displayValue.\n";
displayValue(5); // Call displayValue with argument 5
cout << "Now I am back in main.\n";
return 0;
}
//*********************************************************
//
Definition of function
displayValue.
*
// It uses an integer parameter whose value is displayed. *
//*********************************************************
void displayValue(int num)
{
cout << "The value is " << num << endl;
}
Other Parameter Terminology
- A parameter can also be called a formal parameter or a formal argument
- An argument can also be called an actual parameter or an actual argument
Parameters, Prototypes, and Function Headers
For each function argument,
the prototype must include the data type of each parameter inside its parentheses
the header must include a declaration for each parameter in its ()
void evenOrOdd(int); //prototype
void evenOrOdd(int num) //header
evenOrOdd(val); //call
Function Call Notes
- Value of argument is copied into parameter when the function is called
- A parameter’s scope is the function which uses it
- Function can have multiple parameters
- There must be a data type listed in the prototype () and an argument declaration in the function header () for each parameter
- Arguments will be promoted/demoted as necessary to match parameters
Passing Multiple Arguments
- When calling a function and passing multiple arguments:
- the number of arguments in the call must match the prototype and definition
- the first argument will be used to initialize the first parameter, the second argument to initialize the second parameter, etc.
// This program demonstrates a function with three parameters.
#include <iostream>
using namespace std;
// Function Prototype
void showSum(int, int, int);
int main()
{
int value1, value2, value3;
// Get three integers.
cout << "Enter three integers and I will display ";
cout << "their sum: ";
cin >> value1 >> value2 >> value3;
// Call showSum passing three arguments.
showSum(value1, value2, value3);
return 0;
}
//************************************************************
//
Definition of function
showSum.
*
// It uses three integer parameters. Their sum is displayed. *
//************************************************************
void showSum(int num1, int num2, int num3)
{
cout << (num1 + num2 + num3) << endl;
}
6.5 Passing Data by Value
- Pass by value: when an argument is passed to a function, its value is copied into the parameter.
- Changes to the parameter in the function do not affect the value of the argument
Passing Information to Parameters by Value
evenOrOdd can change variable num, but it will have no effect on variable val
6.6 Using Functions in Menu-Driven Programs
Using Functions in Menu-Driven Programs
Functions can be used
- to implement user choices from menu
- to implement general-purpose tasks:
Higher-level functions can call general-purpose functions,
minimizing the total number of functions and speeding program
development time
// Program 6-10
// This is a menu-driven program that makes a function call
// for each selection the user makes.
#include <iostream>
#include <iomanip>
using namespace std;
// Function prototypes
void showMenu();
void showFees(double, int);
int main()
{
int choice; // To hold a menu choice
int months; // To hold a number of months
// Constants for the menu choices
const int ADULT_CHOICE = 1,
CHILD_CHOICE = 2,
SENIOR_CHOICE = 3,
QUIT_CHOICE = 4;
// Constants for membership rates
const double ADULT = 40.0,
SENIOR = 30.0,
CHILD = 20.0;
// Set up numeric output formatting.
cout << fixed << showpoint << setprecision(2);
do
{
// Display the menu and get the user's choice.
showMenu();
cin >> choice;
// Validate the menu selection.
while (choice < ADULT_CHOICE || choice > QUIT_CHOICE)
{
cout << "Please enter a valid menu choice: ";
cin >> choice;
}
// If the user does not want to quit, proceed.
if (choice != QUIT_CHOICE)
{
// Get the number of months.
cout << "For how many months? ";
cin >> months;
// Display the membership fees.
switch (choice)
{
case ADULT_CHOICE:
showFees(ADULT, months);
break;
case CHILD_CHOICE:
showFees(CHILD, months);
break;
case SENIOR_CHOICE:
showFees(SENIOR, months);
}
}
} while (choice != QUIT_CHOICE);
return 0;
}
//*****************************************************************
// Definition of function showMenu which displays the menu. *
//*****************************************************************
void showMenu()
{
cout << "\n\t\tHealth Club Membership Menu\n\n"
<< "1. Standard Adult Membership\n"
<< "2. Child Membership\n"
<< "3. Senior Citizen Membership\n"
<< "4. Quit the Program\n\n"
<< "Enter your choice: ";
}
//*****************************************************************
// Definition of function showFees. The memberRate parameter *
// the monthly membership rate and the months parameter holds the *
// number of months. The function displays the total charges. *
//*****************************************************************
void showFees(double memberRate, int months)
{
cout << "The total charges are $"
<< (memberRate * months) << endl;
}
6.7 The return Statement
- Used to end execution of a function
- Can be placed anywhere in a function
- Statements that follow the return statement will not be executed
- Can be used to prevent abnormal termination of program
- In a void function without a return statement, the function ends at its last }
// Program 6-11
// This program uses a function to perform division. If division
// by zero is detected, the function returns.
#include <iostream>
using namespace std;
// Function prototype.
void divide(double, double);
int main()
{
double num1, num2;
cout << "Enter two numbers and I will divide the first\n";
cout << "number by the second number: ";
cin >> num1 >> num2;
divide(num1, num2);
return 0;
}
//***************************************************************
//
Definition of function
divide.
*
// Uses two parameters: arg1 and arg2. The function divides arg1*
// by arg2 and shows the result. If arg2 is zero, however, the *
//
function
returns.
*
//***************************************************************
void divide(double arg1, double arg2)
{
if (arg2 == 0.0)
{
cout << "Sorry, I cannot divide by zero.\n";
return;
}
cout << "The quotient is " << (arg1 / arg2) << endl;
}
6.8 Returning a Value From a Function
- A function can return a value back to the statement that called the function.
- You've already seen the pow function, which returns a value:
double x;
x = pow(2.0, 10.0);
In a value-returning function, the return statement can be used to return a value from function to the point of call. Example:
int sum(int num1, int num2)
{
double result;
result = num1 + num2;
return result;
}
// Program 6-12
// This program uses a function that returns a value.
#include <iostream>
using namespace std;
// Function prototype
int sum(int, int);
int main()
{
int value1 = 20, // The first value
value2 = 40, // The second value
total; // To hold the total
// Call the sum function, passing the contents of
// value1 and value2 as arguments. Assign the return
// value to the total variable.
total = sum(value1, value2);
// Display the sum of the values.
cout << "The sum of " << value1 << " and "
<< value2 << " is " << total << endl;
return 0;
}
//*****************************************************
// Definition of function sum. This function returns *
//
the sum of its two
parameters.
*
//*****************************************************
int sum(int num1, int num2)
{
return num1 + num2;
}
// Program 6-13
// This program demonstrates two value-returning functions.
// The square function is called in a mathematical statement.
#include <iostream>
#include <iomanip>
using namespace std;
//Function prototypes
double getRadius();
double square(double);
int main()
{
const double PI = 3.14159; // Constant for pi
double
radius;
// To hold the circle's radius
double
area;
// To hold the circle's area
// Set the numeric output formatting.
cout << fixed << showpoint << setprecision(2);
// Get the radius of the circle.
cout << "This program calculates the area of ";
cout << "a circle.\n";
radius = getRadius();
// Caclulate the area of the circle.
area = PI * square(radius);
// Display the area.
cout << "The area is " << area << endl;
return 0;
}
//******************************************************
//
Definition of function
getRadius.
*
// This function asks the user to enter the radius of *
// the circle and then returns that number as a double.*
//******************************************************
double getRadius()
{
double rad;
cout << "Enter the radius of the circle: ";
cin >> rad;
return rad;
}
//******************************************************
//
Definition of function
square.
*
// This function accepts a double argument and returns *
// the square of the argument as a double. *
//******************************************************
double square(double number)
{
return number * number;
}
Returning a Value From a Function
- The prototype and the definition must indicate the data type of return value (not void)
- Calling function should use return value:
6.9 Returning a Boolean Value
- Function can return true or false
- Declare return type in function prototype and heading as bool
- Function body must contain return statement(s) that return true or false
- Calling function can use return value in a relational expression
// Program 6-15
// This program uses a function that returns true or false.
#include <iostream>
using namespace std;
// Function prototype
bool isEven(int);
int main()
{
int val;
// Get a number from the user.
cout << "Enter an integer and I will tell you ";
cout << "if it is even or odd: ";
cin >> val;
// Indicate whether it is even or odd.
if (isEven(val))
cout << val << " is even.\n";
else
cout << val << " is odd.\n";
return 0;
}
//*****************************************************************
// Definition of function isEven. This function accepts an *
// integer argument and tests it to be even or odd. The function *
// returns true if the argument is even or false if the argument *
//
is odd. The return value is an
bool.
*
//*****************************************************************
bool isEven(int number)
{
bool status;
if (number % 2 == 0)
status = true; // number is even if there is no remainder.
else
status = false; // Otherwise, the number is odd.
return status;
}
6.10 Local and Global Variables
- Variables
defined inside a function are local to that function. They are hidden
from the statements in other functions, which normally cannot access
them.
- Because the variables defined in a function are hidden,
other functions may have separate, distinct variables with the same
name.
// Program 6-16
// This program shows that variables defined in a function
// are hidden from other functions.
#include <iostream>
using namespace std;
void anotherFunction(); // Function prototype
int main()
{
int num = 1; // Local variable
cout << "In main, num is " << num << endl;
anotherFunction();
cout << "Back in main, num is " << num << endl;
return 0;
}
//*****************************************************
//
Definition of
anotherFunction
*
// It has a local variable, num, whose initial value *
//
is
displayed.
*
//*****************************************************
void anotherFunction()
{
int num = 20; // Local variable
cout << "In anotherFunction, num is " << num << endl;
}
Local Variable Lifetime
- A function’s local variables exist only while the function is executing. This is known as the lifetime of a local variable.
- When
the function begins, its local variables and its parameter variables
are created in memory, and when the function ends, the local variables
and parameter variables are destroyed.
- This means that any value stored in a local variable is lost between calls to the function in which the variable is declared.
Global Variables and Global Constants
- A global variable is any variable defined outside all the functions in a program.
- The scope of a global variable is the portion of the program from the variable definition to the end.
- This means that a global variable can be accessed by all functions that are defined after the global variable is defined.
- You should avoid using global variables because they make programs difficult to debug.
- Any global that you create should be global constants.
// Program 6-19
// This program calculates gross pay.
#include <iostream>
#include <iomanip>
using namespace std;
// Global constants
const double PAY_RATE = 22.55; // Hourly pay rate
const double BASE_HOURS = 40.0; // Max non-overtime hours
const double OT_MULTIPLIER = 1.5; // Overtime multiplier
// Function prototypes
double getBasePay(double);
double getOvertimePay(double);
int main()
{
double hours, // Hours worked
basePay, // Base pay
overtime = 0.0, // Overtime pay
totalPay; // Total pay
// Get the number of hours worked.
cout << "How many hours did you work? ";
cin >> hours;
// Get the amount of base pay.
basePay = getBasePay(hours);
// Get overtime pay, if any.
if (hours > BASE_HOURS)
overtime = getOvertimePay(hours);
// Calculate the total pay.
totalPay = basePay + overtime;
// Set up numeric output formatting.
cout << setprecision(2) << fixed << showpoint;
// Display the pay.
cout << "Base pay: $" << basePay << endl
<< "Overtime pay $" << overtime << endl
<< "Total pay $" << totalPay << endl;
return 0;
}
//************************************************
// The getBasePay function accepts the number of *
// hours worked as an argument and returns the *
// employee's pay for non-overtime hours. *
//************************************************
double getBasePay(double hoursWorked)
{
double basePay; // To hold base pay
// Determine base pay.
if (hoursWorked > BASE_HOURS)
basePay = BASE_HOURS * PAY_RATE;
else
basePay = hoursWorked * PAY_RATE;
return basePay;
}
//*************************************************
// The getOvertimePay function accepts the number *
// of hours worked as an argument and returns the *
//
employee's overtime
pay.
*
//*************************************************
double getOvertimePay(double hoursWorked)
{
double overtimePay; // To hold overtime pay
// Determine overtime pay.
if (hoursWorked > BASE_HOURS)
{
overtimePay = (hoursWorked BASE_HOURS) *
PAY_RATE * OT_MULTIPLIER;
}
else
overtimePay = 0.0;
return overtimePay;
}
Initializing Local and Global Variables
- Local variables are not automatically initialized. They must be initialized by programmer.
- Global variables (not constants) are automatically initialized to 0 (numeric) or NULL (character) when the variable is defined.
6.11 Static Local Variables
- Local
variables only exist while the function is executing. When the
function terminates, the contents of local variables are lost.
- static local variables retain their contents between function calls.
- static
local variables are defined and initialized only the first time the
function is executed. 0 is the default initialization value.
// Program 6-21
// This program shows that local variables do not retain
// their values between function calls.
#include <iostream>
using namespace std;
// Function prototype
void showLocal();
int main()
{
showLocal();
showLocal();
return 0;
}
//***********************************************************
//
Definition of function
showLocal.
*
// The initial value of localNum, which is 5, is displayed. *
// The value of localNum is then changed to 99 before the *
//
function
returns.
*
//***********************************************************
void showLocal()
{
int localNum = 5; // Local variable
cout << "localNum is " << localNum << endl;
localNum = 99;
}
A Different Approach, Using a Static Variable
// Program 6-12
// This program uses a static local variable.
#include <iostream>
using namespace std;
void showStatic(); // Function prototype
int main()
{
// Call the showStatic function five times.
for (int count = 0; count < 5; count++)
showStatic();
return 0;
}
//**************************************************************
//
Definition of function
showStatic.
*
// statNum is a static local variable. Its value is displayed *
// and then incremented just before the function returns. *
//**************************************************************
void showStatic()
{
static int statNum;
cout << "statNum is " << statNum << endl;
statNum++;
}
6.12 Default Arguments
A Default argument is an argument that is passed
automatically to a parameter if the argument is missing on the function
call.
Must be a constant declared in prototype:
void evenOrOdd(int = 0);
Can be declared in header if no prototype
Multi-parameter functions may have default arguments for some or all of them:
int getSum(int, int=0, int=0);
If not all parameters to a function have default values, the defaultless ones are declared first in the parameter list:
int getSum(int, int=0, int=0);// OK
int getSum(int, int=0, int); // NO
When an argument is omitted from a function call, all arguments after it must also be omitted:
sum = getSum(num1, num2); // OK
sum = getSum(num1, , num3); // NO
6.13 Using Reference Variables as Parameters
- A mechanism that allows a function to work with the original argument from the function call, not a copy of the argument
- Allows the function to modify values stored in the calling environment
- Provides a way for the function to ‘return’ more than one value
Passing by Reference
A reference variable is an alias for another variable
Defined with an ampersand (&)
void getDimensions(int&, int&);
Changes to a reference variable are made to the variable it refers to
Use reference variables to implement passing parameters by reference
// Program 6-25
// This program uses a reference variable as a function
// parameter.
#include <iostream>
using namespace std;
// Function prototype. The parameter is a reference variable.
void doubleNum(int &);
int main()
{
int value = 4;
cout << "In main, value is " << value << endl;
cout << "Now calling doubleNum..." << endl;
doubleNum(value);
cout << "Now back in main. value is " << value << endl;
return 0;
}
//**********************************************************
//
Definition of
doubleNum.
*
// The parameter refVar is a reference variable. The value *
//
in refVar is
doubled.
*
//**********************************************************
void doubleNum (int &refVar)
{
refVar *= 2;
}
Reference Variable Notes
- Each reference parameter must contain &
- Space between type and & is unimportant
- Must use & in both prototype and header
- Argument passed to reference parameter must be a variable – cannot be an expression or constant
- Use when appropriate – don’t use when argument should not be changed by function, or if function needs to return only 1 value
6.14 Overloading Functions
- Overloaded functions have the same name but different parameter lists
- Can
be used to create functions that perform the same task but take
different parameter types or different number of parameters
- Compiler will determine which version of function to call by argument and parameter lists
Function Overloading Examples
Using these overloaded functions,
void getDimensions(int); // 1
void getDimensions(int, int); // 2
void getDimensions(int, double); // 3
void getDimensions(double, double);// 4
the compiler will use them as follows:
int length, width;
double base, height;
getDimensions(length); // 1
getDimensions(length, width); // 2
getDimensions(length, height); // 3
getDimensions(height, base); // 4
// Program 6-27
// This program uses overloaded functions.
#include <iostream>
#include <iomanip>
using namespace std;
// Function prototypes
int square(int);
double square(double);
int main()
{
int userInt;
double userFloat;
// Get an int and a double.
cout << fixed << showpoint << setprecision(2);
cout << "Enter an integer and a floating-point value: ";
cin >> userInt >> userFloat;
// Display their squares.
cout << "Here are their squares: ";
cout << square(userInt) << " and " << square(userFloat);
return 0;
}
//**************************************************************
//
Definition of overloaded function
square.
*
// This function uses an int parameter, number. It returns the *
//
square of number as an
int.
*
//**************************************************************
int square(int number)
{
return number * number;
}
//***************************************************************
//
Definition of overloaded function
square.
*
// This function uses a double parameter, number. It returns *
//
the square of number as a
double.
*
//***************************************************************
double square(double number)
{
return number * number;
}
6.15 The exit() Function
- Terminates the execution of a program
- Can be called from any function
- Can pass an int value to operating system to indicate status of program termination
- Usually used for abnormal termination of program
- Requires cstdlib header file
Example: exit(0);
The cstdlib header defines two constants that are commonly passed, to indicate success or failure:
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
6.16 Stubs and Drivers
Useful for testing and debugging program and function logic and design
Stub: A dummy function used in place of an actual function
Usually displays a message indicating it was called. May also display parameters
Driver: A function that tests another function by calling it
Various arguments are passed and return values are tested