Transcript Chapter 7-8
Functions
1
Example: Power, Square Root and Absolute values of a number
#include <cmath>
…
float num;
float power, squareRoot, absolute;
cout << "Please input a float number: ";
cin >> num;
power = pow ( num , 2 );
cout << "The power is " << power << endl;
if ( num > 0 )
{
squareRoot = sqrt ( num );
cout << "The square root is " << squareRoot << endl;
}
else
cout << num << " is negative. No squre root!" << endl;
absolute = fabs ( num );
cout << "The absolute value is " << absolute << endl;
2
Math Functions in <cmath>
Need to use #include <cmath> or #include <math.h>
float pow ( float base, float exponent );
float sqrt ( float num );
float fabs ( float num );
They are functions!
These are function prototypes!
3
What other functions have you learned?
bool cin.eof();
int string.length();
string string.substr();
smanip setprecision(int n);
smanip setw(int n);
How to define and use your own function?
4
Example: MAX of 2 numbers
#include <iostream>
using namespace std;
int Max ( int num1, int num2 );
int main()
{
int num1, num2, maxResult;
cin >> num1 >> num2;
// function prototype
(function declaration)
// function
maxResult = Max ( num1, num2 );
cout << "The max is " << maxResult << endl;
call
return 0;
}
int Max ( int num1, int num2 )
{
int result;
if ( num1 > num2 )
result = num1;
else
result = num2;
// function heading
function definition
return result;
}
5
Review: Element of a function
Return Data Type
Function Body
Function Name
Parameter List
int Max ( int num1, int num2 )
{
int result;
if ( num1 > num2 )
result = num1;
else
result = num2;
return result;
}
6
Function Prototype
C++ programmer usually place all supporting functions
after the main function.
C++ rule: identifiers must be declared before use!
Place a function prototype before the main function as a
declaration.
Two ways to declare a function:
int max ( int num1, int num2 );
OR
int max ( int, int );
Add a semicolon to the function heading, and you get the function prototype!
7
Function Prototype
Common Practice!
#include <iostream>
using namespace std;
#include <iostream>
using namespace std;
int max ( int num1, int num2 );
int max ( int num1, int num2 )
{
int result;
if ( num1 > num2 )
result = num1;
else
result = num2;
int main()
{
…
maxResult = max ( num1, num2 )
…
}
int max ( int num1, int num2 )
{
int result;
if ( num1 > num2 )
result = num1;
else
result = num2;
return result;
=
return result;
}
int main()
{
…
maxResult = max ( num1, num2 )
…
}
}
8
Review: Two Types of Functions
Void Function
Return data type is void
Don’t need a return statement in the function
Function call format: functionName(parameters);
Value-Return Function
Return data type is some real data type (int, float, string)
Need a return statement to return a value to the caller
function
Function call format: var = functionName(parameters);
OR use functionName(parameters)as a variable.
9
Formal parameters vs. Actual parameters (Arguments)
Formal parameters appears in a function heading.
int max ( int num1, int num2 );
Used in the callee function.
Actually parameters (Arguments) appear in a function call.
result = max ( 2, 3 );
During a function call, an argument can be a literal, variable, or
expression.
result = pow( 3, 2 );
result = fabs ( num );
result = sqrt ( num / 2 + 1 );
A function is not required to have arguments.
eof();
Used in the caller function.
10
Void Function
#include <iostream>
#include <string>
using namespace std;
const int HEIGHT = 10;
void PrintLine(int height);
int main()
{
int height = HEIGHT;
while ( height > 0 )
{
PrintLine(height);
height --;
}
return 0;
}
Formal parameter: height
Actual parameter: height
They can have the same name!
void PrintLine(int height)
{
string spaceLine = "";
string dollarLine = "";
int count = 0;
while ( count < height - 1 )
{
spaceLine += " ";
count ++;
}
count = 0;
while ( count < 2 * ( HEIGHT - height )
+ 1 )
{
dollarLine += "$";
count ++;
}
cout << spaceLine << dollarLine
<< endl;
}
11
Value-Return Function
Formal parameter: payRate, hour
Actual parameter: rate, hour
They can have different names!
#include <iostream>
using namespace std;
float grossPay(float payRate, float hour);
int main()
{
float hours;
float rate;
float salary;
cout << "Please enter your pay rate “
<< “(per hour): ";
cin >> rate;
cout << "Please enter your working “
<< “hours: ";
cin >> hours;
salary = GrossPay(rate, hours);
cout << "Your salary is " << salary
<< “.” << endl;
float GrossPay(float payRate, float hour)
{
float salary;
if (hour <= 40)
salary = hour * payRate;
else
{
salary = ( hour - 40 ) * payRate *
1.5 + 40 * payRate;
cout << endl << "You have "
<< ( hour - 40 )
<< " hours overtime." << endl;
}
return salary;
}
return 0;
}
12
Function Names
Meaningful names
Names for functions and methods with a return type of void
should generally be verb phrases such as ComputePay() and
PrintOrders().
Names for functions and methods with other return types
should generally be nouns or noun phrases such as
Average() and MonthlySalary().
Capitalize the first letter of each word!
Formal and actual parameters can have the same name
They are different variables in different scopes
Normally they have different names
13
Activation Record
There is one activation record for each function call.
An activation record contains:
Local variables of the function called
Return address
Parameters for the function called
Locals
Return Address
Parameters
Activation Record for GrossPay
int main()
{
float hours;
float rate, salary;
cout << "Please enter your pay rate “
<< “(per hour): ";
cin >> rate;
cout << "Please enter your working “
<< “hours: ";
cin >> hours;
salary = GrossPay(rate, hours);
cout << "Your salary is " << salary
<< “.” << endl;
return 0;
}
hours
rate
Input values:
?
?
salary ?
45
10
475
float GrossPay(float payRate, float hour)
{
float salary;
if (hour <= 40)
salary = hour * payRate;
else
{
salary = ( hour - 40 ) * payRate *
1.5 + 40 * payRate;
cout << endl << "You have "
<< ( hour - 40 )
<< " hours overtime." << endl;
}
return salary;
}
10
45
payRate
10
hour
45
salary
?
475
Scope of Variables
The region of code where it is legal to reference (use)
an identifier.
Local Scope
Global Scope
Class Scope (Later in this semester.)
16
Statement Block
Between a pair of matching braces
e.g. The body of a function
int main()
{
int alpha = 10;
// A block for if statement
if (alpha > 3)
{
int num;
cin >> num;
alpha += num;
}
return 0;
}
17
Local Scope
int main()
{
int alpha = 10;
The scope of an
// A code block
if (alpha > 3)
{
int num;
cin >> num;
alpha += num;
}
cout << "num = “ << num;
// Run time error!
return 0;
identifier declared
inside a block extends
from the point of
declaration to the end
of that block.
}
18
Nested Local Scope
local identifiers have name precedence!
The scope of an identifier does not include any nested block
that contains locally declared identifier of the same name!
int main ()
{
int num = 0;
string name = “Kyle”;
while ( num < 5 )
{
string name = “Alice”;
cout << name << num << endl;
num ++;
}
cout << endl << name;
return 0;
}
What is the output?
Alice0
Alice1
Alice2
Alice3
Alice4
Kyle
19
Global Scope
The scope of an identifier declared outside all
functions (and classes) extends from the point of
declaration to the end of the entire source file.
Programming Rules:
No global variables!
20
Scope of a Function Name
A function name has global scope.
Function definitions cannot be nested within function
definitions!
int main ()
{
int num = 0;
string name = “Kyle”;
while ( num < 5 )
{
void PrintAlice ( int count )
{
string name = “Alice”;
cout << name << count << endl;
}
num ++;
}
cout << endl << name;
return 0;
}
// Can we do that?
// NO!
21
Scope of Function Parameters
Formal parameters
Local scope
Same as local variable
Cannot reference it outside the function
Receive values on function call
Actual parameters (no global variables)
Local scope
Cannot reference it inside the called function
22
Example: GrossPay
#include <iostream>
using namespace std;
formal parameters
float GrossPay(float payRate, float hour);
int main()
{
int hour;
float rate;
float salary;
scope
cout << "Please enter your pay rate “
<< “(per hour): ";
cin >> rate;
cout << "Please enter your working “
<< “hours: ";
cin >> hour;
actual parameters
salary = GrossPay(rate, hour);
cout << "Your salary is " << salary
<< “.” << endl;
float GrossPay(float payRate, float hour)
{
float salary;
if (hour <= 40)
salary = hour * payRate;
else
{
salary = ( hour - 40 ) * payRate *
1.5 + 40 * payRate;
cout << endl << "You have "
<< ( hour - 40 )
<< " hours overtime." << endl;
}
return salary;
}
scope
return 0;
}
23
Example: Using a flag
float DoIt(int num, char op);
int main()
{
int base;
float result;
char choice;
cout << “Enter a number: ”;
cin >> base;
cout << “C for Cube and S for Square Root: ”;
cin >> choice;
// ---------------------------// Precondition: op is ‘C’ or ‘S’
// Postcondition: the cube of
// num is computed when op is
// ‘C’, and square root of num
// is computed when op is ‘S’.
// parameters: in, in
// -----------------------------float DoIt(int num, char op)
{
if (op == ‘C’)
result = pow(num, 3);
else
result = sqrt(num);
while (choice != ‘C’ && choice != ‘S’)
{
cout << “C for Cube and S for Square Root: ”;
cin >> choice;
}
result = DoIt(base, choice);
return result;
}
cout << “The result: ” << result;
return 0;
}
// What is wrong?
// Result not declared in the
// function!
24
Example: Using a flag
int DoIt(int num, char op);
int main()
{
int base;
float result;
char choice;
cout << “Enter a number: ”;
cin >> base;
cout << “C for Cube and S for Square: ”;
cin >> choice;
while (choice != ‘C’ && choice != ‘S’)
{
cout << “C for Cube and S for Square: ”;
cin >> choice;
}
result = DoIt(base, choice);
cout << “The result: ” << result;
return 0;
}
// -----------------------------// Precondition: op is ‘C’ or ‘S’
// Postcondition: the cube of
// num is computed when op is
// ‘C’, and square root of num
// is computed when op is ‘S’.
// parameters: in, in
// -----------------------------float DoIt(int num, char op)
{
float result;
if (op == ‘C’)
result = pow(num, 3);
else
result = sqrt(num);
return result;
}
// The two variables
// result have the same
// name, but different!
25
Programming Ground Rules
All functions, including the main function, should be no more than 30
lines long, from the left brace to the right brace, inclusive.
Every function and method, except the main function, must have a
comment which describes
what it does and
whether the parameters are input, output, or input and output.
Be sure to document the purpose of any parameter which isn't obvious
from its name alone.
Thus function and method headers must have the following format:
//--------------------------------------------------------// A few lines describing what the function or method does.
// params: (in/out/inout, ...)
//--------------------------------------------------------result_type function_name(type1 param1, type2 param2, ...)
26
Function Parameters
IN parameters:
The value of the actual parameter is passed into the
function and assigned to the formal parameter.
OUT parameters:
The value of formal parameter is passed out of the
function and assigned to the actual parameter.
InOut
Both In and Out.
27
Example: IN Parameter
#include <iostream>
using namespace std;
float GrossPay(float payRate, float hour);
int main()
{
int hour;
float rate;
float salary;
cout << "Please enter your pay rate “
<< “(per hour): ";
cin >> rate;
cout << "Please enter your working “
<< “hours: ";
cin >> hour;
salary = GrossPay(rate, hour);
cout << "Your salary is " << salary
<< “.” << endl;
The value of rate and hour
in the main function
is passed to payRate and hour
in the grossPay function.
Can we write a function
to input rate and hour?
How to pass the values back to
the main function?
return 0;
}
28
Example: OUT Parameter
float GrossPay(float payRate, float hour);
void GetInput(float& payRate, float& hoursWorked);
int main()
{
float hour, rate, gross;
// Call function getInput() to get two values
GetInput(rate, hour);
// Call function grossPay to get one value
gross = GrossPay(rate, hour);
// display result
cout << "Your salary is " << gross << endl;
return 0;
}
29
Function definition of GetInput
//
//
//
//
//
------------------------------------------------The function inputs payRate and hoursWorked and
pass both values back to the calling function.
Parameters: (out, out)
-------------------------------------------------
void GetInput(float& payRate, float& hoursWorked)
{
cout << "Enter pay rate: ";
cin >> payRate;
cout << "Enter hours: ";
cin >> hoursWorked;
}
//
//
//
//
return; // in void functions, using return is optional.
The function does input with prompt, but OUT parameters!
How can it pass two values back?
Out Parameters: &
Statement return can pass only one value back!
30
Function definition of GrossPay
// ------------------------------------------------// The function computes and returns the gross pay
//
based on the pay rate and hours. Hours over
//
40 will be paid 1.5 times the regular pay rate.
// Parameters: (in, in)
// ------------------------------------------------float GrossPay(float payRate, float hour)
{
if (hour > REG_HOURS)
payRate = (hour - REG_HOURS) * OVER_TIME * payRate +
REG_HOURS * payRate;
else
payRate = hour * payRate;
return payRate;
}
// No local variable
// payRate is used to store the result
31
Reference and Value Parameters
float GrossPay(float payRate, float hour);
void GetInput(float& payRate, float& hoursWorked);
Value parameter: No & DataType identifier, …
The value of actual parameter is passed to the formal parameter
Reference Parameter: With & DataType& identifier, …
The address of actual parameter is passed to the formal parameter
Does the actual parameter change its value when the corresponding
formal parameter changes its value?
Value parameter (no &): NO
Reference parameter (&): YES
32
Reference and Value Parameters
Function call using value parameters:
gross = GrossPay(rate, hour); float
main
Memory
rate
22.5
hour
50
GrossPay(float payRate, float hour);
GrossPay
payRate
22.5
hour
50
Function call using reference parameters:
GetInput(rate, hour);
Memory
7000 main
rate
22.5
7004
50
hour
void GetInput(float& payRate, float& hoursWorked);
GetInput
70
&payRate
00
70
&hoursWorked
04
33
Trace Functions with OUT parameters
Input: 10
45
GetInput(rate, hour);
// Reference parameters
gross = GrossPay(rate, hour);// Value parameters
main()
rate
?
hour
?
?
gross
GetInput()
10
45
450
GrossPay()
payRate
&rate
payRate
10
hoursWorked
&hour
hour
45
salary
?
450
34
Example: InOut Parameter
int main()
{
float score, highest, lowest;
int scoreCount = 0;
cin >> score;
while (!cin.eof())
{
if (scoreCount == 0)
{
highest = score;
lowest = score;
}
else
{
if (score > highest)
highest = score;
if (score < lowest)
lowest = score;
}
scoreCount ++;
cin >> score;
}
cout << “Highest: “ << highest << “\nLowest: “ << lowest;
return 0;
}
// Task: Use a function to update highest and lowest.
35
Example: InOut Parameter
void UpdateMaxMin ( float, float&, float& );
int main()
{
float score, highest, lowest;
int scoreCount = 0;
cin >> score;
while (!cin.eof())
{
if (scoreCount == 0)
{
highest = score;
lowest = score;
}
else
UpdateMaxMin ( score, highest, lowest );
scoreCount ++;
//
//
//
//
//
//
-------------------------------The function uses the value of
num to update the
values of max and min.
Parameters: ( In, InOut, InOut )
--------------------------------
void UpdateMaxMin( float num,
float& max,
float& min )
{
if (num > max)
max = num;
}
if (num < min)
min = num;
cin >> score;
}
cout << "Highest: " << highest
<< "\nLowest: " << lowest;
return 0;
}
36
Example: InOut Parameter
Function call:
UpdateMaxMin ( score, highest, lowest );
Function Definition:
void UpdateMaxMin( float num, float& max, float& min )
main
Memory
updateMaxMin
score
20
num
highest
20
10
max
&highest
lowest
2
min
&lowest
37
Trace Functions with InOut parameters
Input: 45
40
50
updateMaxMin ( score, highest, lowest );
//Function call
void updateMaxMin( float num, float& max, float& min ) //Function definition
38
Value Parameter and Reference Parameter
What can the actual parameter be for a value parameter?
A VALUE!
Literal value
Variable
Expression
(magic number)
(initialized!)
(with all variables initialized)
What can the actual parameter be for a reference parameter?
AN ADDRESS!
Literal value:
Expression:
Variable:
NO
NO
YES
initialized or uninitialized
39
Actual Parameter
Does the actual parameter change its value when
the corresponding formal parameter changes its
value?
Value Parameter
NO!
Reference Parameter
YES!
40
Function Calls
Main function can call another function A
A function can also call another function B
main
A
B
Caller
Callee
Caller
Callee
41
Decompose the program by functions
Modularity
Any function or method (including the main function) can
have at most 30 lines.
A function should implement ONE basic functionality.
Functions and methods which focus on computation should not
produce output using cout statements.
Check:
Can I replace the loop body with a function?
Can I use a function to get valid input?
Can I use a function to do some particular computation?
Is there any activity that is repeated multiple times in the
program?
42
Design Function Interface
What parameters should be passed?
How? In, Out, or InOut?
In: pass by value. Recommended!
Out: pass by reference.
InOut: pass by reference.
If possible, try to avoid passing reference parameters!
Because it might cause unexpected values changes of the
caller’s variables.
43
Example: Bad Functions
float GetRate(float rate)
{
cout << “Enter the rate: ”;
cin >> rate;
return rate;
}
// Bad: Why use parameter?
float GetRate()
{
float rate;
cout << “Enter the rate: ”;
cin >> rate;
return rate;
}
// Good: Use local variable!
float GrossPay(float rate, float hour)
{
float pay = rate * hour;
cout << “The pay is “ << pay;
return pay;
}
// Bad: No output in calculation
functions!
void Power ( int& base, int& exponent,
int& result )
{
result = 1;
while ( exponent > 0 )
{
result = result * base;
exponent --;
}
}
// Bad: No need to use reference
parameter!
44
Example: Print a chess board
Pseudo Code:
while height is not 8 yet
if line# is odd, then print an odd row
otherwise, print an even row
Print an odd row:
while cell height is not enough
while cell width is not enough
if cell# is odd
print N spaces
otherwise, print N ‘@’
Do we need two print row functions?
Use a flag to indicate odd or even row!
Print an even row:
while cell height is not enough
while cell width is not enough
if cell# is odd
print N ‘@’
otherwise, print N spaces
45
Example: Print a chess board
Pseudo Code:
while height is not 8 yet
if row# is odd, then print an odd row
otherwise, print an even row
The function printRow is too long!
Print a row:
while cell height is not enough
while cell width is not enough
if cell# is odd
print N spaces if row# is even, or
print N ‘@’ if row# is odd
otherwise,
print N ‘@’ if row# is even, or
print N spaces if row# is odd
replace the circled code with function printLine!
Further pass the flag to printLine.
46
Example: Print a chess board
const
const
const
const
const
int BOARD_WIDTH = 8;
int CELL_WIDTH = 10;
int CELL_HEIGHT = 4;
char FILL = '@';
char EMPTY = ' ';
int main()
{
int count = 0;
while ( count < BOARD_WIDTH )
{
printRow ( count );
count ++;
}
return 0;
}
void printRow ( int rowNum )
{
int countHeight = 0;
while ( countHeight < CELL_HEIGHT )
{
printLine ( rowNum );
countHeight ++;
}
}
void printLine ( int rowNum)
{
int countWidth = 0;
int countCell = 0;
while ( countWidth < BOARD_WIDTH )
{
countCell = 0;
if ( countWidth % 2 == 0 )
while ( countCell < CELL_WIDTH )
{
if ( rowNum % 2 == 0)
cout << EMPTY;
else
cout << FILL;
countCell ++;
}
else
while ( countCell < CELL_WIDTH )
{
if ( rowNum % 2 == 0)
cout << FILL;
else
cout << EMPTY;
countCell ++;
}
Can it be further
countWidth ++;
decomposed?
}
cout << endl;
47
}
Summary
Function definition
Function prototype
Void functions vs. value-return functions
Formal parameters vs. actual parameters
Scope of variables
Scope of function parameters
Scope of function names
Parameter passing: In, Out and InOut
Value parameters vs. reference parameters
Program decomposition
48
More about getting input
cin.get()
cin.ignore()
getline(cin, string)
49
cin.get(char&)
the >> operator skips any leading whitespace or new
line in the input stream.
What if we want to read the whitespace?
char ch1, ch2, ch3;
//Input: a b c
cin >> ch1 >> ch2 >> ch3;
//OR
cin.get(ch1);
cin.get(ch2);
cin.get(ch3);
//ch1 = ‘a’, ch2 = ‘b’, ch3=‘c’
//ch1 = ‘a’, ch2 = ‘ ’, ch3=‘c’
50
cin.ignore()
cin.ignore(200, ‘\n’):
skip the next 200 input characters OR
skip characters until a newline character is read
whichever comes first!
string str;
cin.ignore(20, '\n');
cin >> str;
cout << endl << str;
If the input is “This is a test to see which string will be input.”,
what do you think is the input?
51
getline(cin, string)
How to read a complete line of input?
getline(cin, string) will read everything until it reaches
a newline character.
52