0% found this document useful (0 votes)
33 views

CS2311 Lec05 Function

This document provides information about a midterm exam for a computer science course and exercises related to loops in C++ programming. It discusses the midterm exam details including date, duration, topics covered, and percentage of final grade. It then presents 3 exercises involving generating matrices using loops, producing matrices with increasing values from the diagonal using loops, and estimating Pi using Monte Carlo simulation and loops. Sample code is provided for each exercise. The goal of the exercises is to practice loop structures in C++.

Uploaded by

Hello HK World
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views

CS2311 Lec05 Function

This document provides information about a midterm exam for a computer science course and exercises related to loops in C++ programming. It discusses the midterm exam details including date, duration, topics covered, and percentage of final grade. It then presents 3 exercises involving generating matrices using loops, producing matrices with increasing values from the diagonal using loops, and estimating Pi using Monte Carlo simulation and loops. Sample code is provided for each exercise. The goal of the exercises is to practice loop structures in C++.

Uploaded by

Hello HK World
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 82

CS2311 Computer Programming

LT05: Function

Computer Science, City University of Hong Kong


Semester A 2022-23
About Midterm
• Week 9 lecture time (24/10 Monday, 15:00)
• In classroom, on paper
• Formal proof needed for request of absence

• One hour
• From Lec 1 (Intro) to Lec 6 (Array)
• 15% of final mark
• Sample questions and announcement will be released this week

2
Exercises: Loop 1
• write a program to generate a matrix of n rows and m column (n and m is
input by the user), where the element at the i-th row and j-th colum is the
multiplication of i and j. Assume n > 1 and m <= 9

• E.g., when n = 4, m = 3, the following matrix is generated


1 11 1 2 2 13 3
1 2 3
2 122 2 4 2 3 6
2 4 6
33 1 3 36 2 6 39 3 9
4 4 3 12
4 1 4 48 2 8 12

3
Exercises: Loop 1
int main() {
int n, m; // n: rows, m: columns
cin >> n >> m;
for (int i=1; i<=n; i++) {
for (int j=1; j<=m; j++) {
// for the element at the i-th row and j-th column
cout << i*j << "\t";
}
cout << endl;
}
return 0;
}
4
Exercises: Loop 2
• write a program to produce a nxn Example 1 Example 2
Enter the number of rows: 5 Enter the number of rows: 8
matrix (n is input by user) with 0's 0 1 2 3 4 0 1 2 3 4 5 6 7
down the main diagonal, 1's in the 1 0 1 2 3 1 0 1 2 3 4 5 6

Ff
2 1 0 1 2 absto Dt 2 1 0 1 2 3 4 5
entries just above and below the 3 2 1 0 1 3 2 1 0 1 2 3 4
main diagonal, 2's above and below 4 3 2 1 0 4 3 2 1 0 1 2 3
54 5 4 3 2 1 0 1 2
that, etc. 6 5 4 3 2 1 0 1
7 6 5 4 3 2 1 0
• hint: consider using nested for-loop, OExample diagonal
1 23456 all
with the outer loop responsible for
Example 3 4
71mg
Enter the number of rows: 0 Enter the number of rows: 3
row and the inner loop for each Please enter positive 0 1 2
integer. 1 0 1
column 2 1 0

5
Exercises: Loop 2
int n;
cout << "Enter the number of rows: ";
cin >> n;
if (n <= 0) {
cout << "Please enter positive integer.\n";
} else {
for (int row=0; row<n; row++) {
for (int col=0; col<n; col++)
cout << abs(col-row) << " ";
cout << endl;
}
}

6
Exercises: Loop 3
• Monte Carlo estimation of Pi T 122 R
area
• circle_area = Pi*R*R/4 square 4
• square_area = CRI
TIR*RCR 4

• Pi = 4*circle_area/square_area R
• How to estimate circle_area/square_area?
Exercises: Loop 3
• Monte Carlo estimation of Pi R
• circle_area = Pi*R*R/4
• square_area = R*R
• Pi = 4*circle_area/square_area R
• How to estimate circle_area/square_area?
• Randomly throw N points to the square
• Let M be the number of points falling to the yellow area
M point in the yellow area
• circle_area/square_area ≈
N
all point in the area
Exercises: Loop 3
// Assume R=1 R
int M=0;
for (int n=0; n<N; n++) {
// Randomly throw a point
number
from
double x = (double)rand()/RAND_MAX;
double y = (double)rand()/RAND_MAX;
R

if (x*x+y*y < 1.0)


Assume 12 1
M++; // Increment M if (x, y) is within the yellow area
if (n!=0 && n%1000==0)
cout << n << " " << 4.0*M/n << endl;
}

9
Exercises: Loop 3
// Assume R=1 R
int M=0, N=10000;
for (int n=0; n<N; n++) { integer
// Randomly throw a point
O 1
double x = (double)rand()/RAND_MAX; to
YedohagYE R frominteger
convert rand
double y = (double)rand()/RAND_MAX;
if (x*x+y*y < 1.0)
if I the pain
is in the blue
M++; // Increment M if (x, y) is within the yellow area area
double est = 4.0*M/n;
cout << n << " " << est << endl;
}

Repeat for 10000 times 10


Exercises: Loop 3 How can we know
• Each round we throw 10000 pts that we have flow enough
• Then observe if the estimated value points
of Pi has changed significantly
• If true, the estimation is not stable If the value of pi
=> continue throwing pts
• If false, the estimation is now has been changing
stable, stop
significantly we have
to flow more point
If value
no
significant
change of pi we can stop
prg
double precision = 1e-7;

Exercises: Loop 3 double prev_est = 0, curr_est;


int M=0, N=0;
while (true) {
• Each round we throw 10000 pts
• Then observe if the estimated value for (int n=0; n<10000; n++) {
of Pi has changed significantly double x = (double)rand()/RAND_MAX;
double y = (double)rand()/RAND_MAX;
• If true, the estimation is not stable if (x*x+y*y < 1.0)
=> continue throwing pts M++;
N++;
• If false, the estimation is now } // end of for
stable, stop curr_est = 4.0*M/N;
cout << curr_est << endl;
if (abs(curr_est-prev_est) < precision)
break;
prev_est = curr_est;
} // end of while
double precision = 1e-7;

Exercises: Loop 3 double prev_est=0, curr_est=0;


int M=0, N=0;
while (true) {
• Each round we throw 10000 pts
prev_est = curr_est;
• Then observe if the estimated value for (int n=0; n<10000; n++) {
of Pi has changed significantly double x = (double)rand()/RAND_MAX;
double y = (double)rand()/RAND_MAX;
• If true, the estimation is not stable if (x*x+y*y < 1.0)
=> continue throwing pts M++;
N++;
• If false, the estimation is now } // end of for
stable, stop curr_est = 4.0*M/N;
} // end of while
cout << curr_est << endl;
if (abs(curr_est-prev_est) < precision)
break;
double precision = 1e-7;

Exercises: Loop 3 double prev_est=0, curr_est=0;


int M=0, N=0;
while (true) {
• Each round we throw 10000 pts
prev_est = curr_est;I update the prerest
• Then observe if the estimated value for (int n=0; n<10000; n++) {
of Pi has changed significantly double x = (double)rand()/RAND_MAX;
double y = (double)rand()/RAND_MAX;
• If true, the estimation is not stable if (x*x+y*y < 1.0)
=> continue throwing pts M++;
N++;
• If false, the estimation is now } // end of for
stable, stop curr_est = 4.0*M/N;
cout << curr_est << endl;
} // end of while
cout << curr_est << endl;
if (abs(curr_est-prev_est) < precision)
break;
double precision = 1e-10;

Exercises: Loop 3 double prev_est=0, curr_est=0;


int M=0, N=0;
while (true) {
• Each round we throw 10000 pts
prev_est = curr_est;
• Then observe if the estimated value for (int n=0; n<10000; n++) {
of Pi has changed significantly double x = (double)rand()/RAND_MAX;
double y = (double)rand()/RAND_MAX;
• If true, the estimation is not stable if (x*x+y*y < 1.0)
=> continue throwing pts M++;
N++;
• If false, the estimation is now } // end of for
stable, stop curr_est = 4.0*M/N;
cout << curr_est << endl;
if (abs(curr_est-prev_est) < precision)
break;
} // end of while
double precision = 1e-10;

Exercises: Loop 3 double prev_est=0, curr_est=0;


int M=0, N=0;
while (true) do {
• Each round we throw 10000 pts
prev_est = curr_est;
• Then observe if the estimated value for (int n=0; n<10000; n++) {
of Pi has changed significantly double x = (double)rand()/RAND_MAX;
double y = (double)rand()/RAND_MAX;
• If true, the estimation is not stable if (x*x+y*y < 1.0)
=> continue throwing pts M++;
N++;
• If false, the estimation is now } // end of for
stable, stop curr_est = 4.0*M/N;
cout << curr_est << endl;
if (abs(curr_est-prev_est) < precision)
break;
} while (abs(curr_est-prev_est)<precision);
What's Function?
• A collection of statements that perform a specific task
• Functions are used to break a problem down into
manageable pieces
• KISS principle: "keep it simple, stupid!"
• Break the problem down into small functions, each
does only one simple task, and does it correctly

• Function allows programmer to focus on a function


interface, hiding details of how it is implemented
• Reuse of code

17
Today's Outline
• Defining a function
• Calling a function
• Declare a function (function prototype)
• Passing parameters
• Recursive functions

18
Defining a Function • return_type: A function may
return some value.
void type function does not returnAxreturn_type is the data type
any value
return_type function_name parameter_list of the value the function
returns. Some functions do not
return any value. In this case,
void printHello (int n) {
the return_type is void.
for (int i=0; i<n; i++)
• function_name: The actual
cout << "Hello\n";
name of the function.
}
• parameter_list: The input
arguments. The parameter list
refers to the type and order of
parameters. A function may
contain no parameters.
19
Defining a Function • return_type: A function may
return some value.
Axreturn_type is the data type
return_type function_name parameter_list of the value the function
returns. Some functions do not
return any value. In this case,
int findMax (int x, int y) {
the return_type is void.
if (x > y)
• function_name: The actual
return x;
name of the function.
else
• parameter_list: The input
return y;
arguments. The parameter list
}
refers to the type and order of
parameters. A function may
contain no parameters.
20
Defining a Function • return statement
Syntax:
return expression;
return_type function_name parameter_list return;
• when a return is encountered,
int findMax (int x, int y) { the program will immediately go
if (x > y) back to the calling function
return x; • if expression exists, its value
will be sent back to the calling
else
function.
return y;
• if necessary, the returning value
}
Th will be type converted to the
type specified in the function
definition
21
Calling a Function
• To make a function call, we only need to specify a function name and
provide argument(s) in a pair of ()
input parameter
void main() { void printHello(int n) {
int x=4; int i;
printHello(x); for (i=0; i<n; i++)
cout << "bye"; cout << "Hello\n";
} }

22
Calling a Function
• when calling a function, no need to specify parameter and return type
• e.g., the following code will cause syntax errors

void main() { void main() { void printHello(int n) {


int x=4; int x=4; int i;
void printHello(x);
cout << "bye";
x printHello(int x);
cout << "bye";
X for (i=0; i<n; i++)
cout << "Hello\n";
} } }
redefined redefined
syntax error
syntax
error 23
Calling a Function (defined in library)
#include <iostream> // tell the compiler that you are going to use functions
// defined in iostream library
using namespace std;
int main() {
float area, side;
cout << "Enter the area of a square: ";
cin >> area;
side = sqrt(area); // pass area to the function sqrt which will return the
// square root of area
cout << "The square has perimeter: " << 4*side;
return 0;
}

24
Function in C++ Library
• The C++ standard library provides a rich collection of functions
• Mathematical calculations (#include <cmath>) 1 for mathematical ca

• String manipulations (#include <cstring>)


y for string manipulation
• Input/output (#include <iostream>) 11 for
input and output
• Some functions are defined in multiple library in some platform
• e.g. function sqrt is defined in both cmath and iostream in VS

25
Flow of Function Call calling called
• During program execution, when a instruction function(…) {
function name followed by parentheses
is encountered, the function is invoked instruction
and the program control is passed to instruction
that function;
instruction
function }

instruction
r return
the
result
26
Flow of Function Call
• During program execution, when a instruction function(…) {
function name followed by parentheses
is encountered, the function is invoked instruction
and the program control is passed to instruction
that function;
instruction
• when the function ends, program control
function }
is returned to the statement immediately
after the function call in the original
function
instruction

27
Flow of Function Call
1. program starts execution
in main()
void main(){ void printHello(int n) {
2. printHello is called Hellofunction
int x=4; to i;print
passint
3. arguments passed to
printHello printHello(x); for (i=0; i<n; i++)
cout << "bye"; cout << "Hello\n";
} }
print hello for n

times

28
Flow of Function Call
1. program starts execution
in main()
void main(){ void printHello(int n) {
2. printHello is called
3. arguments passed to int x=4; int i;
printHello printHello(x); for (i=0; i<n; i++)
4. execute statements in cout << "bye"; cout << "Hello\n";
printHello } }
5. control goes back to
main() and "bye" is
printed

29
Function in Memory Stack Memory Stack
void f1() { int f2(int a, int b) { Higher Address Part
int x = 5; int x = a + b; address
f1 f1:
int y = 6; int y = b – a; 0048: return addr
0044: x
int z = f2(x, y);
fl call a++;
0040: y
cout << a << " " << z;
the return x*y;
0036: z
} function}
f2 f2 f2:
0032: a
Each function has its own memory space which stores 0028: b
0024: return addr
• data (i.e., local variables and parameters) 0020: x
• return address (address of the next instruction in the 0016: y
0012:
calling function)
Lower
Address
Today's Outline
• Defining a function
• Calling a function
• Declare a function (function prototype)
• Passing parameters
• Recursive functions

31
fun cl funez
Function Prototype Pfund L
in this case it wil
• A function should be defined before use cause syntax error
therefore Ctt has
// CORRECT // SYNTAX ERROR to solve this
int findMax(int x, int y) { void main() { find Mat trompe problem

return (x > y) ? x:y;


notdefined
cout << findMax(3, 4); // findMax undefined
}
another wayto }
void main() { write if condition
int findMax(int x, int y) {
cout << findMax(3, 4); return x>y ? x:y;
} }

• Suppose
to callwe ahave 3 functions, where func1 calls func2, func2 calls func3,
function the function must be
and func3 calls func1. In what order should the functions defined before
be defined?
calling it
• C++ allows us to bypass this problem using function prototypes
32
Function Prototype
• A function should be defined before use
// CORRECT // SYNTAX ERROR
int findMax(int x, int y) { void main() {
return (x > y) ? x:y; cout << findMax(3, 4); // findMax undefined
} }
void main() { int findMax(int x, int y) {
cout << findMax(3, 4); return x>y ? x:y;
} }

• Suppose we have 3 functions, where func1 calls func2, func2 calls func3,
and func3 calls func1. In what order should the functions be defined?
• C++ allows us to bypass this problem using function prototypes
33
Function Prototype
• A function should be defined before use
// CORRECT // SYNTAX ERROR
int findMax(int x, int y) { void main() {
return (x > y) ? x:y; cout << findMax(3, 4); // findMax undefined
} }
void main() { int findMax(int x, int y) {
cout << findMax(3, 4); return x>y ? x:y;
} }

• Suppose we have 3 functions, where func1 calls func2, func2 calls func3,
and func3 calls func1. In what order should the functions be defined?
• C++ allows us to bypass this problem using function prototypes
34
Function Prototype
• C++allows us to declare a function and then call the function before
defining it

• The declaration of the function is called function prototype, which


• specifies the function name, parameters and return type
• for example, the following statement declares foo as a function, there is no
input and no return value
void foo (void);

35
Function Prototype
// SYNTAX ERROR
void main() {
cout << findMax(3, 4); // findMax undefined
}

int findMax(int x, int y) {


return x>y ? x:y;
}

36
Function Prototype // CORRECT
int findMax(int, int);
// SYNTAX ERROR
void main() { void main() {
cout << findMax(3, 4); // findMax undefined cout << findMax(3, 4);
} }

int findMax(int x, int y) { int findMax(int x, int y) {


return x>y ? x:y; 11 thisshould return x>y ? x:y;
} be declared }
first before
the main function to prevent syntax
error
• int findMax(int, int) declares findMax as a function name, the return type
is int, and there're two parameters and their types are int

37
Function Prototype // CORRECT
int findMax(int n1, int n2);
// SYNTAX ERROR
void main() { void main() {
cout << findMax(3, 4); // findMax undefined cout << findMax(3, 4);
} }

int findMax(int x, int y) { int findMax(int x, int y) {


return x>y ? x:y; return x>y ? x:y;
} }

• Another way to declare the prototype is: int findMax(int n1, int n2);
• However, the variable names are optional, and you can use different
parameter names in the actual function definition
38
Function Prototype #include <iostream>

• void is used if a function takes no arguments using namespace std;

data
no printDouble(double);returned
• Prototypes allow the compiler to check the void

code more thoroughly


void main() { M this fundi
int x=4; will take
• Arguments passed to function are coerced double
printDouble(x);
where necessary, e.g., printDouble(4) where } the tht type
type
the integer 4 will be promoted as a double will be converted
type void
to double type d)
printDouble(double {
cout << fixed;
cout << d << endl;
}

39
Function Prototype
• In a large program, a function f may be used by many other functions
written in different source files
• where to declare function f?
Where can
we define
void fl void fl
If you
a cpp b app defined
void AC void BD in the
Cpp file
function
3 will be
redefined
and cause syntax error To 40 solve
see fors
ag

Function Prototype
• In a large program, a function f may be used by many other functions
written in different source files
• where to declare function f?
• In C++, function prototype and definition can be stored separately
• Header file (.h):
• With extension .h, e..g, stdio.h, string.h Solution for the problem
• Contain function prototype only in last page Declare void fl
th header file
• To be included in the program that will call the function
t tax
• Implementation file (.cpp)
if n def H
• Contain function implementation (definition) define H
file will be included void fl
pragmaonce 11theheader end if 41
only once
Function Prototype
main.cpp mylib.h Call the header file
int calMin(int, int)
#include "mylib.h"

mylib.cpp
void main() {
int x, y=2, z=3;
x = calMin(y, z);
int calMin(int a, int b) {
if (a>b)
bags
} return b;
Already how calming else
is defined return a; mylib obj
man obj }

Sol Debug using


mylib Cpp
42
time
Today's Outline
• Defining a function
• Calling a function
• Declare a function (function prototype)
• Passing parameters
• Recursive functions

43
Argument vs Parameter
• Parameter: (a.k.a, formal parameter)
• identifier that appears in function declaration

• Argument: (a.k.a, actual parameter)


• expression that appears in a function call Arguement
refer to something
Parameter
void main() { inside
void printHello(int n) {
the
calling
function Actual data
int i;
parameter int x=4; provided to the calledfunction
for (i=0; i<n; i++) printHello(x);
cout << "Hello\n"; cout << "bye";
} }
Arguement

44
Parameter Passing in C++
• There're different ways in which arguments can be passed into the called
function

• Three most common methods


• Pass-by-Value
• Pass-by-Reference
Will be discussed in the later lecture
• Pass-by-Pointer (later)
Advanced part for 52311

45
Pass-by-Value Memory Stack
• the value of argument is copied to parameter
address
f1 f1:
parameter
void f1() { int f2(int a, int b) { 0048: return addr
function
int x = 5; calling arguement
0044: x = 5.
int x = a + b;
0040: y = 6.
int y = 6;
x copied int y = b – a; called
y function
0036: z pass b
int z = f2(x, y); to a b a++;
value
cout << a << " " << z; parameter
return x*y; f2 f2:
0032: a = 5.
}
X 1st Arguement }
a first Parameter 0028: b = 6.
0024: return addr
0020: x
0016: y
0012:

46
Pass-by-Value Memory Stack
• the value of argument is copied to parameter
address
f1 f1:
void f1() { int f2(int a, int b) { 0048: return addr
0044: x = 5.
int x = 5; int x = a + b;
0040: y = 6.
int y = 6; int y = b – a; 0036: z
int z = f2(x, y); a++; .
cout << a << " " << z; return x*y; f2 f2:
} } 0032: a = 6.
0028: b = 6.
0024: return addr
0020: x
• when a++ is executed in f2, only the memory 0016: y
storage of f2 is modified 0012:

47
Pass-by-Value
void func(int y) {
y=4;
}
void main(){
int y=3;
func(y);
cout << y << endl;
}

• y and y are two different variables stored in different places in memory


• y (parameter) is a local variable in func
• y (argument) is a local variable in main Hint To check which
is the calling
function y will
be an argument
in the callingfunction
48
Pass-by-Value
void func(int y) {

}
y=4; // modify y in func(), not the one in main()
Output is
void main(){
int y=3;
func(y);
3
cout << y << endl; // print 3, y remains unchanged
}

• y and y are two different variables stored in different places in memory


• y (parameter) is a local variable in func
• y (argument) is a local variable in main
• => Modifying y in func doesn't affect y
49
Pass-by-Value
void int func(int y) {
y=4; // modify the value of x to 4
return y;
}
void main(){
int y=3;
func(y); y=func();
cout << y << endl; // print 4
}
output is
• How to modify y in func()?
• By assigning the return value of f(y) to y 4
• After function call, y gets a value of 4

50
Pass-by-Value: Exercises X Ist Para
y 2nd Para
• What's the output of the following program?
copy to
void f(int y, int x) {
cout << "x=" << x << endl;
cout << "y=" << y << endl; x 1st Arg 3
}
y 2nd Arg
4
void main(){
int x=3, y=4;
copy

}
f(x, y);
output to
x 4
y 3
51
Pass-by-Value: Exercises
• Finding the max of 3 numbers, i, j, k
void main() {calling function called function
int findMax(int n1, int n2) {
int i,j,k; if (n1>n2)
declaringthevalue
int max; max return n1;
cin >> i >> j >> k; else
return n2;
// find the max of i, j, k
}
max i ___);
___ = findMax(___,
j
___ = findMax(___, ___);
max max k
updating the maxvalue
cout << "max is " << max;
}

52
Pass-by-Value: Exercises
• Finding the max of 3 numbers, i, j, k
void main() { int findMax(int n1, int n2) {
int i,j,k; if (n1>n2)
int max; return n1;
cin >> i >> j >> k; else
return n2;
// find the max of i, j, k
}
max = findMax(i, j);
max = findMax(k, max);

cout << "max is " << max;


}

53
Pass-by-Reference
• Argument address is passed to the parameter
• Argument can be updated inside the function
• Add '&' in front of the parameter that to be pass by reference pass the
address at
To indicate pass by reference
void swap(int &a, int &b) { void main() { the arguement
int tmp = a; int x=1, y=3;
a = b; swap(x, y);
switch the value of x andy
b = tmp; cout << "x:" << x << ", y:" << y << endl;
} }

• More details will be explained in future lecture (pointer)

54
Pass-by-Reference Memory Stack
void f1() { int f2(int &a, int &b) {
int x = 5; int x = a + b; address
f1 f1:
int y = 6; int y = b – a; 0048: return addr
int z = f2(x, y); a++; 0044: x = 5.
cout << a << " " << z; return x*y; 0040: y = 6.
0036: z
} }
f2 f2:
0032: a:0044.
• the address of x (0044) is passed to f2 0028: b:0040.
Output passby value output
0024:
0020:
return addr
x
a 3 b I pass by 0016: y
x I b 3 reference 0012:
a 3 b l
x 3 bit 55
Pass-by-Reference Memory Stack
void f1() { int f2(int &a, int &b) {
int x = 5; int x = a + b; address
f1 f1:
int y = 6; int y = b – a; 0048: return addr
int z = f2(x, y); a++; 0044: x = 6. r increasefr
cout << a << " " << z; return x*y; 0040: y = 6. 5 to 6
0036: z
} }
f2 f2: check
• the address of x (0044) is passed to f2 0032: a:0044. address
0028: b:0040.
• when a++ is executed in f2, the value stored 0024: return addr
in 0044 (i.e., x in f1) is modified 0020: x
0016: y
Pass value arguement can't bemodified
by
0012:

Pass by reference argument can be modified


56
Parameter Passing: Default Parameters
• We can provide some default values for certain parameters
• Example
void f(int a, int b=0) { // parameter b with a default value 0
cout << a << " " << b << endl;
}
void main() {
f(1, 2);
f(3); // you can call f without providing argument for b, in this case,
// the default value 0 will be used for b in f
}

57
Parameter Passing: Default Parameters
• All the default parameters MUST locate at the right side of normal
parameters
• Invalid example
Trong
void f(int a, int b=0, int c) { // invalid definition, default parameter b
// located at left side of normal parameter c
cout << a << " " << b << endl;
} 0
void main() { void flint a int c the b D
f(1, 2);
f(3); correct
}

58
Today's Outline
• Defining a function
• Calling a function
• Declare a function (function prototype)
• Passing parameters
• Recursive functions

59
Recursions
• One basic problem solving technique is to break the task into subtasks

• If a subtask is a smaller version of the original task, you can solve the
original task using a recursive function

• A recursive function is one that invokes itself, either directly or indirectly

60
Example: Factorial
• The factorial of n is defined as
0! = 1
n! = n*(n-1)*… 2*1, for n > 0
• A recurrence relation: (induction)
n! = n*(n-1)!, for n > 0
• e.g.,
3! = 3 * 2
= 3 * 2 * 1!
= 3 * 2 * 1 * 0!
= 3 * 2 * 1 * 1

61
Iterative vs Recursive
Iterative

int factorial(int n) {
int i, fact=1;
for (i=1; i<=n; i++) {
fact = i*fact;
}
return fact;
}

62
Iterative vs Recursive
Iterative Recursive

int factorial(int n) { int factorial(int n) {


int i, fact=1; if (n==0)
for (i=1; i<=n; i++) { return 1;
smallest Problem
0 I
fact = i*fact; return n*factorial(n-1);
} }
n h x Ch l
return fact;
}

63
Example: Vertical Number
• Input: one (non-negative) integer Input Output
12345 1
• Output: integer with one digit per line 2
3
• Example: 4
5
7894 7
8
9
4
4 4

64
Example: Vertical Number
• How to break down a number into separated digits?

void printDigit(int n) { Input Output


do { 7894 4
cout << n%10 << endl;
9
8
Refer to
n/=10;
} while (n>0);
7
Assignment 1
} Part A
Try to use
it to calculate
lucky number
65
Example: Vertical Number
• How to break down a number into separated digits?

void printDigit(int n) { void printDigit2(int n) { Input Output


do { if (n>=10){ 7894 4
9
cout << n%10 << endl; printDigit2(n/10);
8
n/=10; n n 10 } 7
} while (n>0); cout << n%10 << endl;
} }

7894 7894 10 4 7894110 789


7810 010 789 10 78 789 10 9
71 66
Recursive: Entering

67
Recursive: Leaving

68
Guidelines for Recursive Functions
h
• Identify the parameters
• e.g., n in the factorial problem

• Find out a recurrence relation between the current problem and smaller
versions (in terms of smaller parameters) of the current problem
• e.g., factorial(n) = n*factorial(n-1)

• Find out the base cases and their solutions


• e.g., factorial(0) = 1
• Omitting the base case is one of the common mistakes in writing recursive
functions

69
Checkpoints
1. There is no infinite recursion (check exist condition)

2. The break down of the problem works correctly

3. For each of cases that involve recursion, if all recursive calls perform
their actions correctly, then the entire case performs correctly.

70
Checkpoints
Factorial Vertical Number
Exit condition n == 0 n < 10
Problem break factorial(n) = n*factorial(n-1) printDigits(n/10);
down cout << n%10;
e.g.
n=2 --> 2!=2*1! e.g.
n=3 --> 3!=3*2! n=78 --> 7 was printed
n=4 --> 4!=4*3! n=789 --> 7, 8 were printed
n=7894 --> 7, 8, 9 were printed

If all stopping case n! is returned n digits are printed


are correct

71
Efficiency of Recursion
• Generally speaking, non-recursive versions will execute more efficiently
(time/space)
• Overhead involved in entering and exiting blocks is avoided in non-recursive
solutions.
• Also have a number of local variables and temporaries that do not have to
be saved and restored via a stack.
• There are conflicts between
• Machine efficiency and
• Programmer efficiency

72
Another Example: Tower of Hanoi Try this
• 3 towers and n disks
• the smallest disk is on top and the largest is on the bottom
• you need to move all of the disks from the first tower to the second tower
• the third tower can be used to temporarily hold disks
• only one disk can be moved at a time.
• NO larger disk is allowed butter
atop a smaller disk
smallestdisk

largest disk

1st 2nd 73
Another Example: Tower of Hanoi

74
Another Example: Tower of Hanoi
• Decompose the problem

• Base case

75
Another Example: Tower of Hanoi
• Decompose the problem

• Base case

76
Another Example: Tower of Hanoi
• Decompose the problem

• Base case

77
Another Example: Tower of Hanoi
• Decompose the problem

• Base case

78
Another Example: Tower of Hanoi
• Decompose the problem

• Base case

79
Another Example: Tower of Hanoi
// a:from tower, b:to tower, c: auxiliary tower
// n: number of disks to move

void Hanoi(int n, char a, char b, char c) {


if (n == 1) // base case
Move(a, b);
else { // recursion
Hanoi(n-1, a, c, b); // Move top n-1 disks from A to C using B as auxiliary
Move(a, b); // Move the last disk from A to B
Hanoi(n-1, c, b, a); // Move the n-1 disks on C to B using A as auxiliary
}
}

void Move(char a, char b) {


cout << "Move from " << a << " to " << b << endl;
}

80
Summary
• Define, call, and declare functions

• Parameter passing
• by value
• By reference

• Recursive functions

81

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy