Chapter 3 - Functions

1
Functions and Recursion
Outline
Storage Classes
Scope Rules
Functions with Empty Parameter Lists
Inline Functions
References and Reference Parameters
Default Arguments
Unary Scope Resolution Operator
Function Overloading
Function Templates
 2003 Prentice Hall, Inc. All rights reserved.
2
Storage Classes
• Variables have attributes
– Have seen name, type, size, value
– Storage class
• How long variable exists in memory (briefly or
throughout the execution of the program)
– Automatic vs. static storage
– Scope
• Where variable can be referenced (accessed) in
program (throughout the program or only in limited
portion)
– Linkage
• For multiple-file program, which files can use it (e.g.,
only source file or multiple files)
 2003 Prentice Hall, Inc. All rights reserved.
3
Storage Classes
• Automatic storage class
– Variable created when program enters its block
– Variable destroyed when program leaves block
– Only local variables of functions can be automatic
• Automatic by default
• keyword auto explicitly declares automatic
– register keyword
• Hint to place variable in high-speed register
• Good for often-used items (loop counters)
• Often unnecessary, compiler optimizes
– Specify either register or auto, not both
• auto double x;
• register int counter = 1;
 2003 Prentice Hall, Inc. All rights reserved.
4
Storage Classes
• Static storage class
– Variables exist for entire program
• For functions, name exists for entire program
– May not be accessible, scope rules still apply (more later)
• static keyword
– Local variables defined with static in a function are only
known in the function
– Keeps value between function calls (unlike automatic
variables)
– Only known in own function
• extern keyword
– Default for global variables/functions
• Global variables: defined outside of a function block
• Retain their values throughout the program execution
– Known in any function that comes after it
 2003 Prentice Hall, Inc. All rights reserved.
5
Scope Rules
• Scope
– Portion of program where identifier can be used
– e.g., a local variable defined in a block can only be
used/referenced in that block
• File scope
– Defined outside a function, known in all functions
– e.g., global variables, function definitions and
prototypes
• Function scope
– Can only be referenced inside defining function (and
hidden from others)
– Only labels, e.g., identifiers with a colon (case:)
 2003 Prentice Hall, Inc. All rights reserved.
6
Scope Rules
• Block scope
– Begins at declaration, ends at right brace }
• Can only be referenced in this range
– Local variables, function parameters
– static variables still have block scope
• Storage class separate from scope
– Block nesting, inner and outer blocks
• Same identifier name in both blocks is possible
• The identifier in the outer block is hidden until the
inner block terminates
• The inner block sees only the value of its own local
identifier, not the identically named identifier in the
enclosed block
 2003 Prentice Hall, Inc. All rights reserved.
7
Scope Rules
• Function-prototype scope
– Parameter list of prototype
– Names in prototype optional
• Compiler ignores
– In a single prototype, name can be used once
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
8
// Fig. 6.12: fig06_12.cpp
// A scoping example.
#include <iostream>
Outline
using std::cout;
using std::endl;
void useLocal( void );
// function prototype
Declared
outside of function;
void useStaticLocal( void ); // function prototype
global
variable with
file
void useGlobal( void );
// function
prototype
scope.
int x = 1;
int main()
{
int x = 5;
// global variable
Local variable with function
scope.
// local variable to main
cout << "local x in main's outer
scope
is "block,
<< x giving
<< endl;
Create
a new
x
{ // start new scope
block scope. When the block
ends, this x is destroyed.
int x = 7;
cout << "local x in main's inner scope is " << x << endl;
} // end new scope
 2003 Prentice Hall, Inc.
All rights reserved.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
9
cout << "local x in main's outer scope is " << x << endl;
useLocal();
useStaticLocal();
useGlobal();
useLocal();
useStaticLocal();
useGlobal();
//
//
//
//
//
//
Outline
useLocal has local x
useStaticLocal has static local x
useGlobal uses global x
useLocal reinitializes its local x
static local x retains its prior value
global x also retains its value
cout << "\nlocal x in main is " << x << endl;
return 0;
// indicates successful termination
} // end main
 2003 Prentice Hall, Inc.
All rights reserved.
43
44
45
46
47
48
49
50
51
52
53
54
55
// useLocal reinitializes local variable x during each call
void useLocal( void )
{
int x = 25; // initialized each time useLocal is called
cout <<
<<
++x;
cout <<
<<
10
Outline
variable (local
endl << "local x is Automatic
" << x
variable
function). This
" on entering useLocal"
<< of
endl;
is
destroyed when the function
"local x is " << x exits, and reinitialized when
" on exiting useLocal"
<< endl;begins.
the function
} // end function useLocal
 2003 Prentice Hall, Inc.
All rights reserved.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// useStaticLocal initializes static local variable x only the
// first time the function is called; value of x is saved
// between calls to this function
void useStaticLocal( void )
{
// initialized only first time useStaticLocal is called
static int x = 50;
cout <<
<<
++x;
cout <<
<<
11
Outline
endl << "local static x is " << x
" on entering useStaticLocal" << endl;
"local static x is " << xStatic local variable of
function;
it is initialized
" on exiting useStaticLocal"
<< endl;
} // end function useStaticLocal
only
once, and retains its value
between function calls.
71
 2003 Prentice Hall, Inc.
All rights reserved.
72
73
74
75
76
77
78
79
80
81
// useGlobal modifies global variable x during each call
void useGlobal( void )
{
cout << endl << "global x is " << x
This function does not declare
<< " on entering useGlobal" << endl;
any variables. It uses the
x *= 10;
global x declared in the
cout << "global x is " << x
beginning of the program.
<< " on exiting useGlobal" << endl;
12
Outline
} // end function useGlobal
local x in main's outer scope is 5
local x in main's inner scope is 7
local x in main's outer scope is 5
local x is 25 on entering useLocal
local x is 26 on exiting useLocal
local static x is 50 on entering useStaticLocal
local static x is 51 on exiting useStaticLocal
global x is 1 on entering useGlobal
global x is 10 on exiting useGlobal
 2003 Prentice Hall, Inc.
All rights reserved.
13
local x is 25 on entering useLocal
local x is 26 on exiting useLocal
Outline
local static x is 51 on entering useStaticLocal
local static x is 52 on exiting useStaticLocal
global x is 10 on entering useGlobal
global x is 100 on exiting useGlobal
local x in main is 5
 2003 Prentice Hall, Inc.
All rights reserved.
14
Functions with Empty Parameter Lists
• Empty parameter lists
– void or leave parameter list empty
– Indicates function takes no arguments
– Function print takes no arguments and returns no
value
• void print();
• void print( void );
– It is a compilation error to pass arguments to a
function with empty parameter list; also, it is a
compilation error for a void function to have a
return.
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Fig. 6.17: fig06_17.cpp
// Functions that take no arguments.
#include <iostream>
15
Outline
using std::cout;
using std::endl;
void function1();
void function2( void );
// function prototype
// function prototype
int main()
{
function1();
function2();
// call function1 with no arguments
// call function2 with no arguments
return 0;
// indicates successful termination
} // end main
 2003 Prentice Hall, Inc.
All rights reserved.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// function1 uses an empty parameter list to specify that
// the function receives no arguments
void function1()
{
cout << "function1 takes no arguments" << endl;
16
Outline
} // end function1
// function2 uses a void parameter list to specify that
// the function receives no arguments
void function2( void )
{
cout << "function2 also takes no arguments" << endl;
} // end function2
function1 takes no arguments
function2 also takes no arguments
 2003 Prentice Hall, Inc.
All rights reserved.
17
Inline Functions
• Inline functions
– Keyword inline before function
– Asks the compiler to copy code into program instead
of making function call
• Reduce function-call overhead
• Compiler can ignore inline
– Good for small, often-used functions
– Typically, inline functions are placed in header files
• Example
inline double cube( const double s )
{ return s * s * s; }
– const tells compiler that function does not modify s
• Discussed later!
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Fig. 6.18: fig06_18.cpp
// Using an inline function to calculate.
// the volume of a cube.
#include <iostream>
18
Outline
using std::cout;
using std::cin;
using std::endl;
// Definition of inline function cube. Definition of function
// appears before function is called, so a function prototype
// is not required. First line of function definition acts as
// the prototype.
inline double cube( const double side )
{
return side * side * side; // calculate cube
} // end function cube
 2003 Prentice Hall, Inc.
All rights reserved.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main()
{
cout << "Enter the side length of your cube: ";
19
Outline
double sideValue;
cin >> sideValue;
// calculate cube of sideValue and display result
cout << "Volume of cube with side "
<< sideValue << " is " << cube( sideValue ) << endl;
return 0;
// indicates successful termination
} // end main
Enter the side length of your cube: 3.5
Volume of cube with side 3.5 is 42.875
 2003 Prentice Hall, Inc.
All rights reserved.
20
References and Reference Parameters
• Call by value
– Copy of data passed to the called function
– Changes made to the copy do not affect original
– Prevent unwanted side effects
• Call by reference
– Called function can directly access data
– Changes in called function affect original
 2003 Prentice Hall, Inc. All rights reserved.
21
References and Reference Parameters
• Reference parameter
– Alias for argument in function call
• Passes parameter by reference
– Use & after data type in prototype
• void myFunction( int &data )
• Read “data is a reference to an int”
– Function call format the same (i.e., mention variable
by name to pass it by reference)
• However, original can now be changed
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Fig. 6.19: fig06_19.cpp
// Comparing pass-by-value and pass-by-reference
// with references.
#include <iostream>
using std::cout;
using std::endl;
int squareByValue( int );
void squareByReference( int & );
22
Outline
Notice the & operator,
indicating pass-by-reference.
// function prototype
// function prototype
int main()
{
int x = 2;
int z = 4;
// demonstrate squareByValue
cout << "x = " << x << " before squareByValue\n";
cout << "Value returned by squareByValue: "
<< squareByValue( x ) << endl;
cout << "x = " << x << " after squareByValue\n" << endl;
 2003 Prentice Hall, Inc.
All rights reserved.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// demonstrate squareByReference
cout << "z = " << z << " before squareByReference" << endl;
squareByReference( z );
cout << "z = " << z << " after squareByReference" << endl;
23
Outline
return 0; // indicates successful termination
} // end main
Changes number, but
original parameter (x) is not
squareByValue multiplies number by itself, stores the
modified.
result in number and returns the new value
of number
//
//
int squareByValue( int number )
{
return number *= number; // caller's argument not modified
} // end function squareByValue
Changes numberRef, an
// squareByReference multiplies numberRef by itself and
alias for the original
// stores the result in the variable to which numberRef
parameter. Thus, z is
// refers in function main
changed.
void squareByReference( int &numberRef )
{
numberRef *= numberRef;
// caller's argument modified
} // end function squareByReference
 2003 Prentice Hall, Inc.
All rights reserved.
x = 2 before squareByValue
Value returned by squareByValue: 4
x = 2 after squareByValue
24
Outline
z = 4 before squareByReference
z = 16 after squareByReference
 2003 Prentice Hall, Inc.
All rights reserved.
25
References and Reference Parameters
• Pointers (chapter 8)
– Another way to pass-by-reference
• References as aliases (other names) to
other variables
– Refer to same variable
– Can be used within a function
int count = 1; // declare integer variable count
int &cRef = count; // create cRef as an alias for count
++cRef; // increment count (using its alias)
• References must be initialized when
declared
– Otherwise, compiler error
– Reference to undefined variable
 2003 Prentice Hall, Inc. All rights reserved.
// Fig. 6.20: fig06_20.cpp
// References must be initialized.
#include <iostream>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
x
y
x
y
26
Outline
using std::cout;
using std::endl;
int main()
{
int x = 3;
y declared as a reference to x.
// y refers to (is an alias for) x
int &y = x;
cout << "x = " << x << endl << "y = " << y << endl;
y = 7;
cout << "x = " << x << endl << "y = " << y << endl;
return 0;
// indicates successful termination
} // end main
=
=
=
=
3
3
7
7
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Fig. 6.21: fig06_21.cpp
// References must be initialized.
#include <iostream>
27
Outline
using std::cout;
using std::endl;
int main()
{
int x = 3;
int &y;
Un-initialized reference –
compiler error.
// Error: y must be initialized
cout << "x = " << x << endl << "y = " << y << endl;
y = 7;
cout << "x = " << x << endl << "y = " << y << endl;
return 0;
// indicates successful termination
} // end main
Borland C++ command-line compiler error message:
Error E2304 Fig06_21.cpp 11: Reference variable 'y' must be
initialized in function main()
Microsoft Visual C++ compiler error message:
C:\My_examples\ch06\Fig06_21.cpp(11) : error C2530: 'y' :
references must be initialized
 2003 Prentice Hall, Inc.
All rights reserved.
28
Default Arguments
• Function call with omitted parameters
– If not enough parameters, rightmost go to their
defaults
– Default values
• Can be constants, global variables, or function calls
• Set defaults in function prototype
int myFunction( int x = 1, int y = 2, int z = 3 );
– myFunction(3)
• x = 3, y and z get defaults (rightmost)
– myFunction(3, 5)
• x = 3, y = 5 and z gets default
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
29
// Fig. 6.22: fig06_22.cpp
// Using default arguments.
#include <iostream>
using std::cout;
using std::endl;
Outline
Set defaults in function
prototype.
// function prototype that specifies default arguments
int boxVolume( int length = 1, int width = 1, int height = 1 );
int main()
{
// no arguments--use default values for all dimensions
cout << "The default box volume is: " << boxVolume();
// specify length; default width and height
cout << "\n\nThe volume of a box with length 10,\n"
<< "width 1 and height 1 is: " << boxVolume( 10 );
Function calls with some
parameters missing – the
rightmost parameters get their
defaults.
// specify length and width; default height
cout << "\n\nThe volume of a box with length 10,\n"
<< "width 5 and height 1 is: " << boxVolume( 10, 5 );
 2003 Prentice Hall, Inc.
All rights reserved.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// specify all arguments
cout << "\n\nThe volume of a box with length 10,\n"
<< "width 5 and height 2 is: " << boxVolume( 10, 5, 2 )
<< endl;
return 0;
30
Outline
// indicates successful termination
} // end main
// function boxVolume calculates the volume of a box
int boxVolume( int length, int width, int height )
{
return length * width * height;
} // end function boxVolume
The default box volume is: 1
The volume of a box with length 10,
width 1 and height 1 is: 10
The volume of a box with length 10,
width 5 and height 1 is: 50
The volume of a box with length 10,
width 5 and height 2 is: 100
 2003 Prentice Hall, Inc.
All rights reserved.
31
Unary Scope Resolution Operator
• Unary scope resolution operator (::)
– Access global variable if local variable has same
name and global variable needs to be accessed
within the same block where local variable is
defined
– Not needed if names are different
– Use ::variable
• y = ::x + 3;
– Good to avoid using same names for locals and
globals
 2003 Prentice Hall, Inc. All rights reserved.
1
// Fig. 6.23: fig06_23.cpp
2
// Using the unary scope resolution operator.
3
#include <iostream>
4
using std::cout;
5
using std::endl;
6
7
#include <iomanip>
8
9 int number = 7;
10
Access the global
11 int main()
with ::number.
12 {
13
// define local variable named number
14
double number = 10.5;
15
16
// display values of local and global variables
17
cout << " Local double value of number = " << number
18
<< "\nGlobal int value of number = " << :: number << endl;
19
20
return 0; // indicates successful termination
21
22 } // end main
32
Outline
number
Local double value of number = 10.5
Global int value of number = 7
 2003 Prentice Hall, Inc.
All rights reserved.
33
Function Overloading
• Function overloading
– Functions with same name and different parameters
– Should perform similar tasks
• i.e., function to square ints and function to square
floats
int square( int x) {return x * x;}
float square(float x) { return x * x; }
• Overloaded functions distinguished by signature
– Based on name and parameter types (order matters)
– Type-safe linkage
• Compiler ensures that proper overloaded function
called
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
34
// Fig. 6.24: fig06_24.cpp
// Using overloaded functions.
#include <iostream>
using std::cout;
using std::endl;
Outline
Overloaded functions have
the same name, but the
different parameters
distinguish them.
// function square for int values
int square( int x )
{
cout << “Square of integer " << x << “ is ";
return x * x;
} // end int version of function square
// function square for double values
double square( double y )
{
cout << " Square of double " << y << “ is ";
return y * y;
} // end double version of function square
 2003 Prentice Hall, Inc.
All rights reserved.
24
25
26
27
28
29
30
31
32
int main()
{
cout <<
cout <<
cout <<
cout <<
35
Outline
square(7); // call int version
endl;
square(7.5) //The
call
double
version
proper
function
is called
endl;
based upon the argument
(int or double).
return 0; // indicates successful termination
} // end main
The square of integer 7 is 49
The square of double 7.5 is 56.25
 2003 Prentice Hall, Inc.
All rights reserved.
36
Function Templates
• Compact way to make overloaded functions
– Generate separate function for different data
types (instead of repeating the code)
• Format
– Begin with keyword template
– Formal type parameters in brackets <>
• Every type parameter preceded by typename or
class (synonyms)
• Placeholders for built-in types (i.e., int) or userdefined types
• Specify arguments types, return types, declare
variables
– Function definition like normal, except formal types
used
 2003 Prentice Hall, Inc. All rights reserved.