CppHTP6e 07 08 - Final
CppHTP6e 07 08 - Final
CppHTP6e 07 08 - Final
7&8
Functions and an Introduction to Recursion
2008 Pearson Education, Inc. All rights reserved.
OBJECTIVES
In this chapter youll learn: To construct programs modularly from functions. To use common math functions available in the C++ Standard Library. To create functions with multiple parameters. The mechanisms for passing information between functions and returning results. How the function call/return mechanism is supported by the function call stack and activation records. To use random number generation to implement game-playing applications. How the visibility of identifiers is limited to specific regions of programs. To write and use recursive functions, i.e., functions that call themselves.
2008 Pearson Education, Inc. All rights reserved.
Introduction Program Components in C++ Math Library Functions Function Definitions with Multiple Parameters Function Prototypes and Argument Coercion C++ Standard Library Header Files
6.7
6.8 6.10 6.11 6.12
References and Reference Parameters Default Arguments Unary Scope Resolution Operator Function Overloading Recursion Example Using Recursion: Fibonacci Series
6.21
6.1 Introduction
Divide and conquer technique
Construct a large program from small, simple pieces (e.g., components)
Functions
Facilitate the design, implementation, operation and maintenance of large programs
10
11
12
Function
ceil( x ) cos( x ) exp( x ) fabs( x )
Description
rounds x to the smallest integer not less than x trigonometric cosine of x (x in radians) exponential function ex absolute value of x
Example
ceil( 9.2 ) is 10.0 ceil( -9.8 ) is -9.0 cos( 0.0 ) is 1.0 exp( 1.0 ) is 2.71828 exp( 2.0 ) is 7.38906 fabs( 5.1 ) is 5.1 fabs( 0.0 ) is 0.0 fabs( -8.76 ) is 8.76 floor( 9.2 ) is 9.0 floor( -9.8 ) is -10.0 fmod( 2.6, 1.2 ) is 0.2 log( 2.718282 ) is 1.0 log( 7.389056 ) is 2.0 log10( 10.0 ) is 1.0 log10( 100.0 ) is 2.0 pow( 2, 7 ) is 128 pow( 9, .5 ) is 3 sin( 0.0 ) is 0 sqrt( 9.0 ) is 3.0 tan( 0.0 ) is 0
rounds x to the largest integer not greater than x remainder of x/y as a floating-point number natural logarithm of x (base e) logarithm of x (base 10) x raised to power y (xy) trigonometric sine of x (x in radians) square root of x (where x is a nonnegative value) trigonometric tangent of x (x in radians)
13
1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 19 20
// Fig. 6.3: GradeBook.h // Definition of class GradeBook that finds the maximum of three grades. // Member functions are defined in GradeBook.cpp #include <string> // program uses C++ standard string class using std::string;
14
Outline
GradeBook.h
// GradeBook class definition class GradeBook { GradeBook( string ); // constructor initializes course name void setCourseName( string ); // function to set the course name string getCourseName(); // function to retrieve the course name void displayMessage(); // display a welcome message void inputGrades(); // input three grades from user void displayGradeReport(); // display a report based on the grades int maximum( int, int, int ); // determine max of 3 values string courseName; // course name for this GradeBook int maximumGrade; // maximum of three grades
(1 of 1)
10 public:
18 private:
1 2 3 4 5 6
// Fig. 6.4: GradeBook.cpp // Member-function definitions for class GradeBook that // determines the maximum of three grades. #include <iostream> using std::cout; using std::cin;
15
Outline
7 using std::endl; 8 9 #include "GradeBook.h" // include definition of class GradeBook 10 11 // constructor initializes courseName with string supplied as argument; 12 // initializes studentMaximum to 0 13 GradeBook::GradeBook( string name ) 14 { 15 16 setCourseName( name ); // validate and store courseName maximumGrade = 0; // this value will be replaced by the maximum grade
GradeBook.cpp
(1 of 3)
17 } // end GradeBook constructor 18 19 // function to set the course name; limits name to 25 or fewer characters 20 void GradeBook::setCourseName( string name ) 21 { 22 23 24 25 26 if ( name.length() <= 25 ) // if name has 25 or fewer characters courseName = name; // store the course name in the object else // if name is longer than 25 characters { // set courseName to first 25 characters of parameter name courseName = name.substr( 0, 25 ); // select first 25 characters
27 cout << "Name \"" << name << "\" exceeds maximum length (25).\n" 28 << "Limiting courseName to first 25 characters.\n" << endl; 29 } // end if...else 30 } // end function setCourseName
16
Outline
36 } // end function getCourseName 37 38 // display a welcome message to the GradeBook user 39 void GradeBook::displayMessage() 40 { 41 42 43 44 // this statement calls getCourseName to get the // name of the course this GradeBook represents cout << "Welcome to the grade book for\n" << getCourseName() << "!\n" << endl;
GradeBook.cpp
(2 of 3)
45 } // end function displayMessage 46 47 // input three grades from user; determine maximum 48 void GradeBook::inputGrades() 49 { 50 int grade1; // first grade entered by user 51 int grade2; // second grade entered by user 52 53 54 55 56 57 int grade3; // third grade entered by user cout << "Enter three integer grades: "; cin >> grade1 >> grade2 >> grade3; // store maximum in member studentMaximum
60 61 // returns the maximum of its three integer parameters 62 int GradeBook::maximum( int x, int y, int z ) 63 { 64 65 66 67 68 69 70 71 72 73 74 76 77 // display a report based on the grades entered by user 78 void GradeBook::displayGradeReport() 79 { 80 81 // output maximum of grades entered cout << "Maximum of grades entered: " << maximumGrade << endl; return maximumValue; 75 } // end function maximum // determine whether z is greater than maximumValue if ( z > maximumValue ) maximumValue = z; // make z the new maximumValue // determine whether y is greater than maximumValue if ( y > maximumValue ) maximumValue = y; // make y the new maximumValue int maximumValue = x; // assume x is the largest to start
17
Outline
maximum member function header Comma-separated parameter list (3 of 3)
GradeBook.cpp
1 2 3 4 5 6 7 8 9 10 11 12
// Fig. 6.5: fig06_05.cpp // Create GradeBook object, input grades and display grade report. #include "GradeBook.h" // include definition of class GradeBook int main() { // create GradeBook object GradeBook myGradeBook( "CS101 C++ Programming" ); myGradeBook.displayMessage(); // display welcome message myGradeBook.inputGrades(); // read grades from user myGradeBook.displayGradeReport(); // display report based on grades
18
Outline
fig06_05.cpp
(1 of 1)
13 return 0; // indicate successful termination 14 } // end main Welcome to the grade book for CS101 C++ Programming! Enter three integer grades: 86 67 75 Maximum of grades entered: 86
Welcome to the grade book for CS101 C++ Programming! Enter three integer grades: 67 86 75 Maximum of grades entered: 86
Welcome to the grade book for CS101 C++ Programming! Enter three integer grades: 67 75 86 Maximum of grades entered: 86
19
Each argument must be consistent with the type of the corresponding parameter
Parameters are also called formal parameters
20
21
22
23
24
25
26
27
28
29
Data types
long double double float unsigned long int long int unsigned int int unsigned short int short int unsigned char char bool (synonymous with unsigned long) (synonymous with long) (synonymous with unsigned) (synonymous with unsigned short) (synonymous with short)
30
31
32
Instruct the compiler on how to interface with library and user-written components Header file names ending in .h
Are old-style header files Superseded by the C++ Standard Library header files
33
Explanation
Contains function prototypes for the C++ standard input and standard output functions, introduced in Chapter 2, and is covered in more detail in Chapter 15, Stream Input/Output. This header file replaces header file <iostream.h>. Contains function prototypes for stream manipulators that format streams of data. This header file is first used in Section 4.9 and is discussed in more detail in Chapter 15, Stream Input/Output. This header file replaces header file <iomanip.h>. Contains function prototypes for math library functions (discussed in Section 6.3). This header file replaces header file <math.h>. Contains function prototypes for conversions of numbers to text, text to numbers, memory allocation, random numbers and various other utility functions. Portions of the header file are covered in Section 6.7; Chapter 11, Operator Overloading; String and Array Objects; Chapter 16, Exception Handling; Chapter 19, Web Programming; Chapter 22, Bits, Characters, C-Strings and structs; and Appendix E, C Legacy Code Topics. This header file replaces header file <stdlib.h>.
<iomanip>
<cmath>
<cstdlib>
34
Explanation
Contains function prototypes and types for manipulating the time and date. This header file replaces header file <time.h>. This header file is used in Section 6.7. These header files contain classes that implement the C++ Standard Library containers. Containers store data during a programs execution. The <vector> header is first introduced in Chapter 7, Arrays and Vectors. We discuss all these header files in Chapter 23, Standard Template Library (STL). Contains function prototypes for functions that test characters for certain properties (such as whether the character is a digit or a punctuation), and function prototypes for functions that can be used to convert lowercase letters to uppercase letters and vice versa. This header file replaces header file <ctype.h>. These topics are discussed in Chapter 8, Pointers and Pointer-Based Strings, and Chapter 22, Bits, Characters, C-Strings and structs. Contains function prototypes for C-style string-processing functions. This header file replaces header file <string.h>. This header file is used in Chapter 11, Operator Overloading; String and Array Objects.
<cstring>
35
Explanation
Contains classes for runtime type identification (determining data types at execution time). This header file is discussed in Section 13.8. These header files contain classes that are used for exception handling (discussed in Chapter 16). Contains classes and functions used by the C++ Standard Library to allocate memory to the C++ Standard Library containers. This header is used in Chapter 16, Exception Handling. Contains function prototypes for functions that perform input from files on disk and output to files on disk (discussed in Chapter 17, File Processing). This header file replaces header file <fstream.h>. Contains the definition of class string from the C++ Standard Library (discussed in Chapter 18). Contains function prototypes for functions that perform input from strings in memory and output to strings in memory (discussed in Chapter 18, Class string and String Stream Processing). Contains classes and functions used by C++ Standard Library algorithms. This header file is used in Chapter 23.
<fstream>
<string> <sstream>
<functional>
36
C++ Standard Library Explanation header file
<iterator> Contains classes for accessing data in the C++ Standard Library containers. This header file is used in Chapter 23, Standard Template Library (STL). Contains functions for manipulating data in C++ Standard Library containers. This header file is used in Chapter 23. Contains macros for adding diagnostics that aid program debugging. This replaces header file <assert.h> from pre-standard C++. This header file is used in Appendix F, Preprocessor. Contains the floating-point size limits of the system. This header file replaces header file <float.h>. Contains the integral size limits of the system. This header file replaces header file <limits.h>. Contains function prototypes for the C-style standard input/output library functions and information used by them. This header file replaces header file <stdio.h>. Contains classes and functions normally used by stream processing to process data in the natural form for different languages (e.g., monetary formats, sorting strings, character presentation, etc.). Contains classes for defining the numerical data type limits on each computer platform. Contains classes and functions that are used by many C++ Standard Library header files.
<algorithm> <cassert>
<locale>
<limits> <utility>
37
38
This is called scaling, 6 is the scaling factor Shifting can move the range to 1 to 6
1 + rand() % 6;
1 2 3 4 5 6 7 8 9
// Fig. 6.8: fig06_08.cpp // Shifted and scaled random integers. #include <iostream> using std::cout; using std::endl;
39
Outline
fig06_08.cpp
#include <iomanip> using std::setw;
(1 of 2)
10 #include <cstdlib> // contains function prototype for rand 11 using std::rand; 12 13 int main() 14 { 15 16 17 18 19 // loop 20 times for ( int counter = 1; counter <= 20; counter++ ) { // pick random number from 1 to 6 and output it cout << setw( 10 ) << ( 1 + rand() % 6 );
20 21 22 23 24 25 26 return 0; // indicates successful termination 27 } // end main 6 5 6 6 6 1 6 2 5 1 2 3 5 5 4 4 6 3 2 1 // if counter is divisible by 5, start a new line of output if ( counter % 5 == 0 ) cout << endl; } // end for
40
Outline
fig06_08.cpp
(2 of 2)
1 2 3 4 5 6 7 8 9
// Fig. 6.9: fig06_09.cpp // Roll a six-sided die 6,000,000 times. #include <iostream> using std::cout; using std::endl; #include <iomanip> using std::setw;
41
Outline
fig06_09.cpp
(1 of 3)
10 #include <cstdlib> // contains function prototype for rand 11 using std::rand; 12 13 int main() 14 { 15 16 17 18 19 20 21 22 23 24 25 26 27 int frequency1 = 0; // count of 1s rolled int frequency2 = 0; // count of 2s rolled int int int int frequency3 frequency4 frequency5 frequency6 = = = = 0; 0; 0; 0; // // // // count count count count of of of of 3s 4s 5s 6s rolled rolled rolled rolled
int face; // stores most recently rolled value // summarize results of 6,000,000 rolls of a die for ( int roll = 1; roll <= 6000000; roll++ ) { face = 1 + rand() % 6; // random number from 1 to 6
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 // determine roll value 1-6 and increment appropriate counter switch ( face ) { case 1: ++frequency1; // increment the 1s counter break; case 2: ++frequency2; // increment the 2s counter break; case 3: ++frequency3; // increment the 3s counter break; case 4: ++frequency4; // increment the 4s counter break; case 5: ++frequency5; // increment the 5s counter break; case 6: ++frequency6; // increment the 6s counter break; default: // invalid value cout << "Program should never get here!"; } // end switch } // end for
42
Outline
fig06_09.cpp
(2 of 3)
54 55 56 57 58 59 60 61 62
cout << "Face" << setw( 13 ) << "Frequency" << endl; // output headers cout << " << "\n << "\n 1" << setw( 13 ) << frequency1 2" << setw( 13 ) << frequency2 3" << setw( 13 ) << frequency3
43
Outline
<< "\n 4" << setw( 13 ) << frequency4 << "\n 5" << setw( 13 ) << frequency5 << "\n 6" << setw( 13 ) << frequency6 << endl; return 0; // indicates successful termination
fig06_09.cpp
(3 of 3)
63 } // end main Face 1 2 3 4 5 6 Frequency 999702 1000823 999378 998898 1000777 1000422
44
45
Randomizing
Conditioning a program to produce a different sequence of random numbers for each execution
1 2 3 4 5 6 7 8 9 10
// Fig. 6.10: fig06_10.cpp // Randomizing die-rolling program. #include <iostream> using std::cout; using std::cin; using std::endl; #include <iomanip> using std::setw;
46
Outline
fig06_10.cpp
(1 of 2)
11 #include <cstdlib> // contains prototypes for functions srand and rand 12 using std::rand; 13 using std::srand; 14 15 int main() 16 { 17 18 19 20 21 22 cout << "Enter seed: "; cin >> seed; srand( seed ); // seed random number generator unsigned seed; // stores the seed entered by the user
23 24 25 26 27 28 29 30 31
// loop 10 times for ( int counter = 1; counter <= 10; counter++ ) { // pick random number from 1 to 6 and output it cout << setw( 10 ) << ( 1 + rand() % 6 ); // if counter is divisible by 5, start a new line of output if ( counter % 5 == 0 ) cout << endl;
47
Outline
fig06_10.cpp
(2 of 2)
32 } // end for 33 34 return 0; // indicates successful termination 35 } // end main Enter seed: 67 6 1
1 6
4 1
6 6
2 4
6 1
3 5
1 4
6 2
Program outputs show that each unique seed value produces a different sequence of random numbers
Enter seed: 67 6 1
1 6
4 1
6 6
2 4
48
49
50
51
Defining an enumeration
Keyword enum A type name Comma-separated list of identifier names enclosed in braces Example enum Months { JAN = 1, FEB, MAR, APR };
52
53
54
55
56
Global variables, function definitions and function prototypes placed outside a function all have file scope
Function scope
Labels (identifiers followed by a colon such as start:) are the only identifiers with function scope
Can be used anywhere in the function in which they appear Cannot be referenced outside the function body Labels are implementation details that functions hide from one another
57
Any block can contain variable declarations Identifiers in an outer block can be hidden when a nested block has a local identifier with the same name Local variables declared static still have block scope, even though they exist from the time the program begins execution
Storage duration does not affect the scope of an identifier
58
59
60
1 2 3 4 5 6 7 8 9 10
// Fig. 6.12: fig06_12.cpp // A scoping example. #include <iostream> using std::cout; using std::endl; void useLocal( void ); // function prototype void useStaticLocal( void ); // function prototype void useGlobal( void ); // function prototype
61
Outline
fig06_12.cpp
(1 of 4)
cout << "local x in main's outer scope is " Local << endl; << x variable { // start new scope int x = 7; // hides x in outer scope
cout << "local x in main's inner scope is " << x << endl; hides local variable } // end new scope cout << "local x in main's outer scope is " << x << endl;
26 27 28 29 30 31 32 33 34 35 37 38 // useLocal reinitializes local variable x during each call 39 void useLocal( void ) 40 { 41 42 43 44 45 cout << "\nlocal x is " << x << " on entering useLocal" << endl; x++; cout << "local x is " << x << " on exiting useLocal" << endl; cout << "\nlocal x in main is " << x << endl; return 0; // indicates successful termination useLocal(); // useLocal has local x useStaticLocal(); // useStaticLocal has static local x useGlobal(); // useGlobal uses global x useLocal(); // useLocal reinitializes its local x useStaticLocal(); // static local x retains its prior value useGlobal(); // global x also retains its value
62
Outline
fig06_12.cpp
(2 of 4)
36 } // end main
Local variable that gets recreated and reinitialized each time useLocal is called
47 48 // useStaticLocal initializes static local variable x only the 49 // first time the function is called; value of x is saved 50 // between calls to this function 51 void useStaticLocal( void ) 52 { 53 54 55 56 57 58 59 61 62 // useGlobal modifies global variable x during each call 63 void useGlobal( void ) 64 { 65 66 67 cout << "\nglobal x is " << x << " on entering useGlobal" << endl; x *= 10; cout << "global x is " << x << " on exiting useGlobal" << endl; cout << "\nlocal static x is " << x << " on entering useStaticLocal" << endl; x++; cout << "local static x is " << x << " on exiting useStaticLocal" << endl; static int x = 50; // initialized first time useStaticLocal is called
63
Outline
(3 of 4)
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 local x is 25 on entering useLocal local x is 26 on exiting useLocal 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
64
Outline
fig06_12.cpp
(4 of 4)
65
Similarly, when a dish is removed from the pile, it is normally removed from the top
Referred to as popping the dish off the stack
66
67
Stack overflow
Error that occurs when more function calls occur than can have their activation records stored on the function call stack (due to memory limitations)
1 2 3 4 5 6 7 8 9
// Fig. 6.13: fig06_13.cpp // square function used to demonstrate the function // call stack and activation records. #include <iostream> using std::cin; using std::cout; using std::endl; int square( int ); // prototype for function square
68
Outline
fig06_13.cpp
(1 of 1)
10 11 int main() 12 { 13 14 15 16 17 18 19 20 21
int a = 10; // value to square (local automatic variable in main) cout << a << " squared: " << square( a ) << endl; // display a squared
return 0; // indicate successful termination } // end main // returns the square of an integer int square( int x ) // x is a local variable {
22 return x * x; // calculate square and return result 23 } // end function square 10 squared: 100
69
Operating system calls main, pushing an activation record onto the stack
Fig. 6.14 | Function call stack after the operating system invokes main to execute the
application.
70
main calls function square, pushing another stack frame onto the function call stack
Fig. 6.15 | Function call stack after main invokes function square to perform the
calculation.
71
Program control returns to main and squares stack frame is popped off
Fig. 6.16 | Function call stack after function square returns to main.
72
specifies that function print does not take arguments and does not return a value
73
1 2 3 4 5 6 7 8
// Fig. 6.17: fig06_17.cpp // Functions that take no arguments. #include <iostream> using std::cout; using std::endl;
74
void function1(); // function that takes no arguments void function2( void ); // function that takes no arguments
9 10 int main() 11 { 12 function1(); // call function1 with no arguments 13 function2(); // call function2 with no arguments 14 return 0; // indicates successful termination 15 } // end main 16 17 // function1 uses an empty parameter list to specify that 18 // the function receives no arguments 19 void function1() 20 { 21 cout << "function1 takes no arguments" << endl; 22 } // end function1
23 24 // function2 uses a void parameter list to specify that 25 // the function receives no arguments 26 void function2( void ) 27 { 28 cout << "function2 also takes no arguments" << endl; 29 } // end function2 function1 takes no arguments function2 also takes no arguments
75
Outline
fig06_17.cpp
(2 of 2)
76
Pass-by-reference
Gives called function the ability to access and modify the callers argument data directly
77
78
Parameter name in the body of the called function actually refers to the original variable in the calling function
79
80
1 2 3 4 5 6 7 8 9
// Fig. 6.19: fig06_19.cpp // Comparing pass-by-value and pass-by-reference with references. #include <iostream> using std::cout; using std::endl;
81
Outline
int squareByValue( int ); // function prototype (value pass) void squareByReference( int & ); // function prototype (reference pass)
(1 of 2)
15 // demonstrate squareByValue 16 cout << "x = " << x << " before squareByValue\n"; 17 cout << "Value returned by squareByValue: " 18 << squareByValue( x ) << endl; 19 cout << "x = " << x << " after squareByValue\n" << endl; Variable is 20 21 // demonstrate squareByReference by name in 22 cout << "z = " << z << " before squareByReference" << endl; 23 squareByReference( z ); 24 cout << "z = " << z << " after squareByReference" << endl; 25 return 0; // indicates successful termination 26 } // end main 27
28 // squareByValue multiplies number by itself, stores the 29 // result in number and returns the new value of number 30 int squareByValue( int number ) 31 { 32 34 35 // squareByReference multiplies numberRef by itself and stores the result 36 // in the variable to which numberRef refers in function main 37 void squareByReference( int &numberRef ) 38 { 39 numberRef *= numberRef; // caller's argument modified 40 } // end function squareByReference x = 2 before squareByValue Value returned by squareByValue: 4 x = 2 after squareByValue z = 4 before squareByReference z = 16 after squareByReference 33 } // end function squareByValue
82
Outline
Receives copy of argument in main
fig06_19.cpp
(2 of 2)
83
Example
int count = 1; int &cRef = count; cRef++; Increments count through alias cRef
2008 Pearson Education, Inc. All rights reserved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Fig. 6.20: fig06_20.cpp // References must be initialized. #include <iostream> using std::cout; using std::endl; int main() {
84
Outline
fig06_20.cpp
int x = 3; int &y = x; // y refers to (is an alias for) x cout << "x = " << x << endl << "y = " << y << endl; y = 7; // actually modifies x cout << "x = " << x << endl << "y = " << y << endl; return 0; // indicates successful termination
(1 of 1)
16 } // end main x y x y = = = = 3 3 7 7
1 2 3 4 5 6 7 8 9 10 11
// Fig. 6.21: fig06_21.cpp // References must be initialized. #include <iostream> using std::cout; using std::endl; int main() {
85
Outline
fig06_21.cpp
Uninitialized reference (1 of 2)
12 cout << "x = " << x << endl << "y = " << y << endl; 13 y = 7; 14 cout << "x = " << x << endl << "y = " << y << endl; 15 return 0; // indicates successful termination 16 } // end main Borland C++ command-line compiler error message: Error E2304 C:\cpphtp6_examples\ch06\Fig06_21\fig06_21.cpp 10: Reference variable 'y' must be initialized in function main() Microsoft Visual C++ compiler error message: C:\cpphtp6_examples\ch06\Fig06_21\fig06_21.cpp(10) : error C2530: 'y' : references must be initialized GNU C++ compiler error message: fig06_21.cpp:10: error: 'y' declared as a reference but not initialized
86
Dangling reference
Returning a reference to an automatic variable That variable no longer exists after the function ends
87
88
89
90
Must be the rightmost argument(s) in a functions parameter list Should be specified with the first occurrence of the function name
Typically the function prototype
91
1 2 3 4 5 6 7 8 9
// Fig. 6.22: fig06_22.cpp // Using default arguments. #include <iostream> using std::cout; using std::endl; // function prototype that specifies default arguments int boxVolume( int length = 1, int width = 1, int height = 1 );
92
Outline
fig06_22.cpp
(1 of 2) Default arguments
10 int main() 11 { 12 // no arguments--use default values for all dimensions 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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 ); // 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 ); // 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; // indicates successful termination
Calling function with no arguments; uses three defaults Calling function with one argument; uses two defaults Calling function with two arguments; uses one default Calling function with three arguments; uses no defaults
2008 Pearson Education, Inc. All rights reserved.
28 } // end main
29 30 // function boxVolume calculates the volume of a box 31 int boxVolume( int length, int width, int height ) 32 { 33 return length * width * height; 34 } // 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
93
Outline
fig06_22.cpp
Note that default arguments were specified in the function (2 of 2) prototype, so they are not specified in the function header
94
95
96
1 2 3 4 5 6
// Fig. 6.23: fig06_23.cpp // Using the unary scope resolution operator. #include <iostream> using std::cout; using std::endl;
97
Outline
7 int number = 7; // global variable named number 8 9 int main() 10 { 11 12 13 14 double number = 10.5; // local variable named number // display values of local and global variables cout << "Local double value of number = " << number
fig06_23.cpp
(1 of 1)
15 << "\nGlobal int value of number = " << ::number << endl; 16 return 0; // indicates successful termination Unary 17 } // end main Local double value of number = 10.5 Global int value of number = 7
98
99
Compiler selects proper function to execute based on number, types and order of arguments in the function call Commonly used to create several functions of the same name that perform similar tasks, but on different data types
100
1 2 3 4 5 6 7 8 9 10 11 13
// Fig. 6.24: fig06_24.cpp // Overloaded functions. #include <iostream> using std::cout; using std::endl;
101
Outline
fig06_24.cpp
// function square for int values int square( int x ) { cout << "square of integer " << x << " is "; return x * x;
(1 of 2)
12 } // end function square with int argument 14 // function square for double values 15 double square( double y ) 16 { 17 18 cout << "square of double " << y << " is "; return y * y;
20 21 int main() 22 { 23 24 25 26 27 cout << square( 7 ); // calls int version cout << endl; cout << square( 7.5 ); // calls double version cout << endl; return 0; // indicates successful termination
102
Outline
fig06_24.cpp
(2 of 2)
Output confirms that the proper function was called in each case
103
1 2 3 4 5 6 7 8 9
// Fig. 6.25: fig06_25.cpp // Name mangling. // function square for int values int square( int x ) { return x * x; } // end function square
104
Outline
fig06_25.cpp
10 // function square for double values 11 double square( double y ) 12 { 13 15 16 // function that receives arguments of types 17 // int, float, char and int & 18 void nothing1( int a, float b, char c, int &d ) 19 { 20 // empty function body 21 } // end function nothing1 return y * y; 14 } // end function square
22 23 // function that receives arguments of types 24 // char, int, float & and double & 25 int nothing2( char a, int b, float &c, double &d ) 26 { 27 29 30 int main() 31 { 32 return 0; // indicates successful termination 33 } // end main @square$qi @square$qd @nothing1$qifcri @nothing2$qcirfrd _main return 0;
105
Outline
fig06_25.cpp
(2 of 2)
106
107
108
6.19 Recursion
Recursive function
A function that calls itself, either directly, or indirectly (through another function)
Recursion
Base case(s)
The simplest case(s), which the function knows how to handle
For all other cases, the function typically divides the problem into two conceptual pieces
A piece that the function knows how to do A piece that it does not know how to do
Slightly simpler or smaller version of the original problem
109
110
111
1 2 3 4 5 6 7 8 9
// Fig. 6.29: fig06_29.cpp // Testing the recursive factorial function. #include <iostream> using std::cout; using std::endl;
112
Outline
fig06_29.cpp
#include <iomanip> using std::setw;
(1 of 2)
10 unsigned long factorial( unsigned long ); // function prototype 11 12 int main() 13 { 14 15 16 17 18 19 return 0; // indicates successful termination 20 } // end main // calculate the factorials of 0 through 10 for ( int counter = 0; counter <= 10; counter++ ) cout << setw( 2 ) << counter << "! = " << factorial( counter ) << endl;
21 22 // recursive definition of function factorial 23 unsigned long factorial( unsigned long number ) 24 { 25 26 27 28 if ( number <= 1 ) // test for base case return 1; // base cases: 0! = 1 and 1! = 1 else // recursion step return number * factorial( number - 1 );
113
Outline
Base cases simply return 1
fig06_29.cpp
(2 of 2)
29 } // end function factorial 0! 1! 2! 3! 4! 5! 6! 7! 8! 9! 10! = = = = = = = = = = = 1 1 2 6 24 120 720 5040 40320 362880 3628800
114
115
1 2 3 4 5 6 7 8 9
// Fig. 6.30: fig06_30.cpp // Testing the recursive fibonacci function. #include <iostream> using std::cout; using std::cin; using std::endl; unsigned long fibonacci( unsigned long ); // function prototype
116
Outline
fig06_30.cpp
(1 of 2)
10 int main() 11 { 12 13 14 15 16 17 18 19 20 21 23 // display higher fibonacci values cout << "fibonacci( 20 ) = " << fibonacci( 20 ) << endl; cout << "fibonacci( 30 ) = " << fibonacci( 30 ) << endl; cout << "fibonacci( 35 ) = " << fibonacci( 35 ) << endl; return 0; // indicates successful termination // calculate the fibonacci values of 0 through 10 for ( int counter = 0; counter <= 10; counter++ ) cout << "fibonacci( " << counter << " ) = " << fibonacci( counter ) << endl;
22 } // end main
24 // recursive method fibonacci 25 unsigned long fibonacci( unsigned long number ) 26 { 27 28 29 if ( ( number == 0 ) || ( number == 1 ) ) // base cases return number; else // recursion step
117
Outline
Base cases
fig06_30.cpp
30 return fibonacci( number - 1 ) + fibonacci( number - 2 ); 31 } // end function fibonacci fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( fibonacci( 0 ) = 0 1 ) = 1 2 ) = 1 3 ) = 2 4 ) = 3 5 ) = 5 6 ) = 8 7 ) = 13 8 ) = 21 9 ) = 34 10 ) = 55 20 ) = 6765 30 ) = 832040 35 ) = 9227465
(2 of 2)
118
119
Exponential complexity
Can humble even the worlds most powerful computers
120
121
122
1 2 3 4 5 6 7 8 9
// Fig. 6.32: fig06_32.cpp // Testing the iterative factorial function. #include <iostream> using std::cout; using std::endl; #include <iomanip> using std::setw;
123
Outline
fig06_32.cpp
(1 of 2)
10 unsigned long factorial( unsigned long ); // function prototype 11 12 int main() 13 { 14 15 // calculate the factorials of 0 through 10 for ( int counter = 0; counter <= 10; counter++ )
16 cout << setw( 2 ) << counter << "! = " << factorial( counter ) 17 << endl; 18 19 return 0; 20 } // end main 21 22 // iterative function factorial 23 unsigned long factorial( unsigned long number ) 24 { 25 unsigned long result = 1;
26 27 28 29 30 31 return result; 32 } // end function factorial 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800 // iterative declaration of function factorial for ( unsigned long i = number; i >= 1; i-- ) result *= i;
124
Outline
Iterative approach to finding a factorial
fig06_32.cpp
(2 of 2)