Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
7 views77 pages

Ece Oop Topic3

The document outlines key concepts in Object-Oriented Programming, focusing on variables, the preprocessor, and functions. It explains the distinctions between local, global, static, and extern variables, as well as the use of preprocessor directives like #include and #define. Additionally, it covers function declarations, definitions, and various function-related topics, providing examples throughout for clarity.

Uploaded by

102240177
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)
7 views77 pages

Ece Oop Topic3

The document outlines key concepts in Object-Oriented Programming, focusing on variables, the preprocessor, and functions. It explains the distinctions between local, global, static, and extern variables, as well as the use of preprocessor directives like #include and #define. Additionally, it covers function declarations, definitions, and various function-related topics, providing examples throughout for clarity.

Uploaded by

102240177
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/ 77

Object-Oriented Programming

Topic 3: Program Organizing

Nguyen, Thien Binh


Electrical and Computer Engineering
Vietnamese-German University

11 October 2024

T. B. Nguyen Object-Oriented Programming 11 October 2024 1 / 77


Outline
1 Variables
▶ Blocks and Local Variables
▶ Global Variables
▶ Static Variables
▶ Extern Variables
2 The Preprocessor
▶ #include Directive
▶ #define Directive
▶ Conditional Compilation with #ifdef, #ifndef, #elseif, #endif
▶ Header Files
3 Functions
▶ Declaration and Definition
▶ Default Arguments
▶ Call by Value, Reference, Arrays
▶ Return Types
▶ Function Overloading
▶ Recursive Functions
▶ inline Functions
T. B. Nguyen Object-Oriented Programming 11 October 2024 2 / 77
Outline

1 Variables

T. B. Nguyen Object-Oriented Programming 11 October 2024 3 / 77


Blocks and Local Variables
A block: is whatever defined in between a pair of brackets {}
A local variable:
▶ is defined inside a block
▶ has block scope, i.e., exists within that block only
▶ has automatic duration, i.e., they are automatically allocated on the
stack memory when defined, and deallocated when out of scope
1 int main ()
2 {
3 {
4 int localVar = 10 ;
5 cout << " Inside ␣ the ␣ block : ␣ localVar ␣ = ␣ "
6 << localVar << endl ;
7 }
8 cout << " Outside ␣ the ␣ block : ␣ localVar ␣ = ␣ "
9 << localVar << endl ;
10 return 0 ;
11 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 4 / 77


Global Variables
A global variable:
▶ is defined outside any blocks, by convention, at the top of a file, below
the includes, and above the main
▶ has file scope, i.e., is available anywhere in the file where it is defined
▶ has static duration, i.e., exists until the end of the program
1 # include < iostream >
2 using namespace std ;
3 int globalVar = 100 ;
4
5 int main ()
6 {
7 {
8 globalVar = 10 ;
9 cout << " Inside ␣ the ␣ block : ␣ globalVar ␣ = ␣ "
10 << globalVar << endl ;
11 }
12 cout << " Outside ␣ the ␣ block : ␣ globalVar ␣ = ␣ "
13 << globalVar << endl ;
14 return 0 ;
15 }
T. B. Nguyen Object-Oriented Programming 11 October 2024 5 / 77
Global Variables
What if a local and global variable have the same name? What is the
output inside and outside the block?
1 # include < iostream >
2 using namespace std ;
3 int var = 100 ;
4
5 int main ()
6 {
7 {
8 int var = 20 ;
9 cout << " Inside ␣ the ␣ block : ␣ var ␣ = ␣ "
10 << var << endl ;
11 }
12 cout << " Outside ␣ the ␣ block : ␣ var ␣ = ␣ "
13 << var << endl ;
14 return 0 ;
15 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 6 / 77


Global Variables

What if a local and global variable have the same name? What is the
output inside and outside the block?
1 # include < iostream >
2 using namespace std ;
3 int var = 100 ;
4
5 int main ()
6 {
7 {
8 int var = 20 ;
9 cout << " Inside ␣ the ␣ block : ␣ var ␣ = ␣ " << var << endl ;
10 }
11 cout << " Outside ␣ the ␣ block : ␣ var ␣ = ␣ " << var << endl ;
12 return 0 ;
13 }

⇒ The local variable is prioritized inside the block it is defined.

T. B. Nguyen Object-Oriented Programming 11 October 2024 7 / 77


Static Variables
A static variable:
▶ can be defined anywhere in a program
▶ has file scope and static duration, just like a global variable
▶ has its memory allocated fixed for the lifetime of the program
▶ is initialized just ONCE, and has its value carried on to the next times
when it is used
▶ is commonly used to generate a unique ID for each generated object
1 # include < iostream >
2 using namespace std ;
3 int ObjCounting ()
4 {
5 static int objID = 0 ;
6 return ++ objID ; // starting with 1
7 }
8 int main ()
9 {
10 for ( int i = 0 ; i < 5 ; ++ i )
11 cout << " Object ␣ ID ␣ = ␣ " << ObjCounting () << endl ;
12 return 0 ;
13 }
T. B. Nguyen Object-Oriented Programming 11 October 2024 8 / 77
Extern Variables
Question: A global variable has file scope, i.e., it is visible within the
file it is defined. Then how can a global variable be referred to in a
different file? For example, we want to use the same variable x in
both ExampleLinkage File 1.cpp and
ExampleLinkage File 2.cpp below.
1 int x (5) ; // global variable

Listing 1: ExampleLinkage File 1.cpp


1 # include < iostream >
2 using namespace std ;
3 int main ()
4 {
5 // want to refer to x defined in Ex ample Link age_ File_ 1 . cpp
6 // error : x is not defined !
7 cout << " x ␣ = ␣ " << x << endl ;
8 return 0 ;
9 }

Listing 2: ExampleLinkage File 2.cpp


T. B. Nguyen Object-Oriented Programming 11 October 2024 9 / 77
Extern Variables

Linkage: determines whether a variable can be referred to in multiple


files.
No linkage: variables without linkage are the local ones since they
exist with the block they are defined only
Internal linkage: variables with internal linkage can be visible within
the file that they are defined, i.e., strictly has file scope. These
include
▶ static global variables
▶ const variables
▶ in-line functions
▶ typedef names
▶ enumerations

T. B. Nguyen Object-Oriented Programming 11 October 2024 10 / 77


Extern Variables I

External linkage: variables with external linkage can be visible within


all the files of the program. These include
▶ non-static global variables
▶ static class members
▶ non-const variables
▶ functions
In order for a variable with external linkage to be used, a forward
declaration with keyword extern must be added to tell the compiler
that the variable has been defined in a different file of the program.
Since extern variables are visible in multiple files, they have global
scope.
extern variables has scope depending on where they are forward
declared in the file.

T. B. Nguyen Object-Oriented Programming 11 October 2024 11 / 77


Extern Variables II

1 // global variables have external linkage


2 // no need to add " extern " here
3 int x (5) ;
4 int y ;

Listing 3: ExampleLinkage File 1.cpp


1 # include < iostream >
2 using namespace std ;
3 // forward declaration : this tells the compile that
4 // x has been defined in a different file
5 // in this file , x has file scope
6 extern int x ;
7 int main ()
8 {
9 cout << " x ␣ = ␣ " << x << endl ;
10 {
11 // forward declaration for y
12 // y has local scope in this file

T. B. Nguyen Object-Oriented Programming 11 October 2024 12 / 77


Extern Variables III

13 extern int y ;
14 y = 10 ;
15 cout << " y ␣ = ␣ " << y << endl ;
16 }
17 // cout << " y = " << y << endl ; NOT visible
18 return 0 ;
19 }

Listing 4: ExampleLinkage File 2.cpp

Constants have internal linkage ⇒ adding extern where defining the


constants to change their linkage

T. B. Nguyen Object-Oriented Programming 11 October 2024 13 / 77


Extern Variables IV

1 // global variables have external linkage


2 // no need to add " extern " here
3 int x (5) ;
4 int y ;
5
6 // constants have internal linkage
7 // adding ’" extern " is needed
8 extern const int c = 100 ;

Listing 5: ExampleLinkage File 1.cpp


1 # include < iostream >
2 using namespace std ;
3 // forward declaration for x
4 extern int x ;
5 // forward declaration for const c
6 extern const int c ;
7 int main ()
8 {

T. B. Nguyen Object-Oriented Programming 11 October 2024 14 / 77


Extern Variables V

9 cout << " x ␣ = ␣ " << x << endl ;


10 cout << " c ␣ = ␣ " << c << endl ;
11 {
12 // forward declaration for y
13 extern int y ;
14 y = 10 ;
15 cout << " y ␣ = ␣ " << y << endl ;
16 }
17 return 0 ;
18 }

Listing 6: ExampleLinkage File 2.cpp

T. B. Nguyen Object-Oriented Programming 11 October 2024 15 / 77


Outline

2 The Preprocessor

T. B. Nguyen Object-Oriented Programming 11 October 2024 16 / 77


The Preprocessor

Prior to compilation, the code goes through a phase known as


translation in which a preprocessor takes place.
The preprocessor ignores all code contents but looks for special
directives starting with # and makes appropriate changes/substitutions
The following directives are noteworthy: #include, #define, and
the conditional compilation directivesñ #ifdef, #ifndef, #elseif,
#endif

T. B. Nguyen Object-Oriented Programming 11 October 2024 17 / 77


#include Directive

1 # include < iostream >


2 # include < cmath >
3 # include < cassert >
4 # include " user - header - file . h "

When the preprocessor scans and finds the #include, it will replace
the directive by all the preprocessed contents of associate header file.
A < > bracket is used for standard ANSI C++ libraries, e.g.,
iostream, cmath, or cassert, whereas a quotation " " is used for
user-defined header files.
The #include directive is mainly used to substitute header files .h
into source files .cpp

T. B. Nguyen Object-Oriented Programming 11 October 2024 18 / 77


#include Directive
1 double TriArea ( double height , double base ) ;
2 void Print ( double result ) ;

Listing 7: ExampleDeclare.h

1 # include < iostream >


2 # include " ExampleDeclare . h "
3 using namespace std ;
4
5 double TriArea ( double height , double base )
6 {
7 double area ;
8 area = 0.5* height * base ;
9 return area ;
10 }
11
12 void Print ( double result )
13 {
14 cout << " Result ␣ = ␣ " << result << endl ;
15 }
T. B. Nguyen ListingObject-Oriented
8: ExampleDefine.cpp
Programming 11 October 2024 19 / 77
ExampleDeclare.h and ExampleDefine.cpp are equivalent to
1 // all preprocessed contents of
2 // / usr / include / g ++ / iostream
3 // the contents of ExampleDeclare . h
4 double TriArea ( double height , double base ) ;
5 void Print ( double result ) ;
6 using namespace std ;
7
8 double TriArea ( double height , double base )
9 {
10 double area ;
11 area = 0.5* height * base ;
12 return area ;
13 }
14
15 void Print ( double result )
16 {
17 cout << " Result ␣ = ␣ " << result << endl ;
18 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 20 / 77


#define Directive

1 # define IDENTIFIER tokens

When a processor scans and finds #define, it will textually substitute


all occurrences of IDENTIFIER with tokens
The #define directive is mostly used for defining and giving
meaningful names for global constants
1 # define PI 3.14159265358979323846264338
2 # define LIGHTSPEED 2.997925 e8
3 # define ZERO 0.00000000000000000000000000

T. B. Nguyen Object-Oriented Programming 11 October 2024 21 / 77


#define Directive

The #define directive can also be used to define simple functions,


e.g.,
1 # define SQUARE ( X ) (( x ) * ( X ))

then
1 y = SQUARE (4.0) ;

is equivalent to
1 y = ( (4.0) * (4.0) ) ;

It is always considered a better practice to use const to define


constants instead of #define (see Lecture 2)

T. B. Nguyen Object-Oriented Programming 11 October 2024 22 / 77


Conditional Compilation

1 # define CONDITION_1
2
3 # ifdef CONDITION_1
4 // code segment 1
5 # endif
6
7 # ifndef CONDITION_2
8 // code segment 2
9 # endif

#ifdef, #ifndef, #elseif, #endif can be used to determine which


part of the code is going to be compiled and which is not.
code segment 1 will be compiled if CONDITION 1 is defined. On the
contrary, code segment 2 will be compiled if CONDITION 2 is not
defined.

T. B. Nguyen Object-Oriented Programming 11 October 2024 23 / 77


Conditional Compilation
Example: What is printed out to the screen?
1 # include < iostream >
2 using namespace std ;
3 # define COMPILE
4 void printsomething ()
5 {
6 # ifdef COMPILE
7 cout << " code ␣ segment ␣ 1 " << endl ;
8 # endif
9
10 # ifndef COMPILE
11 cout << " code ␣ segment ␣ 2 " << endl ;
12 # endif
13 }
14
15 int main ()
16 {
17 printsomething () ;
18 return 0 ;
19 }
T. B. Nguyen Object-Oriented Programming 11 October 2024 24 / 77
Conditional Compilation
Example: What is printed out to the screen? Why is that?
1 # include < iostream >
2 using namespace std ;
3 void printsomething ()
4 {
5 # ifdef COMPILE
6 cout << " code ␣ segment ␣ 1 " << endl ;
7 # endif
8
9 # ifndef COMPILE
10 cout << " code ␣ segment ␣ 2 " << endl ;
11 # endif
12 }
13
14 # define COMPILE
15 int main ()
16 {
17 printsomething () ;
18 return 0 ;
19 }
T. B. Nguyen Object-Oriented Programming 11 October 2024 25 / 77
Conditional Compilation
Example: What is printed out to the screen? Why is that?
1 # include < iostream >
2 using namespace std ;
3 void printsomething ()
4 {
5 # ifdef COMPILE
6 cout << " code ␣ segment ␣ 1 " << endl ;
7 # endif
8 # ifndef COMPILE
9 cout << " code ␣ segment ␣ 2 " << endl ;
10 # endif
11 }
12 # define COMPILE
13 int main ()
14 {
15 printsomething () ;
16 return 0 ;
17 }
⇒ A preprocessor ignores all code contents or sequences but looks only for
directives from top to bottom
T. B. Nguyen
of the code.
Object-Oriented Programming 11 October 2024 26 / 77
Conditional Compilation

The #ifdef, #ifndef, #endif together with #define directive are


of particularly useful in creating header guards for header files which
prevents multiple definition.

T. B. Nguyen Object-Oriented Programming 11 October 2024 27 / 77


Header Files

A C++ files are basically classified into 2 types:


▶ source files with the extension .cpp which contain all variables,
functions, and classes definitions,
▶ header files with the extension .h in which functions and classes are
declared. Short inline functions and global constants may also be
defined in header files.
Header files are included into source files with the #include directive.
Using header files enhance code readability and abstraction since
users could justify the use of, e.g., a class, by inspecting its member
data and methods declared in the header file
Header files also serve as the interface for packaged libraries. It is
common that a shared C++ library has its source files precompiled
for the reason of security or copyrights, and users just need to include
the library’s header file in order to use it.

T. B. Nguyen Object-Oriented Programming 11 October 2024 28 / 77


Header Files I

Although a header file can be included in as many files as wanted,


this could
▶ increase the overhead cost as a preprocessor has to substitute all the
contents of the header file at the inclusion location
▶ return errors if there are variables or non-inline functions defined more
than once.
Example: What is wrong with the following code?
1 # include < iostream >
2 using namespace std ;
3
4 // global variable ;
5 double area ;
6
7 // functions
8 double recArea ( const double & side1 , const double & side2 ) ;
9 void printArea ()
10 {

T. B. Nguyen Object-Oriented Programming 11 October 2024 29 / 77


Header Files II

11 cout << " The ␣ area ␣ is ␣ " << area << endl ;
12 }

Listing 9: RecAreaDeclared.h

1 # include " RecAreaDeclared . h "


2
3 // definition for RecArea
4 double recArea ( const double & side1 , const double & side2 )
5 {
6 return side1 * side2 ;
7 }

Listing 10: RecAreaDefined.h

T. B. Nguyen Object-Oriented Programming 11 October 2024 30 / 77


Header Files III

1 # include < iostream >


2 # include " RecAreaDeclared . h "
3 # include " RecAreaDefined . h "
4 using namespace std ;
5 int main ()
6 {
7 double side1 (5) , side2 (10) ;
8 area = recArea ( side1 , side2 ) ;
9 printArea () ;
10 return 0 ;
11 }

Listing 11: RecAreaMain.cpp

T. B. Nguyen Object-Oriented Programming 11 October 2024 31 / 77


Header Files I

Example: What is wrong with the following code? ⇒ area and


recArea are defined twice.
Substituted code:
1 # include < iostream >
2 using namespace std ;
3
4 // === from RecAreaDeclared . h
5 // global variable ;
6 double area ;
7
8 // functions
9 double recArea ( const double & side1 , const double & side2 ) ;
10 void printArea ()
11 {
12 cout << " The ␣ area ␣ is ␣ " << area << endl ;
13 }
14

T. B. Nguyen Object-Oriented Programming 11 October 2024 32 / 77


Header Files II

15 // === from RecAreaDefined . h


16 // global variable ;
17 double area ;
18
19 // functions
20 double recArea ( const double & side1 , const double & side2 ) ;
21 void printArea ()
22 {
23 cout << " The ␣ area ␣ is ␣ " << area << endl ;
24 }
25
26 // definition for RecArea
27 double recArea ( const double & side1 , const double & side2 )
28 {
29 return side1 * side2 ;
30 }
31
32
33

T. B. Nguyen Object-Oriented Programming 11 October 2024 33 / 77


Header Files III

34 int main ()
35 {
36 double side1 (5) , side2 (10) ;
37 area = recArea ( side1 , side2 ) ;
38 printArea () ;
39 return 0 ;
40 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 34 / 77


Header Files I

Header Guards: to prevent multiple definitions of the same variable or


function, or unnecessary inclusion of header files.
Guarded header files:
1 # ifndef _R EC AR EA _D ECLARED_ // header guard
2 # define _R EC AR EA _D ECLARED_ // header guard
3 # include < iostream >
4 using namespace std ;
5 // global variable ;
6 double area ;
7 // functions
8 double recArea ( const double & side1 , const double & side2 ) ;
9 void printArea ()
10 {
11 cout << " The ␣ area ␣ is ␣ " << area << endl ;
12 }
13 # endif

Listing 12: RecAreaDeclared.h


T. B. Nguyen Object-Oriented Programming 11 October 2024 35 / 77
Header Files II

1 # ifndef _RECA REA_DEFINED_ // header guard


2 # define _RECA REA_DEFINED_ // header guard
3
4 # include " RecAreaDeclared . h "
5
6 // definition for RecArea
7 double recArea ( const double & side1 , const double & side2 )
8 {
9 return side1 * side2 ;
10 }
11
12 # endif

Listing 13: RecAreaDefined.h

T. B. Nguyen Object-Oriented Programming 11 October 2024 36 / 77


Header Files III

1 # include < iostream >


2 # include " RecAreaDeclared . h "
3 # include " RecAreaDefined . h "
4 using namespace std ;
5 int main ()
6 {
7 double side1 (5) , side2 (10) ;
8 area = recArea ( side1 , side2 ) ;
9 printArea () ;
10 return 0 ;
11 }

Listing 14: RecAreaMain.cpp

T. B. Nguyen Object-Oriented Programming 11 October 2024 37 / 77


Header Files

Header Guards: to prevent multiple definitions of the same variable or


function, or unnecessary inclusion of header files.
RecAreaDeclared.h: initially, since RECAREA DECLARED was not
defined, the whole file will be compiled due to the #ifndef directive
which defines condition RECAREA DECLARED . When included for the
second time, since RECAREA DECLARED has been defined, the whole
file is ignored.
⇒ No matter how many times RecAreaDeclared.h is included, the
file is in fact compiled just ONCE.

T. B. Nguyen Object-Oriented Programming 11 October 2024 38 / 77


Outline

3 Functions

T. B. Nguyen Object-Oriented Programming 11 October 2024 39 / 77


Functions

A function can be both declared and defined


▶ Declaration:
return type function name(type arg 1, type arg 2, . . .,
type arg n);
▶ Definition:
return type function name(type arg 1, type arg 2, . . .,
type arg n)
{
// function body;
return result;
}
A function can be declared as many times as possible, but defined
only ONCE.

T. B. Nguyen Object-Oriented Programming 11 October 2024 40 / 77


Functions

Why declarations?
▶ For complicated programs with multiple files involved, declarations help
code maintenance and modularity. A common coding practice is that
all relevant functions are declared and collected in a header file which is
included into another source file.
▶ Function declarations play a role in defining classes in C++.
▶ Declarations are in particular important for code packaging which
makes it possible for shared libraries. The declarations collected in a
header file play as the interfaces to the source codes where the
functions are defined. These source codes can be pre-compiled for
saving compile time or protecting copyrights, etc.
Functions have external linkage, i.e., forward declarations with
extern is needed if the functions have global scope

T. B. Nguyen Object-Oriented Programming 11 October 2024 41 / 77


Functions I

Example: The following functions are declared, defined, and used in


different files. 4 files involve in this program.
1 double TriArea ( double height_ , double base_ ) ;
2 void Print ( double result_ ) ;

Listing 15: FunctionDeclare.h

1 double RecArea ( double side1_ , double side2_ )


2 {
3 double area_ ;
4 area_ = side1_ * side2_ ;
5 return area_ ;
6 }
7
8
9 // TriArea is re - declared here . OK !
10 double TriArea ( double height_ , double base_ ) ;

T. B. Nguyen Object-Oriented Programming 11 October 2024 42 / 77


Functions II

Listing 16: FunctionExtern.cpp

1 # include < iostream >


2 // Declarations of TriArea and Print
3 // are included here
4 # include " FunctionDeclare . h "
5 using namespace std ;
6
7 double TriArea ( double height_ , double base_ )
8 {
9 double area_ ;
10 area_ = 0.5* height_ * base_ ;
11 return area_ ;
12 }
13
14 void Print ( double result_ )
15 {

T. B. Nguyen Object-Oriented Programming 11 October 2024 43 / 77


Functions III

16 cout << " Result ␣ = ␣ " << result_ << endl ;


17 }
18
19 // RecArea is re - defined here . Error !
20 /*
21 double RecArea ( double side1_ , double side2_ )
22 {
23 double area_ ;
24 area_ = side1_ * side2_ ;
25 return area_ ;
26 }
27 */

Listing 17: FunctionDefine.cpp

T. B. Nguyen Object-Oriented Programming 11 October 2024 44 / 77


Functions IV

1 # include < iostream >


2 # include " FunctionDeclare . h "
3 // forward declaration for RecArea
4 extern double RecArea ( double side1_ , double side2_ ) ;
5 using namespace std ;
6 int main ()
7 {
8 double h (3.0) , b (5.0) ;
9 Print ( TriArea (h , b ) ) ;
10 Print ( RecArea (h , b ) ) ;
11 return 0 ;
12 }

Listing 18: FunctionMain.cpp

T. B. Nguyen Object-Oriented Programming 11 October 2024 45 / 77


Functions V

1 CC = g ++
2 CFLAGS = -g - Wall
3 LDFLAGS =
4 OBJS = FunctionExtern . o FunctionDefine . o FunctionMain . o
5 TARGET = aaa
6
7 all : $ ( TARGET )
8
9 $ ( TARGET ): $ ( OBJS )
10 $ ( CC ) $ ( CFLAGS ) -o $ ( TARGET ) $ ( OBJS ) $ ( LDFLAGS )
11
12 clean :
13 rm -f $ ( OBJS )

Listing 19: makefile function

T. B. Nguyen Object-Oriented Programming 11 October 2024 46 / 77


Default Arguments

Default values of arguments can be set when a function is declared


1 double TriArea ( double height_ = 3.0 , double base_ = 5.0)
2 {
3 double area_ ;
4 area_ = 0.5* height_ * base_ ;
5 return area_ ;
6 }
7
8 int main ()
9 {
10 Print ( TriArea () ) ;
11 Print ( TriArea (2.0) ) ;
12 Print ( TriArea (0.5 , 2.0) ) ;
13 return 0 ;
14 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 47 / 77


Call by Value
If a variable is in the argument list, a copy of it this variable is created
locally within the scope of the function
1 # include < iostream >
2 using namespace std ;
3
4 double square ( double x_ )
5 {
6 cout << " & x_ ␣ = ␣ " << & x_ << endl ;
7 x_ = x_ * x_ ;
8 return x_ ;
9 }
10
11 int main ()
12 {
13 double x (10) ;
14 cout << " & x ␣ = ␣ " << & x << endl ;
15 cout << " square ( x ) ␣ = ␣ " << square ( x ) << endl ;
16
17 return 0 ;
18 }
T. B. Nguyen Object-Oriented Programming 11 October 2024 48 / 77
Call by Value
Modification of a local variable in a function does not change the
original variable where the function was called
1 # include < iostream >
2 using namespace std ;
3 void donothing ( double x )
4 {
5 x = x * x;
6 }
7 int main ()
8 {
9 double x (10) ;
10 donothing ( x ) ;
11 cout << " x ␣ = ␣ " << x << endl ;
12 return 0 ;
13 }

Calling by value for large objects is usually expensive (running time


and memory allocation) due to the copying process of local variables
T. B. Nguyen Object-Oriented Programming 11 October 2024 49 / 77
Call by Reference

If a reference or a pointer is in the argument list, a copy of this


reference or pointer pointing to the same variable, i.e., the same
memory location, is created
Modification of a local variable changes the original variable where
the function was called since the the reference or pointer points to
the same memory location of the original variable

T. B. Nguyen Object-Oriented Programming 11 October 2024 50 / 77


Call by Reference I

1 # include < iostream >


2 using namespace std ;
3
4 // call by reference
5 void setArg_ref ( double & x_ )
6 {
7 cout << " & x_ ␣ = ␣ " << & x_ << endl ;
8 x_ = 100.0 ;
9 }
10
11 // call by pointer
12 void setArg_ptr ( double * x_ )
13 {
14 cout << " x_ ␣ = ␣ " << x_ << endl ;
15 * x_ = 100.0 ;
16 }
17
18 int main ()
19 {

T. B. Nguyen Object-Oriented Programming 11 October 2024 51 / 77


Call by Reference II

20 double x ;
21 x = 10.0 ;
22 cout << " x ␣ = ␣ " << x << endl ;
23 cout << " & x ␣ = ␣ " << & x << endl ;
24
25 // pass by value
26 setArg_ref ( x ) ;
27 cout << " x ␣ = ␣ " << x << endl ;
28 // pass by address
29 setArg_ptr (& x ) ;
30 cout << " x ␣ = ␣ " << x << endl ;
31
32 return 0 ;
33 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 52 / 77


Call by Reference I

Using references or pointers, a function can return multiple variables


1 # include < iostream >
2 # include < cmath >
3 using namespace std ;
4 const double PI ( 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 8 8 4 ) ;
5
6 void Polar2Cartesian ( double & r_ , double & theta_ ,
7 double & x_ , double & y_ )
8 {
9 cout << " & x_ ␣ = ␣ " << & x_
10 << " ,␣ & y_ ␣ = ␣ " << & y_ << endl ;
11 cout << " & r_ ␣ = ␣ " << & r_
12 << " ,␣ & r_ ␣ = ␣ " << & r_ << endl ;
13 x_ = r_ * cos ( theta_ ) ;
14 y_ = r_ * sin ( theta_ ) ;
15 }
16
17 int main ()

T. B. Nguyen Object-Oriented Programming 11 October 2024 53 / 77


Call by Reference II

18 {
19 double r (3.5) , theta ( PI /3.0) ;
20 double x , y ;
21 Polar2Cartesian (r , theta , x , y ) ;
22 cout << " & x ␣ = ␣ " << & x
23 << " ,␣ & y ␣ = ␣ " << & y << endl ;
24 cout << " & r ␣ = ␣ " << & r
25 << " ,␣ & r ␣ = ␣ " << & r << endl ;
26 cout << " (r , ␣ theta ) ␣ = ␣ " << r
27 << " ,␣ " << theta << endl ;
28 cout << " (x , ␣ y ) ␣ = ␣ " << x
29 << " ,␣ " << y << endl ;
30
31 return 0 ;
32 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 54 / 77


Call by Reference
In case one does not want the original variables to be modified,
const can be used. This is commonly used for large objects passed as
arguments into functions, for example, r and theta are supposed not
to be modified since they are input parameters. In this case, we can
change to function as
1 void Polar2Cartesian ( const double & r_ , const double & theta_ ,
2 double & x_ , double & y_ )
3 {
4 r_ = 10.0 ; theta_ = 0.5* PI ; // r_ , theta_ cannot be modified
5 cout << " & x_ ␣ = ␣ " << & x_
6 << " ,␣ & y_ ␣ = ␣ " << & y_ << endl ;
7 cout << " & r_ ␣ = ␣ " << & r_
8 << " ,␣ & r_ ␣ = ␣ " << & r_ << endl ;
9 x_ = r_ * cos ( theta_ ) ;
10 y_ = r_ * sin ( theta_ ) ;
11 }

Call by reference is cost efficient since no copies of large objects are


needed to pass through function interfaces
T. B. Nguyen Object-Oriented Programming 11 October 2024 55 / 77
Call by Array I

Static allocated arrays can be passed into a function by using square


brackets without specifying the exact number of array elements, e.g.,
v[], A[][]
Pointers are used for dynamically allocated arrays, e.g., *v for 1D
arrays, and **A for 2D arrays
Example: function to compute the dot product of two vectors of the
same size
1 # include < iostream >
2 # include < cmath >
3 using namespace std ;
4
5 // to compute the dot product of 2 vectors of size
6 double DotProd ( const int & size ,
7 const double v [] ,
8 const double w [])
9 {

T. B. Nguyen Object-Oriented Programming 11 October 2024 56 / 77


Call by Array II

10 double dot (0.0) ;


11 for ( int i = 0 ; i < size ; ++ i )
12 dot += v [ i ] * w [ i ] ;
13
14 return dot ;
15 }
16
17 int main ()
18 {
19 int size (4) ;
20 double v [ size ] = {1 , 2 , 3 , 4}
21 double w [ size ] = {4 , 3 , 2 , 1} ;
22 cout << " dot (v , ␣ w ) ␣ = ␣ " << DotProd ( size , v , w ) << endl ;
23
24 return 0 ;
25 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 57 / 77


Function Return
Similarly to the input arguments, a function can return either by
value, reference, or pointer, or nothing (void)
Example: functions to allocate and de-allocate a vector
1 // return by pointer
2 double * allocateVec ( const int & numCols )
3 {
4 double * v ;
5 v = new double [ numCols ] ;
6 return v ;
7 }
8
9 // void return
10 void deallocateVec ( double * v_ )
11 {
12 delete [] v ; // for arrays
13 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 58 / 77


Function Return I

Example: Write a functions to set and get the value for each entry of
a vector

T. B. Nguyen Object-Oriented Programming 11 October 2024 59 / 77


Function Return I

Example: Write functions to set and get the value for each entry of a
vector
1 # include < iostream >
2 using namespace std ;
3
4 // return by reference
5 // allow to modify the returned variable
6 double & setVal ( double v [] , const int & index )
7 {
8 return v [ index ] ;
9 }
10
11 // return by value
12 // does not allow to modify the returned variable
13 double getVal ( double v [] , const int & index )
14 {
15 return v [ index ] ;
16 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 60 / 77


Function Return II
17 // void return
18 void printVec ( double v [] , const int & size )
19 {
20 for ( int j = 0 ; j < size ; ++ j )
21 cout << getVal (v , j ) << " ,␣ " ;
22 cout << endl ;
23 }
24 int main ()
25 {
26 int size (3) ;
27 double v [ size ] ;
28 setVal (v , 0) = 1.0 ;
29 setVal (v , 1) = 2.0 ;
30 setVal (v , 2) = 3.0 ;
31 printVec (v , size ) ;
32 return 0 ;
33 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 61 / 77


Function Return

Example: What is wrong in the following function?


1 # include < iostream >
2 using namespace std ;
3 // return by reference
4 double & somethingWrong ( const double & x )
5 {
6 double y ;
7 y = x + 2;
8 return y ;
9 }
10 int main ()
11 {
12 cout << " Result ␣ = ␣ " << somethingWrong (10.0) << endl ;
13 return 0 ;
14 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 62 / 77


Function Return

Example: What is wrong in the following function?


1 # include < iostream >
2 using namespace std ;
3 // return by reference
4 double & somethingWrong ( const double & x )
5 {
6 double y ;
7 y = x + 2;
8 return y ;
9 }
10 int main ()
11 {
12 cout << " Result ␣ = ␣ " << somethingWrong (10.0) << endl ;
13 return 0 ;
14 }

⇒ Return the reference of a local variable (y) which has been destroyed
when the function is returned!
T. B. Nguyen Object-Oriented Programming 11 October 2024 63 / 77
Function Overloading

In C++, it is possible that a same function is declared and defined


many times with different bodies. This is known as function
overloading
Over loaded functions must be distinguished one another by having
different number of arguments or argument types
Example: Write function add which do the summation of either two
scalars or vectors. Use function overloading with two definitions of
the same function add

T. B. Nguyen Object-Oriented Programming 11 October 2024 64 / 77


Function Overloading I

Example: Write function add which do the summation of either two


scalars or vectors. Use function overloading with two definitions of
the same function add
1 # include < iostream >
2 using namespace std ;
3
4 double * allocateVec ( const int & numCols )
5 {
6 double * v ;
7 v = new double [ numCols ] ;
8 return v ;
9 }
10
11 void deallocateVec ( double * v )
12 {
13 delete [] v ; // for arrays
14 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 65 / 77


Function Overloading II

15
16 void printVec ( const int & numCols_ , double * v_ )
17 {
18 for ( int j = 0 ; j < numCols_ ; ++ j )
19 cout << v_ [ j ] << " ,␣ " ;
20 cout << endl ;
21 }
22
23 double add ( double x1 , double x2 )
24 {
25 return x1 + x2 ;
26 }
27
28 // add two scalars
29 void add ( const double & alp1 , const double & alp2 , double & beta )
30 {
31 beta = alp1 + alp2 ;
32 }
33

T. B. Nguyen Object-Oriented Programming 11 October 2024 66 / 77


Function Overloading III

34 // add two vectors


35 void add ( const int & length , const double * v1 , const double * v2
36 {
37 for ( int i = 0 ; i < length ; ++ i )
38 w [ i ] = v1 [ i ] + v2 [ i ] ;
39 }
40
41 int main ()
42 {
43 int length (5) ;
44 double alp1 (10) , alp2 (20) , beta ;
45 double * v1 , * v2 , * w ;
46
47 v1 = allocateVec ( length ) ;
48 v2 = allocateVec ( length ) ;
49 w = allocateVec ( length ) ;
50
51 for ( int i = 0 ; i < length ; ++ i )
52 {

T. B. Nguyen Object-Oriented Programming 11 October 2024 67 / 77


Function Overloading IV

53 v1 [ i ] = i ;
54 v2 [ i ] = 2.0* i ;
55 }
56
57 add ( alp1 , alp2 , beta ) ;
58 add ( length , v1 , v2 , w ) ;
59
60 cout << " beta ␣ = ␣ " << beta << endl ;
61 printVec ( length , w ) ;
62
63 deallocateVec ( v1 ) ;
64 deallocateVec ( v2 ) ;
65 deallocateVec ( w ) ;
66
67 return 0 ;
68 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 68 / 77


Recursive Functions

Recursion is that a function calls itself, and the corresponding


function is called a recursive function
A base case must be specified in a recursive function
Example: Write a function to compute the factorial of an
non-negative integer

T. B. Nguyen Object-Oriented Programming 11 October 2024 69 / 77


Recursive Functions I

Example: Write a function to compute the factorial of an


non-negative integer
1 # include < iostream >
2 using namespace std ;
3
4 int Fact ( int n )
5 {
6 int x ;
7 // base case : must be specified
8 if ( n < 0)
9 cout << " Err : ␣ n ␣ must ␣ be ␣ greater ␣ than ␣ or ␣ equal ␣ zero ! "
10 << endl ;
11 else if ( n == 0 || n == 1)
12 x = 1;
13 else
14 // recursion : function calls itself
15 x = n * Fact ( n - 1) ;
16 return x ;

T. B. Nguyen Object-Oriented Programming 11 October 2024 70 / 77


Recursive Functions II

17 }
18
19 int main ()
20 {
21 cout << " Fact (5) ␣ = ␣ " << Fact (5) << endl ;
22 return 0 ;
23 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 71 / 77


inline Functions

Overhead cost: whenever a function is called, the program needs to


▶ store the address of the current statement it is executing
▶ copy, allocate the memory, and assign values to the input arguments of
the function
▶ jump to the new memory location allocated for the function execution
▶ etc.
⇒ This overhead cost is significant for small functions!
inline functions: having their contents substituted directly to the
code at run time ⇒ No overhead cost!

T. B. Nguyen Object-Oriented Programming 11 October 2024 72 / 77


inline Functions I

Example: Replacing functions setVec, getVec, and printVec above


with inline versions in a header file.
1 # include < iostream >
2 using namespace std ;
3 // return by reference
4 // allow to modify the returned variable
5 inline double & setVal ( double v [] , const int & index )
6 {
7 return v [ index ] ;
8 }
9
10 // return by value
11 // does not allow to modify the returned variable
12 inline double getVal ( double v [] , const int & index )
13 {
14 return v [ index ] ;
15 }
16

T. B. Nguyen Object-Oriented Programming 11 October 2024 73 / 77


inline Functions II
17 // void return
18 inline void printVec ( double v [] , const int & size )
19 {
20 for ( int j = 0 ; j < size ; ++ j )
21 cout << getVal (v , j ) << " ,␣ " ;
22 cout << endl ;
23 }

Listing 20: ExampleFunction inline.h

1 # include " E x a m p l e F u n c ti on_ in li ne . h "


2 int main ()
3 {
4 int size (3) ;
5 double v [ size ] ;
6 setVal (v , 0) = 1.0 ;
7 setVal (v , 1) = 2.0 ;
8 setVal (v , 2) = 3.0 ;
9 printVec (v , size ) ;

T. B. Nguyen Object-Oriented Programming 11 October 2024 74 / 77


inline Functions III
10
11 return 0 ;
12 }

Listing 21: ExampleFunction inline.cpp


In run time, these inline functions are directly substituted into the
code.
1 # include " E x a m p l e F u n c ti on_ in li ne . h "
2 int main ()
3 {
4 int size (3) ; double v [ size ] ;
5 v [0] = 1.0 ; v [1] = 2.0 ; v [2] = 3.0 ;
6 for ( int j = 0 ; j < size ; ++ j )
7 cout << v [ j ] << " ,␣ " ;
8 cout << endl ;
9 return 0 ;
10 }

T. B. Nguyen Object-Oriented Programming 11 October 2024 75 / 77


inline Functions

Since inline functions have internal linkage, it is a common coding


practice that they are defined in header .h files so that they are
always copied into the source files when being used.
Inline functions usually increase the size of the generated code but
decrease the execution time (no overhead cost). Thus, inline
functions are best suited for short functions only.

T. B. Nguyen Object-Oriented Programming 11 October 2024 76 / 77


Reading

1 Capper, Introducing C++ for Scientists, Engineers, and


Mathematicians, Chapter 5
2 Pitt-Francis, and Whiteley, Guide to Scientific Computing in C++,
Chapter 5

T. B. Nguyen Object-Oriented Programming 11 October 2024 77 / 77

You might also like