C++ Function
C++ Function
3 Introduction
• Programs written by
– combining new functions with “prepackaged” functions in
the C++ standard library.
– new classes with “prepackaged” classes.
• The standard library provides a rich collection of
functions.
• Functions are invoked by a function call
– A function call specifies the function name and provides
information (as arguments) that the called function needs
– Boss to worker analogy:
A boss (the calling function or caller) asks a worker (the
called function) to perform a task and return (i.e., report back)
the results when the task is done.
3.2 Program Components in C++
• Function definitions
– Only written once
– These statements are hidden from other functions.
– Boss to worker analogy:
The boss does not know how the worker gets the job done; he
just wants it done
3.3 Math Library Functions
• Math library functions
– Allow the programmer to perform common mathematical
calculations
– Are used by including the header file <cmath>
• Functions called by writing
functionName (argument)
• Example
cout << sqrt( 900.0 );
– Calls the sqrt (square root) function. The preceding
statement would print 30
– The sqrt function takes an argument of type double and
returns a result of type double, as do all functions in the
math library
3.3 Math Library Functions
• Functions
– Allow the programmer to modularize a program
• Local variables
– Known only in the function in which they are defined
– All variables declared in function definitions are local
variables
• Parameters
– Local variables passed when the function is called that
provide the function with outside information
Functions
1 4 9 16 25 36 49 64 81 100
1 // Fig. 3.4: fig03_04.cpp
3 #include <iostream>
5 using std::cout;
6 using std::cin;
7 using std::endl;
10
11 int main()
12 {
13 int a, b, c;
14
17
• Scaling
– Reduces random number to a certain range
– Modulus ( % ) operator
• Reduces number between 0 and RAND_MAX to a number
between 0 and the scaling factor
– Example
i = rand() % 6 + 1;
• Generates a number between 1 and 6
1 // Fig. 3.7: fig03_07.cpp
2 // Shifted, scaled integers produced by 1 + rand() % 6
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 #include <iomanip>
9
10 using std::setw;
11
12 #include <cstdlib>
13
14 int main()
Notice rand() % 6 . This returns a number
15 {
between 0 and 5 (scaling). Add 1 to get a
16 for ( int i = 1; i <= 20; i++ ) {
17 cout << setw( 10 ) << ( 1 + rand() % 6 );
number between 1 and 6.
18
19 if ( i % 5 == 0 )
20 cout << endl;
21 }
22
23 return 0; Executing the program again gives the
24 } same "random" dice rolls.
5 5 3 5 5
2 4 2 5 5
5 3 2 2 1
5 1 4 6 4
1 // Fig. 3.9: fig03_09.cpp
2 // Randomizing die-rolling program
3 #include <iostream>
4
5 using std::cout;
6 using std::cin;
7 using std::endl;
8
9 #include <iomanip>
10
11 using std::setw;
12
13 #include <cstdlib>
14
15 int main()
16 {
17 unsigned seed;
18
19 cout << "Enter seed: ";
20 cin >> seed;
21 srand( seed );
22
23 for ( int i = 1; i <= 10; i++ ) {
24 cout << setw( 10 ) << 1 + rand() % 6;
25
26 if ( i % 5 == 0 )
27 cout << endl;
28 }
29
30 return 0;
31 }
Enter seed: 67
1 6 5 1 4
5 6 3 1 2
Enter seed: 67
1 6 5 1 4
5 6 3 1 2
Program Output
3.9 Example: A Game of Chance and
Introducing enum
• Enumeration - set of integers with identifiers
enum typeName {constant1, constant2…};
– Constants start at 0 (default), incremented by 1
– Unique constant names
– Example:
enum Status {CONTINUE, WON, LOST};
• Create an enumeration variable of type typeName
– Variable is constant, its value may not be reassigned
Status enumVar; // create variable
enumVar = WON; // set equal to WON
enumVar = 1; // ERROR
Example: A Game of Chance and
Introducing enum(II)
• Enumeration constants can have values pre-set
enum Months { JAN = 1, FEB, MAR, APR, MAY,
JUN, JUL, AUG, SEP, OCT, NOV, DEC};
– Starts at 1, increments by 1
• Craps simulator rules
– Roll two dice
• 7 or 11 on first throw, player wins
• 2, 3, or 12 on first throw, player loses
• 4, 5, 6, 8, 9, 10
– value becomes player's "point"
– player must roll his point before rolling 7 to win
1 // Fig. 3.10: fig03_10.cpp
2 // Craps
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 #include <cstdlib>
9
10 #include <ctime>
11
12 using std::time;
13
14 int rollDice( void ); // function prototype
15
16 int main()
17 {
18 enum Status { CONTINUE, WON, LOST }; Notice how the
19 int sum, myPoint; enum is defined
20 Status gameStatus;
21
22 srand( time( 0 ) );
23 sum = rollDice(); // first roll of the dice
24
25 switch ( sum ) {
26 case 7:
27 case 11: // win on first roll
28 gameStatus = WON;
29 break;
30 case 2:
31 case 3:
32 case 12: // lose on first roll
33 gameStatus = LOST;
34 break;
35 default: // remember point
36 gameStatus = CONTINUE;
37 myPoint = sum;
38 cout << "Point is " << myPoint << endl;
39 break; // optional
40 }
41
42 while ( gameStatus == CONTINUE ) { // keep rolling
43 sum = rollDice();
44
45 if ( sum == myPoint ) // win by making point
46 gameStatus = WON;
47 else
48 if ( sum == 7 ) // lose by rolling 7
49 gameStatus = LOST;
50 }
51
52 if ( gameStatus == WON )
53 cout << "Player wins" << endl;
54 else
55 cout << "Player loses" << endl;
56
57 return 0;
58 }
59
60 int rollDice( void )
61 {
62 int die1, die2, workSum;
63
64 die1 = 1 + rand() % 6;
65 die2 = 1 + rand() % 6;
66 workSum = die1 + die2;
67 cout << "Player rolled " << die1 << " + " << die2
68 << " = " << workSum << endl;
69
70 return workSum;
71 }
Player rolled 6 + 5 = 11
Player wins
Player rolled 6 + 5 = 11
Player wins
Player rolled 4 + 6 = 10
Point is 10
Player rolled 2 + 4 = 6
Player rolled 6 + 5 = 11
Player rolled 3 + 3 = 6
Player rolled 6 + 4 = 10
Player wins
Player rolled 1 + 3 = 4
Point is 4
Player rolled 1 + 4 = 5
Player rolled 5 + 4 = 9
Player rolled 4 + 6 = 10
Player rolled 6 + 3 = 9
Player rolled 1 + 2 = 3
Player rolled 5 + 2 = 7
Player loses
3.10 Storage Classes
• Storage class specifiers
– Storage class
• Where object exists in memory
– Scope
• Where object is referenced in program
– Linkage
• Where an identifier is known
• Automatic storage
– Object created and destroyed within its block
– auto
• Default for local variables.
• Example:
auto float x, y;
– register
• Tries to put variables into high-speed registers
– Can only be used with local variables and parameters
Storage Classes
• Static storage
– Variables exist for entire program execution
– static
• Local variables defined in functions
• Keep value after function ends
• Only known in their own function
– Extern
• Default for global variables and functions.
• Known in any function
Scope Rules
• File scope
– Defined outside a function, known in all functions
– Examples include, global variables, function definitions and
functions prototypes
• Function scope
– Can only be referenced inside a function body
– Only labels (start:, case:, etc.)
• Block scope
– Declared inside a block. Begins at declaration, ends at }
– Variables, function parameters (local variables of function)
– Outer blocks “hidden” from inner blocks if same variable name
• Function prototype scope
– Identifiers in parameter list
– Names in function prototype optional, and can be used anywhere
1 // Fig. 3.12: fig03_12.cpp
2 // A scoping example
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 void a( void ); // function prototype
9 void b( void ); // function prototype
10 void c( void ); // function prototype
11 x is different inside and outside
12 int x = 1; // global variable
the block.
13
14 int main()
15 {
16 int x = 5; // local variable to main
17
18 cout << "local x in outer scope of main is " << x << endl;
19
20 { // start new scope
21
22
int x = 7;
1. Function prototypes
23 cout << "local x in inner scope of main is " << x << endl;
24 } // end new scope
25
26 cout << "local x in outer scope of main is " << x << endl;
27
28 a(); //
1.1 Initialize global variable
a has automatic local x
29 b(); // b has static locallocal
x x in outer scope of main is 5
30 c(); // c uses global x local x in inner scope of main is 7
31 a(); // a reinitializes automatic local
local x in x scope of main is 5
outer
32 b(); // static local x retains its previous value
33
34
c(); // 1.2 Initialize local variable
global x also retains its value
35 cout << "local x in main is " << x << endl;
36
37 return 0;
38 }
Local automatic variables are
39 created and destroyed each
40 void a( void ) time a is called.
41 {
42 int x = 25; // initialized each time a is called
43
44 cout << endl << "local x in a is " << x
45 << " after entering a" << endl; local x in a is 25 after entering a
46 ++x; local x in a is 26 before exiting a
47 cout << "local x in a is " << x
48 << " before exiting a" << endl;
49 }
50
51 void b( void )
52 { Local static variables are not
53 static int x = 50; // Static initialization only
destroyed when the function
54 // first time b is called.
55
56
cout <<
<<
3.1 Define Functions
endl << "local static x is " << x
" on entering b" << endl;
ends.
global x is 1 on entering c
global x is 10 on exiting c
global x is 10 on entering c
global x is 100 on exiting c
local x in main is 5
References and Reference
Parameters
• Call by value
– Copy of data passed to function
– Changes to copy do not change original
– Used to prevent unwanted side effects
• Call by reference
– Function can directly access data
– Changes affect original
• Reference parameter alias for argument
– & is used to signify a reference
void change( int &variable )
{ variable += 3; }
– Adds 3 to the variable inputted
int y = &x.
– A change to y will now affect x as well
1 // Fig. 3.20: fig03_20.cpp
2 // Comparing call-by-value and call-by-reference
3 // with references.
4 #include <iostream>
5
6 using std::cout;
7 using std::endl;
8
9 int squareByValue( int );
10 void squareByReference( int & );
11
12 int main()
13 {
14 int x = 2, z = 4;
15
16 cout << "x = " << x << " before squareByValue\n"
17 << "Value returned by squareByValue: "
18 << squareByValue( x ) << endl
19 << "x = " << x << " after squareByValue\n" << endl;
20
21 cout << "z = " << z << " before squareByReference" << endl;
22 squareByReference( z );
23 cout << "z = " << z << " after squareByReference" << endl;
24
25 return 0;
26 }
27
28 int squareByValue( int a )
29 {
30 return a *= a; // caller's argument not modified
31 }
32
33 void squareByReference( int &cRef )
34 {
35 cRef *= cRef; // caller's argument modified
36 }
x = 2 before squareByValue
Value returned by squareByValue: 4
x = 2 after squareByValue
z = 4 before squareByReference
z = 16 after squareByReference
3.12 Recursion
• Recursive functions
– Are functions that calls themselves
– Can only solve a base case
– If not base case, the function breaks the problem into a
slightly smaller, slightly simpler, problem that resembles the
original problem and
• Launches a new copy of itself to work on the smaller problem,
slowly converging towards the base case
• Makes a call to itself inside the return statement
– Eventually the base case gets solved and then that value
works its way back up to solve the whole problem
Recursion
• Example: factorial
n! = n * ( n – 1 ) * ( n – 2 ) * … * 1
– Recursive relationship ( n! = n * ( n – 1 )! )
5! = 5 * 4!
4! = 4 * 3!…
– Base case (1! = 0! = 1)
The Fibonacci Series
• Fibonacci series: 0, 1, 1, 2, 3, 5, 8...
– Each number sum of two previous ones
– Example of a recursive formula:
fib(n) = fib(n-1) + fib(n-2)
• C++ code for fibonacci function
return f( 2 ) + f( 1 )
return f( 1 ) + f( 0 ) return 1
return 1 return 0
1 // Fig. 3.15: fig03_15.cpp
2 // Recursive fibonacci function
3 #include <iostream>
4
5 using std::cout;
6 using std::cin;
7 using std::endl;
8
9 unsigned long fibonacci( unsigned long );
10
11 int main()
12 {
13 unsigned long result, number;
14
15 cout << "Enter an integer: ";
16 cin >> number;
17 result = fibonacci( number );
18
19
1. Function prototype
cout << "Fibonacci(" << number << ") = " << result << endl;
return 0;
20 }
21
22 // Recursive definition of function fibonacci
Enter an integer: 5
Fibonacci(5) = 5
Enter an integer: 10
Fibonacci(10) = 55
Enter an integer: 6
Fibonacci(6) = 8
Enter an integer: 20
Fibonacci(20) = 6765
Enter an integer: 30
Fibonacci(30) = 832040
Enter an integer: 35
Program Output
Fibonacci(35) = 9227465
3.14 Recursion vs. Iteration
• Repetition
– Iteration: explicit loop
– Recursion: repeated function calls
• Termination
– Iteration: loop condition fails
– Recursion: base case recognized
• Both can have infinite loops
• Balance between performance (iteration) and good
software engineering (recursion)
Functions with Empty Parameter
Lists
• Empty parameter lists
– Either writing void or leaving a parameter list empty
indicates that the function takes no arguments
void print();
or
void print( void );
– Function print takes no arguments and returns no value
1 // Fig. 3.18: fig03_18.cpp
2 // Functions that take no arguments
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 void function1();
9 void function2( void );
10
11 int main()
12 {
13 function1();
14 function2();
15
16 return 0;
17 }
18
19 void function1()
20 {
21 cout << "function1 takes no arguments" << endl;
22 }
23
24 void function2( void )
25 {
26 cout << "function2 also takes no arguments" << endl;
27 }
• inline functions
– Reduce function-call overhead
– Asks the compiler to copy code into program instead of using a
function call
– Compiler can ignore inline
– Should be used with small, often-used functions
• Example:
inline double cube( const double s )
{ return s * s * s; }
3.18 Default Arguments
Program Output
3.19 Unary Scope Resolution Operator
• Function overloading
– Having functions with same name and different parameters
– Should perform similar tasks ( i.e., a function to square
ints, and function to square floats).
int square( int x) {return x * x;}
float square(float x) { return x * x; }
– Program chooses function by signature
• signature determined by function name and parameter types
– Can have the same return types
1 // Fig. 3.25: fig03_25.cpp
2 // Using overloaded functions
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 int square( int x ) { return x * x; }
9
10 double square( double y ) { return y * y; }
11
12 int main()
13 {
14 cout << "The square of integer 7 is " << square( 7 )
15 << "\nThe square of double 7.5 is " << square( 7.5 )
16 << endl;
17
18 return 0;
19 }