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

07 Functions

The document provides an overview of functions in C++, covering their creation, invocation, parameter passing (by value and by reference), function overloading, and the use of prototypes and header files. It explains the concept of local and global variable scope, inline functions, and the importance of function abstraction for reducing complexity. Additionally, it discusses the benefits of functions, including reusability and information hiding, and introduces concepts like static local variables and the use of stubs in function implementation.

Uploaded by

neil.tu.tu
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)
2 views

07 Functions

The document provides an overview of functions in C++, covering their creation, invocation, parameter passing (by value and by reference), function overloading, and the use of prototypes and header files. It explains the concept of local and global variable scope, inline functions, and the importance of function abstraction for reducing complexity. Additionally, it discusses the benefits of functions, including reusability and information hiding, and introduces concepts like static local variables and the use of stubs in function implementation.

Uploaded by

neil.tu.tu
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/ 68

Functions

Tian-Li Yu
[email protected]

Department of Electrical Engineering


National Taiwan University
Objectives

➢ Understand functions
⚫ create
⚫ invoke
⚫ pass parameters to

➢ Pass-by-value, pass-by-reference
➢ Function overloading
➢ Function prototypes & header files
➢ Scope of local and global variables
➢ Inline functions

2
Introducing Functions

➢ A function is a collection of statements that are


grouped together to perform an operation

3
Introducing Functions (contd.)

➢ Function signature is the combination of the


function name and the parameter list.

➢ The variables defined in the function header →


formal parameters.

➢ When a function is invoked, you pass a value to


the parameter → actual parameter (argument).

➢ A Function may return one value or void.

4
Example: max

#include <iostream>
using namespace std;
/** Return the max between two
numbers */ int main() {
int max(int num1, int num2) { int i = 5;
int result; int j = 2;
if (num1 > num2) int k = max(i, j);
result = num1; cout << "The maximum is " << k;
else return 0;
result = num2; }
return result;
}

5
Struct

➢ If you need to return more than one variable.


⚫ You may use struct.
⚫ But later we’ll learn class in C++, which is easier to
use.

Complex add(Complex c1, Complex c2) {


struct Complex { Complex result;
double re; result.re = c1.re + c2.re;
double im; result.im = c1.im + c2.im;
}; return result;
}

6
Calling Functions

7
Calling Functions (contd.)

i is now 5

8
Calling Functions (contd.)

j is now 2

9
Calling Functions (contd.)

Invoke max(i, j)

10
Calling Functions (contd.)
invoke max(i, j)
Pass the value of i to num1 (num1=5)
Pass the value of j to num2 (num2=2)

11
Calling Functions (contd.)
return result, which is 5

12
Calling Functions (contd.)
Assign the return value to k
int k = 5;

13
Call Stacks

14
Trace Call Stack

15
Trace Call Stack (contd.)

16
Trace Call Stack (contd.)

17
Trace Call Stack (contd.)

18
Trace Call Stack (contd.)

19
Trace Call Stack (contd.)

20
Trace Call Stack (contd.)

21
Trace Call Stack (contd.)

22
Trace Call Stack (contd.)

23
Pass By Value

➢ When you invoke a function with a parameter,


the value of the argument is passed to the
parameter. This is referred to as pass-by-value.

➢ The actual parameters are not affected,


regardless of the changes made to the formal
parameter inside the function.

➢ If you don’t need a function to return any value,


declare it as void.

TestPassByValue
24
Pass By Value (contd.)

25
Reference Variables

➢ C++ provides a special type of variable, called a


reference variable.

➢ A reference variable is an alias for another


variable. Any changes made through the
reference variable are actually performed on the
original variable.

➢ To declare a reference variable, place & in front


of the name.

26
Pass By Reference

➢ Reference variable example


int count = 1;
int &ref_Count = count;

++ref_Count;
cout << "count is " << count << endl;
cout << "ref_Count is " << ref_Count << endl;

➢ We can use reference to modify the actual


parameters in a function.

TestPassByReference
27
Note

➢ Reference is like an alias.

➢ Reference exists only when the variable which it


refers to exists.

➢ For example, this is invalid.

int & count ;

28
Overloading Functions

➢ The max function that was used earlier works


only with the int data type.

➢ What if we need to find which of two floating-


point numbers has the maximum value?

➢ Create another function with the same name but


different parameters.

TestFunctionOverloading
29
Ambiguous Invocation

➢ Sometimes there may be two or more possible


matches for an invocation of a function, but the
compiler cannot determine the most specific
match.

➢ Ambiguous invocation: a compilation error.

30
Ambiguous Invocation (contd.)

int maxNumber(int num1, double num2) {


return (num1 > num2)? num1: num2;
}

double maxNumber(double num1, int num2) {


return (num1 > num2)? num1: num2;
}

int main() {
cout << maxNumber(1, 2) << endl;
return 0;
}

31
Function Prototypes

➢ Like variables, a function int f3(int num) {


needs to be declared if (num == 0) return 0;
return f1(num-1);
before it can be used.
}

➢ One way to ensure it is int f2(int num) {


to place the declaration if (num == 0) return 0;
before all function calls. return f3(num-1);
}

➢ What if… int f1(int num) {


if (num == 0) return 0;
return f2(num-1);
}
32
Function Prototypes (contd.)

➢ The other way is to declare a function prototype


before the function is called.

➢ A function prototype is a function declaration


without implementation. The implementation can
be given later in the program.

33
Function Prototypes (contd.)
int f3(int num);
int f2(int num);
int f1(int num);

int f3(int num) {


if (num == 0) return 0;
return f1(num-1);
}

int f2(int num) {


if (num == 0) return 0;
return f3(num-1);
}

int f1(int num) {


if (num == 0) return 0;
return f2(num-1);
34
}
Function Prototypes (contd.)

➢ You don’t even need to name the parameters in


function prototypes.

➢ But naming parameters is recommended for


better readability.

// Return (base^exponent)
double pow(double base, double exponent);

double pow(double, double);


35
Default Arguments

➢ C++ allows you to declare functions with default


argument values. The default values are passed
to the parameters when a function is invoked
without the arguments.

DefaultArgumentDemo

36
Example: Root Finding By Bisection

➢ Recall our root finding program.


➢ Now let’s make use of function.
➢ DBL_EPSILON
⚫ #include <cfloat> (for C++) or <float.h>
⚫ It’s the minimal difference from 1 that a double can
represent.

BisectionF

37
Recursive Call

➢ Golden rule
⚫ Base case first
⚫ Then recursive call

38
Example: Factorial

int factorial(int num){


int result = 1;
Loop Version for (int i=1; i<=num; i++)
result *= i;
return result;
}

int factorial(int num){


if (num == 0) return 1;
Recursion Version return num * factorial(num-1);
}

39
Tracing Factorial

40
Do Not Abuse Recursion

➢ Fibonacci
⚫ a0 = 0, a1 = 1.
⚫ an = an-1 + an-2

int fibonacci(int x) {
if (x==0) return 0;
if (x==1) return 1;
return fibonacci(x-2)+ fibonacci(x-1);
}

➢ This is bad. Why?


⚫ How many function calls for fibonacci(30)?
41
Tracing Fibonacci

42
Do Not Abuse Recursion (contd.)

➢ Fibonacci int fibonacci(int x) {


⚫ a0 = 0, a1 = 1. if (x==0) return 0;
⚫ an = an-1 + an-2 . if (x==1) return 1;
int a = 0, b = 1;
➢ Loop version for (int i = 2; i <= x; i++) {
result = a + b;
a = b;
➢ Only 30 b = result;
iterations for }
fibonacci(30) return result;
}

43
Practices

GCD

Double^Int

44
Header Files

➢ To make your function reusable, you need to


create a header file (*.h)

➢ A header file define the function prototype.

➢ Other programs use #include to use your


functions.

➢ Function implementations can be in separated


cpp files (recommended) or in the header file.

45
Header File Examples

➢ MyLib.h bool isEven(int number) {


return (number % 2 == 0);
}

#include <iostream>
➢ UseMyLib.cpp #include "MyLib.h"

using namespace std;


int main() {
Note!
cout << isEven(4) << endl;
cout << isEven(5) << endl;
return 0;
}
46
Header File Examples 2

➢ MyLib.h bool isEven(int number);

➢ MyLib.cpp #include <iostream>


#include "MyLib.h"
bool isEven(int number) {
return (number % 2 == 0); using namespace std;
} int main() {
cout << isEven(4) << endl;
cout << isEven(5) << endl;
return 0;
➢ UseMyLib.cpp →→ }

➢ MyLib.cpp and
UseMyLib.cpp in one project.
47
Keyword: #define

➢ Preprocessors: #define, #ifdef, #ifndef, #endif

➢ Note: they are NOT statements.

➢ #define is just a text replacement.

➢ #define N 4
int b = a * N; int b = a * 4;

➢ #define square(x) x*x


int b = square(a); int b = a * a; 48
Keyword: #define (contd.)

➢ #define max(x,y) (x>y)?x:y


int c = max(a, b); int c = (a>b)?a:b;

➢ Why do we need functions then?


⚫ How about #define square(x) x*x

int c = square(3+4); int c = 3+4*3+4; int c = 19;

⚫ How about #define square(x) (x)*(x)

int c = square(3+4); int c = (3+4)*(3+4); int c = 49;

int c = square(++a); int c = (++a)*(++a); ?


49
Keyword: #define (contd.)

➢ In general, use #define as functions is bad.


➢ Why do we need it?

➢ Prevent header files from being included twice:


#ifndef _MY_LIB_H_ Unique identifier
#define _MY_LIB_H_
MyLib.h
bool isEven(int number);

#endif

➢ Recommended way to write a header file. 50


Scope of Local Variables

➢ Local variable: defined inside a function.

➢ Scope: the part of the program where the


variable can be referenced.

➢ The scope of a variable


⚫ Starts from its declaration
⚫ Continues to the end of the block that contains the
variable.

51
Scope of Local Variables (contd.)

➢ Variable declared in the initial action part of a for


loop header has its scope in the entire loop.

➢ Variable declared inside a for loop body has its


scope limited in the loop body from its
declaration and to the end of the block that
contains the variable.

52
Scope of Local Variables (contd.)

53
Scope of Local Variables (contd.)

54
Global Variables

➢ Global variables are declared outside all functions


and are accessible to all functions in its scope.

➢ Local variables do not have default values, but


global variables are defaulted to zero.

➢ Notes:
⚫ Do not rely on “defaulted to zero.” (Always initialize)
⚫ Using global variables is usually not recommended.

VariableScopeDemo
55
Unary Scope Resolution

➢ If a local variable name is the same as a global


variable name, you can access the global variable
using ::globalVariable.
➢ The :: operator is known as the unary scope
resolution.
int v1 = 10;
int main() {
int v1 = 5;
cout << "local variable v1 is " << v1 << endl;
cout << "global variable v1 is " << ::v1 << endl;
return 0;
}
56
Static Local Variables

➢ After a function completes its execution, all its


local variables are destroyed.
➢ Sometimes, it is desirable to retain the value
stored in local variables so that they can be used
in the next call.
➢ C++ allows you to declare static local variables.
➢ Static local variables are permanently allocated in
the memory for the lifetime of the program. To
declare a static variable, use the keyword static.

StaticVariableDemo
57
Function Abstraction

➢ You can think of the Function body as a black box


that contains the detailed implementation for the
Function.

58
Benefits of Functions

• Write a Function once and reuse it anywhere.


• Information hiding. Hide the implementation
from the user.
• Reduce complexity.

59
Math Functions

60
Divide and Conquer

➢ Also known as stepwise refinement.

➢ Problem decomposition.

➢ Big, difficult problem → small, easy subproblems.

PrintCalendar

61
Design Diagram

printMonthName

62
Implementation: Top-Down

➢ Stubs can be used for the Functions waiting to be


implemented.
➢ A stub is a simple but incomplete version of a
Function.
➢ The use of stubs enables you to test invoking the
Function from a caller.

void printMonth(int year, int month) {


cout << month << " " << year << endl;
}

63
Implementation: Bottom-Up

➢ Implement one function in the structure chart at


a time from the bottom to the top.

➢ For each function implemented, write a test


program to test it.

➢ Both top-down and bottom-up functions are fine.

➢ Both approaches implement the functions


incrementally and help to isolate programming
errors and makes debugging easy.

➢ Sometimes, they can be used together.


64
Inline Functions

➢ Implementing a program using functions makes


the program easy to read and easy to maintain,
but function calls involve runtime overhead.

➢ C++ provides inline functions to avoid function


calls.

➢ Inline functions are not called; rather, the


compiler copies the function code in line at the
point of each invocation.

65
Inline Function Example

#include <iostream>
using namespace std;
inline void f(int month, int year) {
cout << "month is " << month << endl;
cout << "year is " << year << endl;
}

int main() {
int month = 10, year = 2008;
f(month, year);
return 0;
}

66
Final Notes About Inline

➢ Inline functions are desirable for short functions,


but not suitable for long functions.

➢ long inline functions will dramatically increase the


executable code size when it is copied in multiple
places.

➢ C/C++ allows the compilers to ignore the inline


keyword if the function is too long.

67
Summary

➢ Functions, prototypes, header files.

➢ Pass-by-value, pass-by-reference.

➢ Scope of local, global, and static local variables.

➢ Inline functions.

➢ Divide-and-conquer methodology.

68

You might also like