You are on page 1of 219

Faculty of

Engineering Technology

Programming in Engineering
2018

Thomas Weinhart, Anthony Thornton,


Wouter den Otter, Deepak Tunuguntla, Kit Windows-Yule,
Katja Bertoldi, Holger Steeb and Stefan Luding

edition: 2018
Contents

Contents i

Preface ix

Acknowledgement ix

History x

Preliminaries xii

A MATLAB 1

1 Getting started with Matlab 2

1.1 Input via the command-line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2 help-facilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3 Interrupting a command or program . . . . . . . . . . . . . . . . . . . . . . . . 6

1.4 Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.5 Workspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.6 Saving and loading data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2 Basic syntax and variables 10

2.1 Matlab as a calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.1.1 An introduction to floating-point numbers . . . . . . . . . . . . . . . . . 11

–i–
Contents ii

2.1.2 Assignments and variables . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.2 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3 Mathematics with vectors and matrices 16

3.1 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.1.1 Row vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.1.2 Colon notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.1.3 Extracting and appending parts of a vector . . . . . . . . . . . . . . . . 18

3.1.4 Column vectors and transposing . . . . . . . . . . . . . . . . . . . . . . 19

3.1.5 Products, divisions and powers of vectors . . . . . . . . . . . . . . . . . 20

3.2 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.2.1 Special matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.2.2 Building matrices and extracting parts of matrices . . . . . . . . . . . . 24

3.2.3 Matrix operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.3 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3.4 Appendix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4 Scripts 35

4.1 Script m-files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.2 Creating and running a script . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.3 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5 Control flow 37

5.1 Logical and relational operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5.1.1 Logical indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

5.1.2 The find command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5.2 Conditional code execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.2.1 Using if ... elseif ... else ... end . . . . . . . . . . . . . . . 42

5.2.2 Using switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5.3 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

5.4 Comments on logical and relational expressions . . . . . . . . . . . . . . . . . . 47


Contents iii

6 Functions 50

6.1 Function m-file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

6.2 Local and global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.3 Subfunctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6.4 Nested functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6.5 Special function variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

6.6 Indirect function evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

6.7 Scripts versus functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

7 Cell arrays and structures 60

7.1 Cell arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

7.2 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

7.3 Object handles and the internal set and get functions . . . . . . . . . . . . . . 63

7.3.1 Parents and children . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

8 File input/output operations 68

8.1 Formatted files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

8.1.1 Writing formatted files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

8.1.2 Reading formatted files . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

8.2 Excel files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

9 Writing and debugging Matlab programs 72

9.1 Structural programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

9.2 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

9.3 Recommended programming style . . . . . . . . . . . . . . . . . . . . . . . . . . 76

9.4 Commenting and publishing in MATLAB . . . . . . . . . . . . . . . . . . . . . 77

9.4.1 Publishing Matlab code . . . . . . . . . . . . . . . . . . . . . . . . . . 77

10 Matlab and execution speed 78

10.1 Vectorizing your code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78


Contents iv

10.2 Pre-allocation of arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

11 Visualisation 80

11.1 2D plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

11.2 Several functions in one figure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

11.3 Adding text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

11.4 Changing the axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

11.5 Fine-tuning plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

11.6 Saving graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

11.7 Exporting graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

11.8 Plotting surfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

11.9 3D line plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

11.10Animations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

11.11Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

12 Numerical analysis 90

12.1 Differentiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

12.2 Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

12.2.1 Matlab commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

12.3 Solving differential equations - the ODE toolbox . . . . . . . . . . . . . . . . . 93

12.3.1 First order ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

12.3.2 Systems of ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

12.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

13 Symbolic computation 98

13.1 Symbolic objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

13.2 Solving symbolic expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

13.3 Matrix and and vector operations . . . . . . . . . . . . . . . . . . . . . . . . . . 100

13.4 Differentiation and integration . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

13.5 Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

13.6 Solving ordinary differential equations . . . . . . . . . . . . . . . . . . . . . . . 103


Contents v

13.7 Summations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

13.8 Symbolic substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

B C++ 106

14 Introduction to C++ 107

14.1 Objective of the course . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

14.2 Installation of a C++ compiler/IDE . . . . . . . . . . . . . . . . . . . . . . . . 107

14.3 A short history of C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

14.4 Why use C++? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

15 Programming-style 110

15.1 Comments (see also §16.1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

15.2 Clear style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

16 The basics 112

16.1 Language Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

16.2 Hello World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

16.3 data types, Variables, Constants . . . . . . . . . . . . . . . . . . . . . . . . . . 114

16.3.1 Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

16.3.2 Basic data types and their declaration . . . . . . . . . . . . . . . . . . . 115

16.3.3 Type conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

16.3.4 Variable-attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

16.3.5 string type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

16.3.6 String stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

16.3.7 Life-time and position in memory . . . . . . . . . . . . . . . . . . . . . . 120

16.3.8 Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

16.4 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

16.4.1 Arithmetic operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

16.4.2 Assignment and increment operators . . . . . . . . . . . . . . . . . . . . 124


Contents vi

16.4.3 Comparison and logical operators . . . . . . . . . . . . . . . . . . . . . . 124

16.4.4 Further operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

16.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

17 Decision structures 128

17.1 The if-command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

17.2 The ternary ?: operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

17.3 switch-command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

18 Loop control structures 131

18.1 (do) while-loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

18.2 for-loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

18.3 break and continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

19 Functions and Operators 134

19.1 Transfer of arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

19.1.1 Example of passing by reference . . . . . . . . . . . . . . . . . . . . . . 136

19.2 Functions without arguments or return value – void . . . . . . . . . . . . . . . 137

19.3 Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

19.4 inline functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

19.5 Overloading of functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

19.6 Templated functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

20 Pointers, pointer-field duality, and references 141

20.1 Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141

20.1.1 Pointer to void . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

20.2 pointer-field duality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

20.3 Transfer of field-variables to functions . . . . . . . . . . . . . . . . . . . . . . . 145

20.4 Dynamical Memory Management . . . . . . . . . . . . . . . . . . . . . . . . . . 148

21 Object Oriented Programming I: Containers in the Standard Template Library 149

21.1 C++ standard classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149


Contents vii

21.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

21.3 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

21.4 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

21.5 Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

21.6 Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

21.6.1 Iterator operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

21.6.2 Iterator member functions . . . . . . . . . . . . . . . . . . . . . . . . . . 158

21.6.3 Declaring and using iterators . . . . . . . . . . . . . . . . . . . . . . . . 159

21.7 Range-Based for loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

22 Object Oriented Programming II: Creating New Classes 166

22.1 A simple OOP problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

22.2 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

22.3 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

22.4 C++ standard classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

22.5 STL vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

23 I/O (Input and Output) 175

23.1 Elementary functions of iostreams . . . . . . . . . . . . . . . . . . . . . . . . . 175

23.2 Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

23.3 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

24 Organisation implementation and header-files 180

24.1 Compiling and linking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

25 Functional Programming 183

25.1 Function Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

25.1.1 std::functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

25.2 Lambda Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189

25.2.1 An Introduction to Lambda Functions . . . . . . . . . . . . . . . . . . . 189

25.2.2 Lambdas in Action – Making a DIY CTRL+F . . . . . . . . . . . . . . 190


Contents viii

25.2.3 Summary of Capture Specifiers . . . . . . . . . . . . . . . . . . . . . . . 196

26 Literature and longer exercises 200

26.1 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

26.2 Longer exercises C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201


Contents ix

Preface
This manuscript contains short introductions to the interpreter language Matlab and the
object-oriented compiler language C++, including many small and large exercises.

The manuscript consists of two parts: The first part covers Matlab, the second part is an
introduction to C++. Both parts are self-contained, but cross-references and similarities are
highlighted. Therefore, students who are interested in self-study can begin either with the
Matlab or the C++ part. Within both parts you will find numerous small examples and
exercises. These can be used for self-evaluation. At the end of every chapter you will find
various larger exercises similar to the exercises of the final assignment.

Acknowledgement
This work includes material from “Programming in Engineering” by Stefan Luding, Holger
Steeb and Katja Bertoldi (all from the University of Twente) and “Introduction to Matlab”
by Elżbieta Pȩkalska (Delft University of Technology), with contributions from Hans Zwart,
Anthony Thornton, Thomas Weinhart, Deepak Tunuguntla, Kit Windows-Yule and Wouter den
Otter (all from the University of Twente). The respective authors have given us permission to
re-use their work.
Contents x

History
Version 1.0 The manuscript was compiled for the 10-day summer course Programming in
Engineering, July - 18 July 2008.

Version 1.1 Updated for self-study purposes, 3 September 2008

Version 1.2 Compiled for the 10-day summer course Programming in Engineering, 6 July-17
July 2009. This version also used for self-study program beginning 2 September
2009.

Version 1.3 Extended and updated by Stefan Luding and Anthony Thornton, for the 10-day
summer course Programming in Engineering 5 July - 18 July 2010. Short exercise
added to the C++ part. This version also will be used for self-study program
beginning 30 August 2010.

Version 1.4 More information on OOP added and other general improvements to both C++
and MATLAB part. Designed for use in the Summer school 2011 and for the self
study for 2011/12 academic year (Anthony Thornton).

Version 1.5 Even more information on OOP to C++ , details of handles added to MAT-
LAB part, and other general improvements to both C++ and MATLAB part.
Designed for use in the Summer school 2012 and for the self study for 2012/13
academic year (by Thomas Weinhart & Anthony Thornton).

Version 1.6 Script updated to reflect change of order. Now Matlab is taught before C++ (by
Anthony Thornton).

Version 1.7 C++ part updated: templates added, intro to STL added, various other sections
reworded and the whole documented was reordered to reflect the way it was
taught for summer 2013. This was used for the September 2013 and 2014 version
of the course (by Anthony Thornton).

Version 1.8 This will be used for the July 2015 version of the course by Deepak Tunuguntla,
Thomas Weinhart and Kit Windows-Yule. Matlab section has a general clean up
and the long exercises where removed (Deepak Tunuguntla).

Version 1.9 General update of Matlab section, including expanding sections on complex
numbers, find command, commenting, set and get functions, use of handles (in
particular ode solvers). Additionally new sections where added on nested func-
tions, code publishing, subs command and vectorising. (Anthony Thornton).
For C++, created a C++11 standard function section; this includes new infor-
mation on iterators and range-based for loops. Added new chapter on functional
programming, dealing with function pointers, std::functions and lambda func-
tions (Kit Windows-Yule). This version was used for the summer course 2016.

Version 1.10 Thorough revision of the Matlab section to make it more consistent and self-
contained, and up-to-date with the ever changing commands in Matlab (Wouter
den Otter). Various small updates implemented for the summer course starting
July 10, 2017 (Thomas Weinhart).

Version 1.11 Assorted minor revisions for the summer course starting July 9, 2018 (Wouter
den Otter and Anthony Thornton).
Contents xi
Contents xii

Preliminaries

Below you find a short list of basic definitions concerning computers and programming. Please
get acquainted with these keywords as they introduce key concepts needed in the coming sections:
• A bit (short for binary digit) is the smallest unit of information on a computer. A single
bit can hold only the value 0 (zero) or 1 (one). More meaningful information is obtained
by combining consecutive bits into larger units, such as bytes.
• A byte is a combination of 8 bits, capable of holding 28 = 256 distinct values. Floating
point numbers are stored in 8 bytes, strings use 1 byte per character. Memory is measured
in terms of kilobytes (1024 bytes), megabytes (1024 kB), and gigabytes (1024 MB).
• Binary system - a number system that has two digits only, 0 and 1. Computers are based
on this system because of their electrical nature (charged versus uncharged, current versus
no current). Similar to our decimal system, where each digit position represents a specific
power of 10, in the binary system each digit position represents a specific power of 2, with
the power increasing from right to left. Here is an example of a binary number (denoted
by the subscript 2) and its decimal representation (subscript 10):
101102 = 1 · 24 + 0 · 23 + 1 · 22 + 1 · 21 + 0 · 20 = 2210 = 2 · 101 + 2 · 100 .
• Data is information represented using symbols, e.g. numbers, words, signals or images.
• A command is an instruction to do a specific task.
• An algorithm is a sequence of instructions for the solution of a specific task in a finite
number of steps.
• A program is the implementation of an algorithm suitable for execution by a computer.
• A variable is a ‘container’ that can hold a value. For example, the expression x = 2*y
relates the variables x and y. Variables can represent numeric values like 25.5, characters
like ‘c’ or character strings like ‘Matlab’. Variables make programs more flexible. When
a program is executed, the variables are replaced with real data; for y = 4, the above
expression becomes x = 8. That is how a program can process different sets of data.
Every variable has a name (called the variable name) and a data type. A variable’s data
type indicates the sort of data that the variable can represent (see below).
• A constant is a container holding a value that never changes. It can be a numeric value,
a character or a string.
• A data type is a classification of the type of information. The basic data types are:
• integer: a whole number, i.e. a number that has no fractional part, e.g. 3.
• floating-point: a number with a decimal point, e.g. 3.5 or 1.2e–16 (= 1.2 ∗ 10−16 ).
• character: readable text character, e.g. ‘p’.
• A bug is an error in a program. Depending on the type of bug, is may cause the program
to stop running, not to run at all or to provide wrong results. Some bugs can be very
subtle and hard to find. The process of finding and removing bugs is called debugging.
• A file is a collection of data or information stored on an internal or external data storage
device (hard disk, USB stick, backup-tape). There are many different types of files: data
files, program files, text files etc.
• An ASCII file is a readable and editable plain text file, using the American Standard Code
for Information Interchange (ASCII).
• A binary file is a file stored in a computer-readable format, not meant to be human-
readable. All executable programs and most numeric data are stored in binary files.
Matlab creates binary files with the extensions ‘*.mat’ and ‘*.fig’.
Part A
MATLAB

–1–
Chapter 1
Getting started with Matlab

Matlab is a tool for performing or executing mathematical (technical) calculations. Besides


its usage as a scientific calculator, it also allows you to plot or visualise data in several pos-
sible ways. In addition, it allows for complex matrix manipulations, polynomial operations,
differentiation and integration of functions and many more useful features essential for our
problem analysis. Like in a programmable calculator, you can create, execute and save a
sequence of commands in order to make your computational process automatic and repeat-
able. It can be used to store or retrieve data. In summary, Matlab can also be treated as
a user-friendly programming language, which gives the possibility to handle mathematical cal-
culations in an easy way. As a computing/programming environment, Matlab is especially
designed to work with data sets as a whole such as vectors, matrices and images. Tools such
as, PRTOOLS (http://prtools.org), a toolbox for Pattern Recognition, and DIPIMAGE
(http://www.ph.tn.tudelft.nl/DIPlib/dipimage_1.html), a toolbox for Image Processing,
have been developed under Matlab.

Under Windows, you can start Matlab by double clicking on the Matlab icon that should
be on the desktop of your computer. On a unix system, type matlab at the command line.
Running Matlab creates one or more windows on your screen. The most important is the
Command Window , which is the place where you interact with Matlab, i.e. it is used to enter
commands and display text results. The string >> is the Matlab prompt (or EDU>> for the
Student Edition). When the Command Window is active, a cursor appears after the prompt,
indicating that Matlab is waiting for your command. Matlab responds by printing text in
the Command Window or by creating a Figure Window for graphics. To exit Matlab use
the command exit or quit. Control-C is a local abort which kills the current execution of a
command.

1.1 Input via the command-line

Matlab is an interactive system: commands followed by Enter are executed immediately. The

–2–
1.1. Input via the command-line 3

results are, if desired, displayed on screen. However, execution of a command will only be
possible if the command is typed according to the rules. Table 1.1 shows a list of commands
used to solve indicated mathematical equations. Below you find basic information to help you
starting with Matlab:

• Commands in Matlab are executed by pressing Enter or Return. The output will be
displayed on screen immediately. Try the following (hit Enter after the end of line):

>> 3 + 7.5
>> 18/4
>> 3 * 7

Note that spaces are not important in Matlab.


• The result of the last performed computation is ascribed to the variable ans, which is an
example of a Matlab built-in variable. It can be used in the subsequent command. For
instance:

>> 14/4
ans =
3.5000
>> ansˆ(−6)
ans =
5.4399e−04

5.4399e-04 is a computer notation of 5.4399 ∗ 10−4 (see ). Note that ans is always
overwritten by the last command that has no assignment.
• You can also define your own variables. To assign values to the variables a and b:

>> a = 14/4
a =
3.5000
>> b = aˆ(−6)
b =
5.4399e−04

Read Preliminaries to better understand the concept of variables. You will learn more on
Matlab variables in section 2.1.2. Not that the equals sign ‘=’ is best read as ‘becomes.’
• When a command is followed by a semicolon ’;’, the output is suppressed. Check the
difference between the following expressions:

>> x = 3 + 7.5
>> y = 3 + 7.5;

• It is possible combine multiple commands in a single line, by separating the commands by


commas (to display the output) or by semicolons (to suppress the output display), e.g.:

>> sin(pi/4), cos(pi); sin(0)


ans =
0.7071
ans =
0

Note that the value of cos(pi) is not printed.


• By default, Matlab displays floating point numbers using 4 decimals. and format long
increases this number to 15, format short reduces it to 4 again. For instance:
1.1. Input via the command-line 4

> 312/56
ans =
5.5714
>> format long
>> 312/56
ans =
5.57142857142857

• The output may contain some empty lines; this can be suppressed by the command format
compact. In contrast, the command format loose will insert extra empty lines.
• To enter a statement that is too long to be typed in one line, use three periods ’...’
followed by Enter or Return. For instance:

>> sin(1) + sin(2) − sin(3) + sin(4) − sin(5) + sin(6) − ...


sin(8) + sin(9) − sin(10) + sin(11) − sin(12)
ans =
1.0357

• Matlab is case sensitive, hence a and A are two distinct variables.


• All text after a percent sign % until the end of a line is treated as a comment. Enter e.g.
the following:

>> sin(3.14159) % this is an approximation of sin(pi)

You will notice that some examples in this text are followed by comments. They are meant
for you and you should skip them while typing.
• Previous commands can be retrieved with the ↑ -key. The command can also be changed;
the ← and → -keys may be used to move around in a line and edit it.
• To recall the most recent command line starting with e.g. c, type c at the prompt followed
by the ↑ -key. Similarly, cos followed by the ↑ -key will retrieve the last command-line
starting with cos.
• Use the tab key for automated completion of commands and variable names; try for
instance shou<tab> and sho<tab> and see what happens.
• The command window is cleared by typing clc.

Since Matlab executes the command immediately, it might be useful to have an idea of the
expected outcome. You might be surprised how long it takes to print out a 1000 × 1000 matrix!
1.2. help-facilities 5

Mathematical notation Matlab command


a+b a + b
a−b a - b
ab a * b
a
b a / b or b \ a
xb x^b

x sqrt(x) or x^0.5
|x| abs(x)
π pi
4 ·√103 4e3 or 4*10^3
i( −1) i or j or 1i or 1j
3 − 4i 3-4*i or 3-4j
e, ex exp(1), exp(x)
ln x, log x log(x), log10(x)
sin x, arctan x, ... sin(x), atan(x),...
Table 1.1: Mathematical notation and the corresponding commands in Matlab (where a, b,
x and y are numbers).

1.2 help-facilities

There are several ways for getting help with MATLAB. A good way to start is to press the
‘Help’ button to type:

>> doc

The doc command opens an HTML document, which contains the Matlab reference book. This
is quite a large document! Useful sections for beginners include Getting Started and Matlab
Functions. You might want to browse them before beginning your first session. Its helpful to
keep this browser window open while you are working with Matlab, so that you can refer to it
easily.
There are other ways of getting help with Matlab that do not make you search through the
whole reference book. If you already know the name of a Matlab function, for example, quit,
and you want to learn about its use, enter:

>> help quit

You will see a description of the command quit. You can also open the help in a browser window
using doc quit. During your first experiences with Matlab you can from time to time take a:

>> demo

session which will show you various features of Matlab. Another very useful feature is the
lookfor command. It looks for all the commands related to a given topic (which can make it
very slow). Try:
1.3. Interrupting a command or program 6

>> lookfor 'help'

It will list all of the commands we just discussed.

Besides the inherent help of Matlab, you will find various online courses and references in the
internet and, last but not least, textbooks. Here, we just mention a view:
Online sources

• Matlab home page (from manufacturers)


http://www.mathworks.com

• Matlab online course (TU Eindhoven)


http://www.imc.tue.nl

• Matlab online Reference Documentation


http://www.math.ufl.edu/help/matlab/ReferenceTOC.html

Books and others references

• Matlab An Introduction with Applications, Amos Gilat, 2008.

• Matlab Programming for Engineers, Stephen Chapman, 2007.

• Essential Matlab for Engineers and Scientists, Brian Hahn and Dan Valentine, 2007.

1.3 Interrupting a command or program

Sometimes you might spot an error in your command or program. Due to this error it can
happen that the command or program does not stop. Pressing Ctrl-C (or Ctrl-Break on PC)
forces Matlab to stop the process. Sometimes, however, you may need to press a few times.
After this the Matlab prompt (>>) re-appears. This may take a while, though.

1.4 Path

The Matlab ‘path’ is a list of directories that tells Matlab where to find relevant m-files. When-
ever you enter a command, Matlab searches the directories in the path until it comes across an
m-file with the same name (plus the .m extension) and then executes that procedure. Basically,
the path defines the universe in which Matlab is working at a given time.

A few technical notes: when you enter something in the command line, Matlab actually begins
by looking for a variable of the given name, then for an m-file in the current directory, and only
then does it search in its path. Hence, if the current directory contains an m-file whose name
matches the requested command, Matlab executes that m-file and never enters the path. The
type of m-file is irrelevant to the search procedure: Matlab executes the first match it finds,
1.5. Workspace 7

regardless of whether it contains a script, function or an object method. Finally, you should
never use variables and functions (described in the following chapters) of the same name.

To display or modify the path, use the path, addpath and rmpath functions. One may also click
on the Set Path button in the ‘environment’ segment under the ‘home’ tab.

Why does it matter? Proper path management is essential to ensure smooth running code. In
order to invoke any code, its m-file must be in one of the directories contained in the path.
Calling a procedure that is stored outside of the path will result in errors. A bit more subtly,
the order in which directories appear in the path can affect how your code functions. If you
ever create two functions with the same definitions (called overloading), then Matlab will call
whichever one it encounters first. Users often overload standard toolbox functions with (slight)
modifications of their own. Overloading functions requires that you be very careful in defining
your Matlab path.

The current working directory is resolved by typing pwd, while cd is used to change the working
directory. The contents of the working directory is listed by dir or ls.

Exercise 1.1.
Type path to check which directories are placed on your path. Add you personal directory to
the path (assuming that you created your personal directory for working with Matlab). 

1.5 Workspace

All variables you create in the Command Windows are stored in Matlab’s workspace. All
variables contained in your workspace can be listed with the command who. The command whos
provides additional information on the number of allocated bytes and the class of all variables.
For example, assuming that you performed all commands from section 1.1, after typing who you
should get the following information:

>> who
Your variables are:
a ans b x

The command clear <name> deletes the variable <name> from the Matlab workspace, clear
or clear all removes all variables. This is useful when starting a new exercise. For example:

>> clear a x
>> who
Your variables are:
ans b

Note that you cannot use comma after a variable, i.e. clear a, x, as it will be interpreted in
Matlab as clear a and print x on the screen. See what is the result of:

>> clear all


>> a = 1; b = 2; c = 3;
>> clear a, b, c
1.6. Saving and loading data 8

>> clear b c

Matlab also offers a separate window to display the contents of its workspace (in the ’home’
tab, click ’layout’ and select ’workspace’). Try what happens when you double-click on a variable
name.

1.6 Saving and loading data

The easiest way to save or load Matlab variables is by clicking the Save Workspace or the
Open button, respectively. Also Matlab commands exist which save data to files and which
load data from files.

The command save allows for saving your workspace variables either in a binary file or an
ASCII file (check the ‘Preliminaries’ for the differences). Binary files automatically get the
‘.mat’ extension. There is no automatic extension to ASCII files, so it is recommended to add
the extension ‘.txt’ or ‘.dat’ by hand.

Exercise 1.2.
Learn how to use the save command by exercising:

>> clear all


>> s1 = sin(pi/4);
>> c1 = cos(pi/4); c2 = cos(pi/2);
>> str = 'hello world'; % this is a string
>> save % saves all variables in binary format to
% matlab.mat
>> save data % saves all variables in binary format to data.mat
>> save numdata s1 c1 % saves numeric variables s1 and c1 to numdata.mat
>> save strdata str % saves a string variable str to strdata.mat
>> save allcos.dat c* −ascii % saves c1,c2 in 8−digit ascii format to
% allcos.dat

The load command allows for loading variables into the workspace. It uses the same syntax as
save.

Exercise 1.3.
Assuming that you have done the previous exercise, try to load variables from the created files.
Before each load command, clear the workspace and after loading check which variables are
present in the workspace (use who).

>> load % loads all variables from the file matlab.mat


>> load data s1 c1 % loads only specified variables from the file
% data.mat
>> load strdata % loads all variables from the file strdata.mat

It is also possible to read ASCII files that contain rows of space separated values. Such a file
may contain comments that begin with a percent character. The resulting data is placed into a
1.7. Exercises 9

variable with the same name as the ASCII file (without the extension). Check, for example:

>> load allcos.dat % loads data from allcos.dat into variable allcos
>> who % lists variables present in the workspace now

1.7 Exercises

Exercise 1.4.

• Is the inverse cosine function, known as cos−1 or arccos, one of Matlab’s elementary
functions?
• Does Matlab have a mathematical function to calculate the greatest common divisor?
• Look for information on how to compute logarithms; what is the syntax for ln(a), log10 (a),
log2 (a)?

Use help or lookfor to find out. 


Chapter 2
Basic syntax and variables

2.1 Matlab as a calculator

There are three kinds of numbers used in Matlab: integers, real numbers and complex numbers.
In addition, Matlab has representations of the non-numbers: Inf, for positive infinity, gener-
ated e.g. by 1/0, and NaN, Not-a-Number, obtained as a result of the mathematically undefined
operations such as 0/0 or ∞ - ∞.

You have already got some experience with Matlab and you know that it can be used as a
calculator. To do that you can, for example, simply type:

>> (23*17)/7

The result will be:

ans =
55.8571

Matlab has six basic arithmetic operations, such as: +, -, *, / or \ (right and left divisions)
and ^ (power). Note that the two division operators are different (especially for matrices, as we
will see later):

>> 19/3 % mathematically: 19/3


ans =
6.3333
>> 19\3, 3/19 % mathematically: 3/19
ans =
0.1579
ans =
0.1579

Basic built-in functions, trigonometric, exponential, etc, are available for a user. Try help

– 10 –
2.1. Matlab as a calculator 11

elfun to get the list of elementary functions.

Exercise 2.1.
Evaluate the following expressions by hand and use Matlab to check the answers. Note the
difference between the left and right divisors. Use help to learn more on commands rounding
numbers, such as: round, floor, ceil, etc.

• 2/2 ∗ 3 • 3^2/4
• 8 ∗ 5\4 • 3^2^3
• 8 ∗ (5\4) • 2 + round (6/9 + 3 ∗ 2)/2
• 7 − 5 ∗ 4\9 • 2 + floor (6/9 + 3 ∗ 2)/2
• 6 − 2/5 + 7^2 − 1 • 2 + ceil (6/9 + 3 ∗ 2)/2
• 10/2\5 − 3 + 2 ∗ 4 • x = pi/3, x = x − 1, x = x + 5, x = abs(x)/x

intermezzo

2.1.1 An introduction to floating-point numbers

In a computer, numbers can be represented only in a discrete form. This means that numbers
are stored within a limited range and with a finite precision. Integers can be represented exactly
with the base of 2 (read Preliminaries on bits and the binary system). The typical size of an
integer is 32 bits, in which case the largest storable positive integer 232 = 4294967296. If negative
integers are permitted, then 32 bits allow for storage of integers between intmax(’int32’) =
2147483647 and intmin(’int32’) = -2147483648. Within this range, operations defined on
the set of integers can be performed exactly. Be prepared for unexpected behaviour when using
integers outside their range of validity (try: i = intmax(’int8’), i = i + 1 ).

However, this is not valid for other real numbers. In practice, computers are integer machines
and are capable of representing real numbers only by using complicated codes. The most popular
code is the floating point standard. The term floating point is derived from the fact that there
is no fixed number of digits before and after the decimal point, meaning that the decimal
point can float. Note that most floating-point numbers that a computer can represent are just
approximations. Therefore, care should be taken that these approximations lead to reasonable
results. If a programmer is not careful, small discrepancies in the approximations can cause
meaningless results. Note the difference between e.g. the integer arithmetic and floating-point
arithmetic:

Integer arithmetic: Floating-point arithmetic


2 + 4 = 6 18/7 = 2.5714
3 * 4 = 12 2.5714 * 7 = 17.9998
25/11 = 2 10000/3 = 3.3333e+03

Floating point numbers are often classified as single precision (32 bits) or double precision (64
bits). In binary form, floats are of the form ±1.xxxx ∗ 2±yy where every x in the fraction and
every y in the exponent is either 0 or 1. The fraction and exponent (and their signs) are stored
2.1. Matlab as a calculator 12

together in 32 (or 64) bits. In practice, switching from 32 to 64 bits increases not only the size
of the fraction – to store numbers more accurately – but also increases the size of the exponent
– to widen the range of stored numbers to both larger and smaller (i.e. closer to zero) values.

The relative accuracy might be defined as the smallest positive number ǫ that, when added to 1,
creates a numerical result larger than 1, i.e. 1 + ǫ > 1. In floating-point arithmetic, for positive
values δ smaller than ǫ, the result of 1 + δ equals 1 (whereas in exact arithmetic, of course, the
result is always larger than 1). In Matlab, the value of ǫ is stored in the built-in variable eps
≈ 2.2204e − 16. This value implies that the relative accuracy of individual arithmetic operations
is about 15 digits.

Matlab relies on your computer’s floating point arithmetic. You could have noticed that in the
last exercise, where the value of sin(pi) was almost zero but not completely zero. This stems
from the value of π being represented by pi with a finite precision, as well as from the function
sin being evaluated with a finite precision.

The fundamental type in Matlab is double, which stands for a representation with a double
precision, i.e. using 64 bits. The single precision obtained by using the single type offers 32
bits. Since most numeric operations require high accuracy, the double type is used by default.
Even when the user is inputting integer values in Matlab, e.g. k = 4, the data is still stored
in the double format (unless the user explicitly requests integers, e.g. k = int32(4)).
end intermezzo

2.1.2 Assignments and variables

Assigning variables in Matlab is easy. Consider the code below

>> i=4;
>> x=2.5;

It assigns 4 to the variable i and 2.5 to variable x.

Complex numbers in Matlab

Working with complex numbers is easily done with Matlab. There are two ways to declare a
complex number

>> z1 = complex(3,4)
>> z2 = 3+4i;

Note that i and j are often used as a loop counters and thereby loose their special values.
Consider the code

>> i
>> z1 = 3+4*i
2.1. Matlab as a calculator 13

>> i = 4
>> z2 = 3+4*i
>> z3 = 3+4i


Note that only without the multiplication sign in front do i and j always equal −1. Be warned
that redefining i and/or j is an easy mistake to make... The problem with redefinition of internal
variables and internal functions can occur in many ways. Consider the code.

>> quit = 1;
>> quit

More examples of this type will be discussed below.

Exercise 2.2.
Choose two complex numbers, for example -3 + 2i and 5 - 7i. Add, subtract, multiply, and
divide these two numbers. 

During this exercise, the complex numbers had to be typed four times. To reduce this, assign
each number to a variable. For the previous exercise, this results in:

>> z = −3 + 2*i; w = 5 − 7*i;


>> y1 = z + w; y2 = z − w;
>> y3 = z * w;
>> y4 = z / w; y5 = w \ z;

Formally, there is no need to declare (i.e. define the name, size and type of) a new variable
in Matlab. A variable is simply created by an assignment, e.g. z = -3 + 2*i. Each newly
created numerical variable is always of the double type, i.e. real numbers are approximated
with the highest possible precision. You can change the type by converting to e.g. the single
type.1 In some cases, e.g. when handling huge matrices occupying large amounts of memory
(and precision is not very important), this might be a way to proceed. Also, when only integers
are requires, it might be useful to convert from the double representations to an integer type,
e.g. int32. Note that integer numbers are represented exactly, no matter which integer type is
being used, as long as its value lies within the range of the integer type.

Bear in mind that undefined values can not be assigned to variables. So, the following is not
possible:

>> clear x; % to make sure that x does not exist


>> f = xˆ2 + 4 * sin(x)

It becomes possible by:

>> x = pi / 3; f = xˆ2 + 4 * sin(x)

Variable names begin with a letter, followed by zero or more letters, numbers or underscores.
Matlab recognizes only the first 63 characters of a name.
1
A variable a is converted into a different type by performing e.g. a = single(a) or a = int32(a). Note
that Matlab all too eagerly reverts your singles and integers back to the default doubles.
2.1. Matlab as a calculator 14

Exercise 2.3.
Here are some examples of different types of Matlab variables. You do not need to understand
them all now, since you will learn more about them during the course. Create them manually
in Matlab:

>> this is my very simple variable today = 5 % check what happens; the name is
% very long
>> 2t = 8 % What are the problems here?
>> M = [1 2; 3 4; 5 6] % a matrix
>> c = 'E' % a character
>> str = 'Hello world' % a string
>> m = ['J','o','h','n'] % Can you guess what this is?

Check the types by using the command whos. Use clear <name> to remove a variable from the
workspace. 

As you already know, Matlab variables can be created by an assignment. There are also a
number of built-in variables, e.g. pi, eps and i, summarized in Table 2.1. In addition to creating
variables by assigning values to them, another possibility is to copy one variable, e.g. b, into
another, e.g. a. In this way, the variable a is automatically created (if a already existed, its
previous value and type are lost):

>> b = 10.5;
>> a = b;

A variable can also be created by the evaluation of an expression,

>> a = 10.5; c = aˆ2 + sin(pi*a)/4;

or by loading data from text or ‘*.mat’ files.

If min is the name of a function (see help min), then a defined as:

>> b = 5; c = 7;
>> a = min (b,c); % create a as the minimum of b and c

will call that function, with the values b and c as parameters, and the result of this function
(its return value) will be written (assigned) into a. So, variables can be created as results of
the execution of built-in or user-defined functions (you will learn more how to built your own
functions in section 6.1).

Important: do not define variables with names that are already in use as function names (for
instance mean or error) or as built-in variable names,2 because from this point on you cannot
access the function or built-in variable anymore. For example, try

>> mean([4 6])


ans =
2
There is always one √exception √to the rule: the variables i and j are often used as counters in loops, while
they are also used as i = −1, j = −1. As mentioned before, use 1i and 1j to ensure that you are dealing with
the imaginary unit.
2.2. Exercises 15

5
>> mean=3
mean =
3
>> mean([4 6])
??? Index exceeds matrix dimensions.

At the second calling, mean is a variable rather than the function mean. Note that Matlab does
not warn you of potential conflicts.

If you are going to use a suspicious variable name, use help <name> to find out if the name is
already in use.

Variable name Value/meaning


ans the default variable name used for storing the last result
pi π = 3.14159...
eps the smallest positive number that added to 1 makes a result larger than
1
inf representation for positive infinity, e.g. 1/0
nan or NaN representation
√ for not-a-number, e.g. 0/0
i or j i = j = −1 (Note: better use 1i in case the variable i is used)
nargin/nargout number of function input/output arguments used
realmin/realmax the smallest/largest usable positive real number:
1.7977e+308 / 2.2251e−308

Table 2.1: Built-in variables in Matlab.

2.2 Exercises

Exercise 2.4.
Define the format in Matlab such that empty lines are suppressed and the output is given with
15 digits. Calculate:

>> pi
>> sin(pi)

Note that the answer is not exactly 0. Use the command format to put Matlab in its standard-
format. 
Chapter 3
Mathematics with vectors and matrices

The basic element of Matlab is a two-dimensional matrix. Special cases are:

• a (1 × 1) matrix, i.e. a scalar or a single number;


• a (1 × n) matrix, i.e. a row vector;
• a (n × 1) matrix, i.e. a column vector.

Note that Matlab may behave differently depending on the input, whether it is a number, a
vector or a two-dimensional (or more-dimensional) matrix.

Readers not familiar with vectors and matrices are advised to read the appendix at the end of
this chapter before continuing.

3.1 Vectors

3.1.1 Row vectors

Row vectors are lists, bracketed by [ ], of numbers separated either by commas or spaces.
They are examples of simple arrays. Their entities are referred to as elements or components.
In Matlab the first element always has index 1. The number of entries is known as the length
of the vector, as returned by the command length.

>> v = [−1 sin(3) 7]


v =
−1.0000 0.1411 7.0000
>> length(v)
ans =
3

– 16 –
3.1. Vectors 17

A number of operations can be done on vectors. A vector can be multiplied by a scalar, or


added/subtracted to/from another vector with the same length, or a number can be added/-
subtracted to/from every element in a vector. All these operations are carried out element-by-
element. Vectors can also be built from already existing vectors.

>> v = [−1 2 7]; w = [2 3 4];


>> z = v + w % an element−by−element sum
z =
1 5 11
>> vv = v + 2 % add 2 to all elements of vector v
vv =
1 4 9
>> t = [2*v, −w]
ans =
−2 4 14 −2 −3 −4

To display or change a particular element,

>> v(2) = −1 % change the 2nd element of v


v =
−1 −1 7
>> w(2) % display the 2nd element of w
ans =
3

Note that this requires rounded brackets.

3.1.2 Colon notation

Colon notation is an useful shortcut, used when producing row vectors (see Table 3.1 and help
colon):

>> 2:5
ans =
2 3 4 5
>> −2:3
ans =
−2 −1 0 1 2 3

In general, first:step:last produces a row vector of entities, starting with the value first,
incrementing by step, with the final value last (or the last increment before exceeding last).
The default step size is one.

>> 0.2:0.5:2.4
ans =
0.2000 0.7000 1.2000 1.7000 2.2000
>> 3:8 % default step size
ans =
3 4 5 6 7 8
>> −3:3:10
3.1. Vectors 18

ans =
−3 0 3 6 9
>> 1.5:−0.5:−0.5 % negative step is also possible
ans =
1.5000 1.0000 0.5000 0 −0.5000
>> 10:3:20 % last value is not part of the series
ans =
10 13 16 19

Given an array, one can easily evaluate a function for every element:

>> x = 1:9;
>> y = sqrt(x)
y =
1.0000 1.4142 1.7321 2.0000 2.2361 2.4495 2.6458 2.8284 3.0000

3.1.3 Extracting and appending parts of a vector

Parts of vectors can be extracted by using colon notation:

>> r = [−1:2:6, 2, 3, −2] % −1:2:6 => −1 1 3 5


r =
−1 1 3 5 2 3 −2
>> r(3:6) % get elements 3 through 6 (inclusive) of r
ans =
3 5 2 3
>> r(1:2:5) % get elements 1, 3 and 5 of r
ans =
−1 3 2
>> r(5:−1:2) % What will you get here?

Matlab allocates memory for all variables on the fly. This allows you to increase the size of a
vector simply by assigning a value to an element exceeding the current range.

>> x = linspace(21,25,5) % create 5 equidistant values from 21 to 25


x =
21 22 23 24 25
>> x(8)
Index exceeds matrix dimensions.
>> x(8) = −9
x =
21 22 23 24 25 0 0 −9

In the last line the array size is extended from 5 to 8, element 8 is assigned the value -9, and the
elements intermediate between 5 and 8 are set to zero. Note that this easy approach to resizing
arrays might appear user-friendly, but it complicates the tracking of out-of-range errors. When
working with steadily growing arrays, the repeated resizing becomes a time consuming business;
it is therefore recommended to directly define arrays with their intended maximum sizes.
3.1. Vectors 19

3.1.4 Column vectors and transposing

To create column vectors, you should separate entries by new lines or semicolons ’;’:

>> z = [1
7
7];
z =
1
7
7
>> u = [−1; 3; 5]
u =
−1
3
5

The operations applied to row vectors can be applied to column vectors as well. You can not,
however, add a column vector to a row vector (which also makes no sense mathematically). To
’add’ a column vector to a row vector (of the same length) or vice versa, you need an operation
called transposing which converts a column vector into a row vector or vice versa:

>> transpose(u) % u is a column vector, transposing yields a row


ans =
−1 3 5
>> u' % prime as (potentially dangerous) short−hand
ans =
−1 3 5
>> v = [−1 2 7]; % v is a row vector
>> u + v % you can not add a column vector to a row vector
Matrix dimensions must agree.
>> u' + v
ans =
−2 5 12
>> u + v'
ans =
−2
5
12

For a complex vector z, the shorthand z’ returns the conjugate transpose. For instance:

>> z = [1+2i, −1+i]


z =
1.0000 + 2.0000i −1.0000 + 1.0000i
>> transpose(z) % the transpose
ans =
1.0000 + 2.0000i
−1.0000 + 1.0000i
>> z' % the conjugate transpose
ans =
1.0000 − 2.0000i
−1.0000 − 1.0000i
>> z.' % shorthand transpose
ans =
1.0000 + 2.0000i
3.1. Vectors 20

−1.0000 + 1.0000i

3.1.5 Products, divisions and powers of vectors

You can now compute the inner product (a.k.a. dot product) of two vectors x and y of the same
length, x · y, in a simple way:

>> u = [−1; 3; 5] % a column vector


>> v = [−1; 2; 7] % a column vector
>> u * v % you can not multiply a column vector
% by a column vector
Error using *
Inner matrix dimensions must agree.
>> u' * v % this is the inner product
ans =
42
>> dot(u,v) % this is also the inner product
ans =
42

Given two vectors x and y of the same length n, an element-wise multiplication yields a vector
with elements x1 y1 , x2 y2 , . . . , xn yn . For instance:

>> u .* v % this is an element−by−element multiplication


1
6
35
>> sum(u.*v) % yet another way to compute the inner product
ans =
42
>> z = [4 3 1]; % z is a row vector
>> sum(u'.*z) % this is the inner product
ans =
10
>> u'*z' % and this is the inner product
ans =
10
>> z*u % and this is the inner product
ans =
10

Try what happens for u*v’, u’.*v, u*z and u.*z; the result is known as the dyadic product.

Mathematically, the division of one vector by another vector is an undefined operation. In


Matlab, however, the operator ./ is introduced to perform an element-wise division for vectors
of the same size and type:

>> x = 2:2:10
x =
2 4 6 8 10
>> y = 6:10
y =
6 7 8 9 10
>> x./y
3.2. Matrices 21

ans =
0.3333 0.5714 0.7500 0.8889 1.0000
>> z = −1:3
z =
−1 0 1 2 3
>> x./z % division 4/0, resulting in infinity
Warning: Divide by zero. % recent versions of matlab do not warn :−(
ans =
−2.0000 Inf 6.0000 4.0000 3.3333
>> z./z % division 0/0, resulting in 'not any number'
Warning: Divide by zero.
ans =
1 NaN 1 1 1

The operator ./ can also be used to divide a scalar by a vector:

>> x=1:5; 2/x % this is not possible


Error using /
Matrix dimensions must agree.
>> 2./x % but this is!
ans =
2.0000 1.0000 0.6667 0.5000 0.4000

Exercise 3.1.

Get acquainted with operations on row and column vectors. Perform, for instance:
• Create a vector consisting of the even numbers between 21 and 47.
• Let x = [4 5 9 6].
– Subtract 3 from each element.
– Add 11 to the odd-index elements.
– Compute the square root of each element.
– Raise each element to the power 3.
• Create a vector x with the elements:
– 2, 4, 6, 8, ..., 16;
– 9, 7, 5, 3, 1, −1, −3, −5.
• Given x = [2 1 3 7 9 4 6], explain what the following commands do:
– x (3) – x (1:end-1) – x (:)
– x (1:7) – x (2:2:6) – sum(x)
– x (end) – x (6:-2:1) – mean(x)
– x (1:end) – x (end/2:-3:2) – min(x)


3.2 Matrices

Row and column vectors are special types of matrices. An (n × k) matrix is a rectangular
collection of numbers having n rows and k columns. Defining a matrix in Matlab is similar
to defining a vector. The generalisation is straightforward once you appreciate that a matrix is
a column of row vectors or a row of column vectors. Like before, commas or spaces are used
to separate elements in a row, and semicolons are used to separate elements in a column. For
example,
3.2. Matrices 22

>> A = [1 2 3 ; 4 5 6 ; 7 8 9] % row by row input


A =
1 2 3
4 5 6
7 8 9
>> B = [ [ 1 ; 4 ; 7 ] [ 2 ; 5 ; 8 ] [ 3 ; 6 ; 9 ] ] % column by column
B =
1 2 3
4 5 6
7 8 9

Other examples are, for instance:

>> A2 = [1:4; −1:2:5]


A2 =
1 2 3 4
−1 1 3 5
>> A3 = [1 3
−4 7]
A3 =
1 3
−4 7

Conversely, a row vector is a (1×k) matrix and a column vector is an (n×1) matrix. Transposing
a vector changes it from a row to a column or the other way round. For a matrix, the transpose
operation interchanges the rows with the corresponding columns, as in the example:

>> A2
A2 =
1 2 3 4
−1 1 3 5

>> A2' % transpose of A2


ans =
1 −1
2 1
3 3
4 5
>> size(A2) % returns the size (dimensions) of A2:
% 2 rows and 4 columns
ans =
2 4
>> size(A2')
ans =
4 2

Command Result
A(i,j) Aij
A(:,j) j-th column of A
A(i,:) i-th row of A
A(k:l,m:n) ((l − k + 1) × (n − m + 1)) matrix with elements Aij for k ≤ i ≤ l, m ≤ j ≤ n
A(isnan(A)) functions like isnan return a logical (boolean) array; see section 5.1.1
v(i:j) ’vector-part’ (vi , vi+1 , . . . , vj ) of vector v

Table 3.1: Manipulation of (groups of) matrix elements.


3.2. Matrices 23

Command Result
n = rank(A) n becomes the rank of matrix A
x = det(A) x becomes the determinant of matrix A
x = size(A) x becomes a row-vector with 2 elements: the number of rows and columns of A
x = trace(A) x becomes the trace (sum of diagonal elements) of matrix A
x = norm(v) x becomes the Euclidean length of vector v
C = A + B sum of two matrices
C = A - B subtraction of two matrices
C = A * B multiplication of two matrices
C = A .* B ’element-by-element’ multiplication (A and B are of equal size)
C = A^k power of a matrix (k ∈ Z; can also be used for A−1 )
C = A.^k ’element-by-element’ power of a matrix
C = A’ the conjugate transpose of a matrix; A∗
C = A.’ the transpose of a matrix; AT
C = A ./ B ’element-by-element’ division (A and B are of equal size)
X = A \ B finds the solution in the least squares sense to the system of equations AX = B
X = B / A finds the solution of XA = B, analogous to the previous command
C = inv(A) C becomes the inverse of A
C = null(A) C is an orthonormal basis for the null space of A obtained from the singular
value decomposition
C = orth(A) C is an orthonormal basis for the range of A
L = eig(A) L is a vector containing the (possibly complex) eigenvalues of a square matrix A
[Q,L] = eig(A) produces a diagonal matrix L of eigenvalues and a full matrix Q whose columns
are the corresponding eigenvectors of a square matrix A
S = svd(A) S is a vector containing the singular values of a rectangular matrix A
[U,S,V] = svd(A) S is a diagonal matrix with nonnegative diagonal elements in decreasing order;
columns of U and V are the accompanying singular vectors of A
x = linspace(a,b,n) generates a vector x of n equally spaced points between a and b
x = logspace(a,b,n) generates a vector x starting at 10a and ended at 10b containing n values
A = eye(n) A is an (n × n) identity matrix
A = zeros(n,m) A is an (n × m) matrix with zeros (default m = n)
A = ones(n,m) A is an (n × m) matrix with ones (default m = n)
A = diag(v) results in a diagonal matrix with the elements v1 , v2 , . . . , vn on the diagonal
v = diag(A) results in a vector equivalent to the diagonal of A
X = tril(A) X is lower triangular part of A
X = triu(A) X is upper triangular part of A
A = rand(n,m) A is an (n × m) matrix of elements drawn from a uniform distribution on [0, 1]
A = randn(n,m) A is an (n × m) matrix of elements drawn from a standard normal distribution
spy(A) Plots the non-zero elements of A
v = max(A) v is a vector of the maximum values of the columns in A
v = max(A,[],dim) v is a vector of the maximum values along dimension dim in A (1=column, 2=rows)
B = max(A,x) elements in B equal the corresponding element(s) in A or x, whichever is bigger
v = min(A),
ditto - with minimum
v = min(A,[],dim)
v = sum(A),
ditto - with sum
v = sum(A,dim)

Table 3.2: Frequently used matrix operations and functions.


3.2. Matrices 24

3.2.1 Special matrices

There are a number of built-in commands to generate frequently used matrices with user-
specified sizes, see Table 3.2. A few examples are given below:

>> E = [] % an empty matrix of (0 x 0) elements!


E =
[]
>> size(E)
ans =
0 0
>> I = eye(3); % the (3 x 3) identity matrix
I =
1 0 0
0 1 0
0 0 1
>> r = [1 3 −2]; R = diag(r) % create a diagonal matrix with r on the diagonal
R =
1 0 0
0 3 0
0 0 −2
>> A = [1 2 3; 4 5 6; 7 8 9];
>> diag(A) % extracts the diagonal entries of A
ans =
1
5
9
>> B = ones(3,2)
B =
1 1
1 1
1 1
>> C = zeros (size(B')) % a matrix of all zeros of the size given by B'
C =
0 0 0
0 0 0
>> D = rand(2,3) % a matrix of random numbers; you will get a
% different one!
D =
0.0227 0.9101 0.9222
0.0299 0.0640 0.3309
>> v = linspace(1,2,4) % a vector is also an example of a matrix
v =
1.0000 1.3333 1.6667 2.0000

3.2.2 Building matrices and extracting parts of matrices

It is often useful to build a larger matrix from a number of smaller ones:

>> x = [4; −1], y = [−1 3]


x =
4
−1
y =
−1 3
>> X = [x y'] % X consists of the columns x and y'
3.2. Matrices 25

X =
4 −1
−1 3
>> T = [ −1 3 4; 4 5 6]; t = 1:3;
>> T = [T; t] % add to T a new row, namely the row vector t
T =
−1 3 4
4 5 6
1 2 3
>> G = [1 5; 4 5; 0 2]; % G is (3 x 2); check with size(G)
>> T2 = [T G] % join two matrices
T2 =
−1 3 4 1 5
4 5 6 4 5
1 2 3 0 2
>> T3 = [T; G ones(3,1)] % G is (3 x 2), T is (3 x 3)
T3 =
−1 3 4
4 5 6
1 2 3
1 5 1
4 5 1
0 2 1
>> T3 = [T; G']; % this is also possible
T3 =
−1 3 4
4 5 6
1 2 3
1 4 0
5 5 2
>> [G' diag(5:6); ones(3,2) T] % you can join many matrices
ans =
1 4 0 5 0
5 5 2 0 6
1 1 −1 3 4
1 1 4 5 6
1 1 1 2 3

A part of a matrix can be extracted from a matrix in a similar way as the extraction of parts
of vectors. Each element in a matrix is indexed by the row and column to which it belongs. In
mathematics the element in the i-th row and the j-th column of the matrix A is denoted as Aij ,
whereas Matlab uses the A(i,j) notation.

>> A = [1:3; 4:6; 7:9]


A =
1 2 3
4 5 6
7 8 9
>> A(1,2), A(2,3), A(3,1)
ans =
2
ans =
6
ans =
7
>> A(4,3) % this is not possible: A is a (3 x 3) matrix!
??? Index exceeds matrix dimensions.
>> A(2,3) = A(2,3) + 2*A(1,1) % change the value of A(2,3)
A =
1 2 3
3.2. Matrices 26

4 5 8
7 8 9

It is (too) easy to automatically extend the size of a matrix. For the matrix A above this can
be done e.g. as follows:

>> A(5,2) = 5 % assign 5 to the position (5,2); the uninitialized


A = % elements of A become zeros
1 2 3
4 5 8
7 8 9
0 0 0
0 5 0

The newly introduced zero-valued elements of the matrix can be assigned a value, e.g.

>> A(4,:) = [2, 1, 2]; % assign vector [2, 1, 2] to the 4th row of A
>> A(5,[1,3]) = [4, 4]; % assign: A(5,1) = 4 and A(5,3) = 4
>> A % what does the matrix A look like now?
A =
1 2 3
4 5 8
7 8 9
2 1 2
4 5 4

Different parts of the matrix A can now be extracted:

>> A(3,:) % extract the 3rd row of A


ans =
7 8 9
>> A(:,2) % extract the 2nd column of A
ans =
2
5
8
1
5
>> A(1:2,:) % extract the 1st and 2nd row of A
ans =
1 2 3
4 5 8
>> A([2,5],1:2) % extract a part of A
ans =
4 5
4 5

As you have seen in the examples above, it is possible to manipulate (groups of) matrix-elements.
The commands are summarized in Table 3.1.

The concept of an empty matrix [] is also very useful in Matlab. For instance, columns or
rows can be removed from a matrix by ‘filling’ them with an empty matrix. Try for example:

>> C = [1 2 3 4; 5 6 7 8; 1 1 1 1];
>> D = C; % the entire matrix C is copied to D
3.2. Matrices 27

>> D(:,2) = [] % remove the 2nd column


>> C ([1,3],:) = [] % remove rows 1 and 3

3.2.3 Matrix operations

Matrix-matrix multiplication are straightforward: use the multiplication sign, as in C = A * B,


and Matlab applies the usual rules of linear algebra,
X
Cij = Aip Bpj .
p

Keep in mind that this multiplication only works if the number of columns in A equals the
number of rows in B. The resulting matrix C contains the same number of rows as A and the
same number of columns as B.

>> b = [1 3 −2];
>> B = [1 −1 3; 4 0 7]
B =
1 −1 3
4 0 7
>> b * B % not possible: b is (1 x 3), B is (2 x 3)
??? Error using ==> *
Inner matrix dimensions must agree.

>> b * B' % ok: (1 x 3) * ( 3 x 2 ) −> (1 x 2)


ans =
−8 −10
>> B' * ones(2,1) % a (2 x 1) matrix filled with one−s
ans =
5
−1
10
>> C = [3 1; 1 −3];
>> C * B
ans =
7 −3 16
−11 −1 −18
>> Cˆ3 % this is equivalent to C*C*C
ans =
30 10
10 −30
>> ( ones(3,4) / 4 ) * diag(1:4)
ans =
0.2500 0.5000 0.7500 1.0000
0.2500 0.5000 0.7500 1.0000
0.2500 0.5000 0.7500 1.0000

Table 3.2 lists frequently used matrix operations and functions, including all usual manipulations
encountered in linear algebra.

The element-wise dot-operations, as discussed above for vectors, also work for matrices. A
couple of examples:

>> B = [1 −1 3; 4 0 7]
B =
3.3. Exercises 28

1 −1 3
4 0 7
>> B2 = [1 2; 5 1; 5 6];
>> B = B + B2 % add two matrices
Matrix dimensions must agree
>> B = B + B2' % add two matrices
B =
2 4 8
6 1 13
>> B−2 % subtract 2 from all elements of B
ans =
0 2 6
4 −1 11
>> ans = B/4 % divide all elements of the matrix B by 4
ans =
0.5000 1.0000 2.0000
1.5000 0.2500 3.2500
>> 4/B % this is not possible
Error using /
Matrix dimensions must agree.

>> 4./B % this is possible;


% equivalent to: 4*ones(size(B))./ B
ans =
2.0000 1.0000 0.5000
0.6667 4.0000 0.3077
>> C = [1 −1 4; 7 0 −1];
>> B .* C % multiply element−by−element
ans =
2 −4 32
42 0 −13
>> ans.ˆ3 − 2 % for all elements: raise to power 3 and subtract 2
ans =
6 −66 32766
74086 −2 −2199
>> ans ./ B.ˆ2 % element−by−element division by squared elements
ans =
1.0e+03 * % multiplication factor for all elements
0.0015 −0.0041 0.5120
2.0579 −0.0020 −0.0130

3.3 Exercises

Exercise 3.2.
Create a vector containing five elements such that the elements are equally spaced when you
take the logarithm of the vector. 

Exercise 3.3.
Perform the following exercises:

• Create a vector x with the elements:


– 1, 1/2, 1/3, 1/4, 1/5;
– 0, 1/2, 2/3, 3/4, 4/5.

Realize this by dividing a vector y by a vector z.


3.3. Exercises 29

(−1)n
• Create a vector x with the elements xn = for n = 1, 2, 3, ..., and determine the sum
2n − 1
of the 100-element vector (≈ −π/4).
• Given a vector x, provide the Matlab expressions that will return for all elements x:
– ln(2 + x + x2 )
– cos(x2 ) + sin(x2 )
– cos2 (x) + sin2 (x)
– ex (1 + cos(3x))
– arctan(x)

Test your expressions for x = 1:0.2:2.

Exercise 3.4.
Use the knowledge on computing the inner product to find:

qP
1. the Euclidean length of the vector x = (2, 1, 3, 7, 9, 4, 6), defined as |x| = ( i x2i ). Use
the Matlab command norm to verify your answer.
2. the angle between two vectors x and y, defined as α = arccos[(x · y)/(|x| |y|)]. Compute
the angles between the vectors
• x = (3,2,1) and y = (1,2,3),
• x = 1:5 and y = 6:10.

Exercise 3.5.
Define the matrix A = [1:4; 5:8; 1 1 1 1]. Predict and check the result of the following
operations (starting with the first column):

• x = A(:,3) • y = A(3:3,1:4)
• B = A(1:3,2:2) • A = [A; 2 1 7 7; 7 7 4 5]
• A(1,1) = 9 + A(2,3) • C = A([1,3],2)
• A(2:3,1:3) = [0 0 0; 0 0 0] • D = A([2,3,5],[1,3,4])
• A(2:3,1:2) = [1 1; 3 3] • D(2,:) = []

Exercise 3.6.
Define the matrices T = [ 3 4; 1 8; -4 3] and A = [diag(-1:2:3) T; -4 4 1 2 1]. Per-
form the following operations on the matrix A:

• extract a vector consisting of the 2nd and 4th elements of the 3rd row
• find the minimum of the 3rd column
• find the maximum of the 2nd row
• compute the sum of the 2nd column
• compute the mean of the 1st and 4th rows
• extract the submatrix consisting of the 1st and 3rd rows and all columns
3.3. Exercises 30

• extract the submatrix consisting of the 1st and 2nd rows and the 3rd, 4th and 5th columns
• compute the total sum of the 1st and 2nd rows
• add 3 to all elements of the 2nd and 3rd columns

Exercise 3.7.
Let A = [2 4 1; 6 7 2; 3 5 9]. Provide the commands that:

• assign the first row of A to a vector x;


• assign the last 2 rows of A to a vector y;
• add up the columns of A;
• add up the rows of A;

Exercise 3.8.
Let A = [2 7 9 7; 3 1 5 6; 8 1 2 5]. Explain the results of the following commands:

• A’ • fliplr (A) • sum (A,2)


• A(1,:)’ • [A A(end,:)] • mean (A,2)
• A(:,[1 4]) • [A; A(1:2,:)] • min (A)
• A([2 3], [3 1]) • sum (A) • max (A’)
• reshape (A,2,6) • sum (A’) • min (A(:,4))
• A(:) • mean (A) • [min(A)’ max(A)’]
• flipud (A) • mean (A’) • max (min(A))

• [ [A; sum (A)] [ sum (A,2); sum (A(:)) ] ]


• assign the even-numbered columns of A to an array B
• assign the odd-numbered rows to an array C
• convert A into a 4-by-3 array
• compute the reciprocal of each element of A
• compute the square-root of each element of A
• remove the second column of A
• add a row of all 1’s at the beginning and at the end
• swap the 2nd row and the last row

Exercise 3.9.
Given the vectors x = [1 3 7] and y = [2 4 2] and the matrices A = [3 1 6; 5 2 7] and
B = [1 4; 7 8; 2 2], determine which of the following statements can be correctly executed
(and if not, try to understand why not) and explain their results:
3.4. Appendix 31

• x + y • [x; y’] • B * A • B ./ x’
• x + A • [x; y] • A .* B • B ./ [x’ x’]
• x’ + y • A - 3 • A’ .* B • 2 / A
• A - [x’ y’] • A + B • 2 * B • ones(1,3) * A
• [x; y] + A • B’ + A • 2 .* B • ones(1,3) * B

Exercise 3.10.
Perform all operations from Table 3.2, using some matrices A and B, vector v and scalars k, a,
b, n, and m. 

Exercise 3.11.
Let A be a square 6-by-6 matrix.

1. Create a matrix B whose elements are the same as those of A except for the entries on the
main diagonal: the diagonal of B should consist of one-s.

2. Create a tridiagonal matrix T whose three diagonals are taken from the matrix A.
Hint: you may want to use the commands triu, tril and diag.

Exercise 3.12.
Let A be a random (5×5) matrix and let y be a random (5×1) vector. Given that Ax = y, solve
the vector x. Explain the difference between the operator \ (a.k.a. mldivide), the operator /,
and the command inv. Having found y, verify whether Ax − y is close to a zero vector. 

Exercise 3.13.
Let A by a 6 × 8 random matrix. Normalize the columns of the matrix so that all columns of
the resulting matrix, say B, have the Euclidean norm (length) equal to 1. Next, calculate the
angles between the consecutive columns of the matrix B. 

Exercise 3.14.
Try what happens upon entering a(3,3,3) = 1. 

3.4 Appendix

In a three-dimensional space, the position of a point relative to the origin is represented by


three numbers, the x, y and z coordinates of that point. A convenient way of collecting these
coordinates is in a (3 × 1) column vector,
   
r1 x
r =  r2  =  y  .
r3 z
3.4. Appendix 32

Likewise, for a cloud of N particles one collects the coordinates are into a (3 × n) matrix,
 
r1,1 r1,2 r1,n
R = (r1 , r2 , . . . , rN ) =  r2,1 r2,2 . . . r2,n  .
r3,1 r3,2 r3,n

The i-th column of R contains the three coordinates of the i-th point, the third row of r contains
the z-coordinates of all N points, and the y coordinate of the i-th point is contained in R2i , etc.

The distance |r| from point r to the origin is readily evaluated using Pythagoras’ theorem, which
in three-dimensions reads as

|r|2 = x2 + y 2 + z 2 = r12 + r22 + r32 .

The angle γ between the vectors running from the origin to points i and j, respectively, follows
from

|ri ||rj | cos γ = r1,i r1,j + r2,i r2,j + r3,i r3,j .

Note that the calculation of the length |ri | is a special case of the latter expression, with i = j
and γ = 0. The sum of products on the r.h.s. is known as the inner product or dot product,
with the short-hand notation
K
X
ri · rj = rk,i rk,j ,
k=1
P
where the summation, , runs from 1 to K = 3 for 3D space (while in other contexts K can
take on other values).

Suppose now that we want to rotate the entire cloud of points around the z-axis over an angle
α. For a point with old coordinates ro , its new coordinates rn read as

xn = cos α · xo − sin α · y o ,
y n = sin α · xo + cos α · y o ,
zn = zo.

Every new coordinate is obtained by a linear combination of the old coordinates. To stress this,
we write
 n  
cos α · r1o + − sin α · r2o + 0 · r3o

r1
 r2  =  sin α · r1o + cos α · r2o
n + 0 · r3o  .
r3n 0 · r1o + 0 · r2o + 1 · r3o

These equations follow the pattern


X
rjn = Ajk rko ,
k

where j and k take the values 1, 2 and 3 (for x, y and z) and A is a collection of nine elements
sorted in three rows (with ordinal number j) and three columns (with ordinal number k): a
matrix. This is more commonly written as the matrix-vector multiplication
 n    o 
r1 cos α − sin α 0 r1
 r2n  =  sin α cos α 0   r2o  ,
r3n 0 0 1 r3o
3.4. Appendix 33

or even shorter,

rn = Aro ,

where the dimensions follow the rule (3 × 1) ← (3 × 3)(3 × 1). To rotate the entire cloud of
particles,
X
n o
rji = Ajk rki ,
k

or in short-hand

Rn = ARo ,

where the dimensions follow the rule (3 × N ) ← (3 × 3)(3 × N ). The above indexed expressions
provide the general rule for matrix multiplication, with dimensions (P × N ) ← (P × Q)(Q × N ).

We can rotate the rotated cloud once more, to Rm , using a second (3 × 3) rotation matrix B.
The new coordinates are then related to the old (pre-rotation coordinates) by
X X X
rlim = n
Blj rji = Blj o
Ajk rki ,
j j k

or

Rm = BRn = BARo .

The two consecutive rotations can be combined into a single rotation,


X
rlim = o
Clk rki ,
k

with
X
Clk = Blj Ajk .
j

Note that this relation again follows the general rule for matrix multiplication.

For any given rotation matrix A, it is possible to construct a rotation matrix B such that all
points return to their original positions,

rlim = rlio ,

for all l and i. In that case, C = BA is the identity matrix,


 
1 0 0
C =  0 1 0 ,
0 0 1
or in short-hand C = I, and B acts as the inverse of A,

B = A−1 .

Note that, in general, the elements Bij = (A−1 )ij of A−1 are not simply 1/Aij but have to be
solved from the set of equations
X
Bij Ajk = Iik .
j
3.4. Appendix 34

Rotation matrices have the special property that their inverse is equal to their transposed, i.e.
the matrix obtained by swapping rows and columns,

(A−1 )ij = Aji ,

or for short A−1 = AT , while most matrices require much more work to find their inverse.

Take an asymmetric object, like your laptop, and rotate it by 90◦ around a space-based x axis
(e.g. the long axis of your desk), followed by a 90◦ rotation around a space-based y axis (e.g.
the short axis of your desk) Next, start with the laptop (or your neighbour’s) in the same
initial orientation and execute the two rotations in the reverse order. Note how the two final
orientations differ; in other words,

AB 6= BA.

This reveals an important property of matrices: the order of multiplication matters, unlike
the multiplication behaviour of ordinary numbers (‘scalars’). One therefore must take care
when manipulating matrices, by hand or in Matlab, to conserve the correct order. For two
consecutive rotations, the order becomes irrelevant when both rotations rotate around the same
axis, in which case the two matrices are said to commute.

Once you understand matrices, you will recognize them everywhere: in the weighted combination
of the grades you scored on tests into the final grade for a course, in the calculation of nutrional
values (kcals, grams of fibers, fats and proteins) from your diet composition (half a liter of milk
contributing xxx per 100 ml, four slices of bread contributing xxx per slice, etc), in the solution
of coupled linear equations,

y = Ax → x = A−1 y,

and so on.

Matrices have many more useful properties, for which we refer the reader to the literature. Some
of these properties are listed in Table 3.2.
Chapter 4
Scripts

4.1 Script m-files

Thus far, all Matlab commands were entered at the Matlab prompt and executed immediately.
This becomes inefficient when a problem becomes more complicated. A solution is to store the
commands in script m-files.

M-files are useful e.g. when the number of commands increases or when you want to repeat
the same series of commands with different starting values. Formally, a script is an external
file that contains a sequence of Matlab commands (statements).1 When you run a script, the
commands in it are executed as if they have been entered through the keyboard.

4.2 Creating and running a script

To generate an example script m-file:

• Type edit sinplot in the workspace or use the mouse to open a ‘New Script’.

• Enter the lines listed below

%creates a plot of the sine function


x = 0 : 0.1 : 6.3;
y = sin(a*x);
plot(x,y);
title('Plot of y = sin(x)');

1
Note the difference between script and function m-files, as discussed in more detail in Chapter 6: a script
has neither input nor output parameters, and the variables in a script reside in the regular workspace rather than
in a function-specific workspace.

– 35 –
4.3. Exercises 36

• Save the file under the name ‘sinplot’ (Matlab will add the extension ‘.m’) in a directory
(folder) of your choice.
• Run the script by typing in the Matlab prompt:

a = 3;
sinplot

Alternatively, type a = 3; in the command window and then press F5 or click on the
‘Run’ button.
You might experience problems if your path is not set correctly. The path is the collection
of directories (folders) that Matlab scans for programs to be run, see Section 1.4. If you
saved your script in, say, Myfolder, you can make this your working directory in Matlab,

>> cd Myfolder

or add this directory to the path using the ‘Set Path’ button.
• Try help sinplot to appreciate the usefulness of including comment lines at the top of
an m-file.

Note that the sinplot script affects the workspace:

clear % all variables are removed from the workspace


a = 3;
who
Your variables are: a
sinplot
who
Your variables are: a x y

The trivial variable names x and y may may well be in use already, in which case invoking the
script overwrites their values. Note that the script also relies on the value of a in the workspace,
and will abort with an error if a was not defined before invocation. Undesirable side-effect are
likely to occur when scripts change variables (here: x and y) other than the ‘input’ arguments
(here: a), and even these restricted changes can have undesirable consequences. Since scripts
create and change variables in the workspace without warning, they may easily introduce bugs
that are hard to track down. Hence, it is important to keep in mind that the commands within
a script have access to all variables in the workspace and all variables created in a script become
part of the workspace. It is highly recommended, therefore, to use script m-files sparingly and
to resort to function m-files to solve recurring sub-problems, see Chapter 6, as functions do not
have access to the workspace.

We will have much more to say on plotting graphs in section 11.

4.3 Exercises

Exercise 4.1.
Write a script that, for given 2
√ a, b and c, solves the quadratic equation ax + bx + c = 0, i.e.
returns the roots x = (−b ± b2 − 4ac)/(2a). 
Chapter 5
Control flow

Control flow deals with the conditional and/or repeated execution of blocks of commands.

5.1 Logical and relational operators

To use control flow commands, it is necessary to perform operations that result in logical values:
TRUE or FALSE. In Matlab these are denoted as 1 (true) and 0 (false). Table 5.1 shows the
relational and logical operations; another way to get to know more about them is to type help
relop. The relational operators <=, <, >, >=, == and ∼= are used to compare two arrays of the
same size element-by-element, or to compare all elements in one array against the same scalar.
The logical operators &, |, xor, any and all combine collections of two or more logicals into a
smaller number of logicals, while the logical operator ∼ is used for negation ( true ⇆ false).

Important: the operations & and | have equal precedence in Matlab, which means that these
operators associate from right to left (unlike regular arithmetic). A common situation is:1

>> b = 10;
>> 1 | b > 0 & 0 % evaluated from right to left
ans =
1
>> ( 1 | b > 0 ) & 0
ans =
0
>> 1 | ( b > 0 & 0 ) % this is equivalent to the first evaluation
ans =
1

You are strongly advised to always use brackets to impose a desired order of evaluations.2
1
Note that the relational operation b > 0 is evaluated before the logical operations.
2
This is also highly recommended for numerical operations, e.g. a = 4 / 5 * 3 .

– 37 –
5.1. Logical and relational operators 38

Command Result
a = (b > c) a becomes 1 if b is larger than c and a becomes 0 otherwise.
a = (b == c) a becomes 1 if b is equal to c and a becomes 0 otherwise.
a = (b ∼= c) a becomes 1 if b is not equal to c and a becomes 0 otherwise.
a = ∼b a becomes 1 if b equals 0 and a becomes 0 otherwise.
a = (b & c) a becomes 1 if both b and c are true and a becomes 0 otherwise.
a = (b | c) a becomes 1 if b and/or c are true and a becomes 0 otherwise.
a = xor(b,c) a becomes 1 if either b or c is true and a becomes 0 otherwise.

Table 5.1: Relational and logical operations.

5.1.1 Logical indexing

The application of relational operators to an array returns an array of logicals,

>> i = 5:14;
i =
5 6 7 8 9 10 11 12 13 14
>> j = ( mod(i,2) == 1 ) % brackets added for clarity
j =
1x10 logical array % matlab warning: these are not floats
1 0 1 0 1 0 1 0 1 0

The array j can be used to access selected elements of i, by the method of ‘logical indexing’:

>> i(j) % show the elements of i for which


% the matching element of j is true.
ans =
5 7 9 11 13
>> i(j) = i(j) + 50 % modify the selected elements
i =
55 6 57 8 59 10 61 12 63 14

Note that an array of numerical zeros and ones differs from a array of logical zeros and ones:

>> i = 5:14;
>> j = ( mod(i,2) == 1 )
j =
1 0 1 0 1 0 1 0 1 0 % logicals
>> k = ( mod(i,2) )
k =
1 0 1 0 1 0 1 0 1 0 % floats
>> i(k) = i(k) + 50
Subscript indices must either be real positive integers or logicals.

For the latter line to work, the array k must first be converted into an array of logicals, which
is realized with p = logical(k). In Matlab, any non-zero numerical value is ‘true’ and only
absolute zero is ‘false’. The logical complement ∼ implicitly converts floats into logicals, but
tricks like p = ∼∼k are better avoided: when you read your code again in a couple of months
you will be confused by the double negation – does that not recover the original value? – and
remove it, thereby ending up with a malfunctioning code.
5.1. Logical and relational operators 39

Whereas numerical zeros and ones can not be used for logical indexing, logical zeros and ones
can be used for arithmetic operations (with ‘true’ acting as 1. and ‘false’ as 0.). In the above
example, both i.*j and i.*k will yield the same output: odd numbers alternating with zeros.

Note what happens when we turn k into an array of real positive integers by adding one,

>> i = 5:14;
>> k = mod(i,2) + 1
k =
2 1 2 1 2 1 2 1 2 1
>> i(k)
6 5 6 5 6 5 6 5 6 5
>> i(k) = i(k) + 50
i =
55 56 3 4 5 6 7 8 9 10

You probably expected the last line to increase elements 1 and 2 of i five times by 50, yielding
the values 255 and 256, which clearly did not happen. The ten increments were indeed executed,
but each of these calculations used a (copy of) the original values of i. If you want consecutive
calculations on array elements to build on previous updates of these elements, you must write a
loop (see below).

Exercise 5.1.
Exercise with logical and relational operators:

1. Predict and check the result of each of the operations of Table 5.1 for b = 0 and c = -1.
2. Predict and check the result of each logical operator for b = [2 31 -40 0] and c = 0.
3. Define two random vectors (randn(1,7)) and perform all logical operations, including xor,
any and all.

Exercise 5.2.
Exercise with logical and relational operators:

1. Let x = [1 5 2 8 9 0 1] and y = [5 2 2 6 0 0 2]. Execute and explain the results


of the following commands:
• x > y • x <= y • x & (∼y)
• y < x • y >= x • (x > y) | (y < x)
• x == y • x | y • (x > y) & (y < x)
2. Let x = 1:10 and y = [3 5 6 1 8 2 9 4 0 7]. The exercises here show the techniques
of logical-indexing. Execute and interpret the results of the following commands:
• (x > 3) & (x < 8) • x( (x < 2) | (x >= 8) )
• x( x > 5 ) • y( (x < 2) | (x >= 8) )
• y( x <= 4 ) • x( y < 0 )

Exercise 5.3.
Let x = [3 16 9 12 -1 0 -12 9 6 1]. Provide the command(s) that will:
5.1. Logical and relational operators 40

• set the positive values of x to zero;


• set values that are multiples of 3 to 3 (make use of rem);
• multiply the even values of x by 5;
• extract the values of x that are greater than 10 into a vector called y;
• set the values in x that are less than the mean to 0;
• set the values in x that are above the mean to their difference from the mean.


Exercise 5.4.
Execute the following commands and try to understand how z is defined.

>> hold on
>> x = −3:0.05:3; y = sin(3*x);
>> subplot(1,2,1); plot(x,y); axis tight
>> z = (y < 0.5) .* y;
>> subplot(1,2,2); plot(x,y,'r:'); plot(x,z,'r'); axis tight
>> hold off

Before moving on, check whether you now understand the following relations:

>> a = randperm(10); % random permutation


>> b = 1:10;
>> b − (a <= 7) % subtracts from b a 0−1 vector,
>> % with 1 for a <= 7 and 0 otherwise
>> (a >= 2) & (a < 4) % returns ones at positions where 2 <= a < 4
>> ∼(b > 4) % returns ones at positions where b <= 4
>> (a == b) | b == 3 % returns ones at positions where
>> % a is equal to b and/or b is equal to 3
>> any(a > 5) % returns 1 when ANY of the a elements is larger than 5
>> any(b < 5 & a > 8) % returns 1 when (b < 5 & a > 8) yields at least one true
>> all(b > 2) % returns 1 when ALL elements of b are larger than 2

5.1.2 The find command

Logical indexing allows one to extract those elements from a vector (or matrix) that satisfying
a given condition, by using an array of logicals as the intermediate step. The same final result
can be obtained using find, which returns the positions (indices) of the element(s) matching
the condition:

>> x = [1 1 3 4 1];
>> i = (x == 1) % i holds: do the elements satisfy x == 1?
i =
1 1 0 0 1
>> y = x(i)
y =
1 1 1
>> j = find(x == 1) % j holds: which element(s) satisfy x == 1?
j =
1 2 5
>> z = x(j)
z =
1 1 1
5.1. Logical and relational operators 41

Another example:

>> x = −1:0.05:1;
>> y = sin(x) .* sin(3*pi*x);
>> plot (x,y, '−'); hold on
>> k = find (y <= −0.1)
k =
9 10 11 12 13 29 30 31 32 33
>> plot (x(k), y(k), 'ro');
>> r = find (x > 0.5 & y > 0)
r =
35 36 37 38 39 40 41
>> plot (x(r), y(r), 'r*');

The command find operates in a similar way on matrices:

>> A = [1 3 −3 −5; −1 2 −1 0; 3 −7 2 7];


>> k = find (A >= 2.5)
k =
3
4
12
>> A(k)
ans =
3
3
7

In this example, find approached the matrix A as a single column vector [which is achieved with
the command A(:)] and the returned indices refer to positions in this column vector. The row
and column indices of the selected elements are returned by

>> [I,J] = find (A >= 2.5)


I =
3
1
3
J =
1
2
4
>> [A(I(1),J(1)), A(I(2),J(2)), A(I(3),J(3))] % lists the values
ans =
3 3 7
>> A(sub2ind(size(A),I,J)) % list the values
ans =
3
3
7

or the can be calculated from k by [i,j] = ind2sub(size(A),k).

Exercise 5.5.
Let A = ceil (5*randn(6,6)). Use both logical indexing and the command find to

• find the indices and list all elements of A which are smaller than -3;
• find the indices and list all elements of A which are smaller than 5 and larger than -1;
5.2. Conditional code execution 42

• remove those columns of A which contain at least one 0 element.

5.2 Conditional code execution

5.2.1 Using if ... elseif ... else ... end

Selection control structures, if-blocks, are used to decide which instruction to execute next
depending whether expression is TRUE or not. The general description of the syntax is presented
by the diagrams below, on the left. In the examples on the right, the command disp is used to
display specificied messages on the screen.

• if ... end

Syntax Example
if logical_expression if (a > 0)
statement1 b = a;
statement2 disp ('a is positive');
.... end
end

• if ... else ... end

Syntax Example
if logical_expression if (temperature > 100)
block of statements disp ('Above boiling.');
evaluated if TRUE toohigh = 1;
else else
block of statements disp ('Temperature is OK.');
evaluated if FALSE toohigh = 0;
end end

• if ... elseif ... end

Syntax Example
if logical_expression1 if (price > 100)
block of statements evaluated disp ('too expensive');
if logical_expression1 is TRUE elseif (price < 10)
elseif logical_expression2 disp ('cheap');
block of statements evaluated end
if logical_expression2 is TRUE
end
5.2. Conditional code execution 43

• if ... elseif ... else ... end

Syntax Example
if logical_expression1 if (height > 190)
block of statements evaluated disp ('very tall');
if logical_expression1 is TRUE elseif (height > 170)
elseif logical_expression2 disp ('tall');
block of statements evaluated elseif (height < 150)
if logical_expression2 is TRUE disp ('small');
else else
block of statements evaluated disp ('average');
if no other expression is TRUE end
end

Important: at most one block of commands is executed, i.e. the first that matches (if any).
Exercise 5.6.
For each of the four following fragments of code, predict what results they will produce for the
various starting values given on the right. Use Matlab to verify your answers, but be warned
that these fragments are not proper Matlab code and therefore might need correction(s) before
they work properly.

1. if n > 1 a) n = 7 m = ?
m = n + 2 b) n = 0 m = ?
else c) n = −7 m = ?
m = n − 2
end

2. if s <= 1 a) s = 1 t = ?
t = 2z b) s = 7 t = ?
elseif s < 10 c) s = 57 t = ?
t = 9 − z d) s = 300 t = ?
elseif s < 100
t = sqrt(s)
else
t = s
end

3. if t >= 24 a) t = 50 h = ?
z = 3t + 1 b) t = 19 h = ?
elseif t < 9 c) t = −6 h = ?
z = tˆ2/3 − 2t d) t = 0 h = ?
else
z = −t
end

4. if 0 < x < 7 a) x = −1 y = ?
y = 4x b) x = 5 y = ?
elseif 7 < x < 55 c) x = 30 y = ?
y = −10x d) x = 56 y = ?
else
5.2. Conditional code execution 44

y = 333
end

Exercise 5.7.
Create a script that converts the Reynolds number Re of a body in a flow into the resulting
drag coefficient C, where


 0 Re ≤ 0,
 24/Re Re ∈ (0, 0.1],



C= 0.7
(24/Re)(1 + 0.14Re ) Re ∈ (0.1, 1e3],




 0.43 Re ∈ (1e3, 5e5],
0.19 − 8e4/Re Re > 5e5.

Verify whether your script works correctly by computing various drag coefficients calculated by
the script against their values calculated by hand, for e.g. Re = −3 · 103 , 0.01 56, 103 and 3 · 106 .
Remember that e.g. 4e5 is Matlab notation of 4 · 105 . 

Exercise 5.8.
Write a script that asks (using input) for an integer and returns whether it can be divided by
2 and/or 3. Consider all possibilities, such as, divisible by both 2 and 3, divisible by 2 but not
by 3, etc. Hint: look up the commands mod and rem. 

5.2.2 Using switch

Another selection structure is switch, which switches between several cases depending on the
value of a variable:

Syntax Example
switch variable method = 2;
case choice1 switch method
block of commands1 case 1
case {choice2a, choice2b,...} disp('Method is linear.');
block of commands2 case {2,3}
... disp('Method is cubic.');
otherwise otherwise
block of commands disp('Unknown method.');
end end

Important: at most one block of commands is executed, i.e. the first that matches (if any).

The variable can be a scalar or a string; a scalar matches if the comparison variable ==
choice returns 1, a string matches if the comparison strcmp(variable, choice) returns 1. A
case can be endowed with multiple matches by using curly brackets, as in the example. The
switch construction can be very handy to avoid long if .. elseif ... else ... end
constructions. If a case must match many values (say 1 through 100) or a range of values
(between 5.5 and 10), an if construction is more appropriate.
5.3. Loops 45

Exercise 5.9.
Write a script that asks (using input) the user for the ordinal number of a month and returns
the number of days in that month (assuming February has 28 days). Next, modify your script
to use the name of a month in stead of the ordinal number. 

5.3 Loops

Iteration control structures, loops, are used to repeat a block of commands several times. Two
types of loops exist:

• The for loop repeats a group of statements a fixed 3 number of times:


Syntax Example
for index = row_vector sumx = 0;
block of statements for i=1:length(x)
end sumx = sumx + x(i);
end

The row vector is often conveniently created using colon notation, first:step:last.
The elements of row vector need not be integers, do not have to be ordered, can be
characters and can even be column vectors. Some examples of possible variations:
Example 1 Example 2 Example 3 Example 4
for i=1:2:7 for i=8:-1:3 for x=0:0.1:1 for x=[25 9 81]
... .... disp(x^2); disp(sqrt(x));
end end end end

• The while loop evaluates a group of commands as long as an expression holds true:
Syntax Example
while expression N = 100;
statement1 iter = 1;
statement2 msum = 0;
statement3 while iter <= N
... msum = msum + iter;
end iter = iter + 1;
end;

Be aware that you can end up with an infinite loop; these can be interrupted with Ctrl–C.

As a simple example of how to use the loop construct, execute the following script to draw
graphs of f (x) = cos(nx) for n = 1, . . . , 9 ordered in an (3 × 3) array of subplots:

3
The set of values of index is determined when entering the loop and can not be changed within the loop.
5.3. Loops 46

figure
hold on
x = linspace(0,2*pi);
for n=1:9
subplot(3,3,n);
y = cos(n*x);
plot(x,y);
axis tight
end

As a second example of for loops, we combine two vectors x and y into a matrix A whose
elements are defined as Aij = xi yj . Enter the following commands in a script:

n = length(x);
m = length(y);
for i=1:n
for j=1:m
A(i,j) = x(i) * y(j);
end
end

and determine A for x = [1 2 -1 5 -7 2 4] and y = [3 1 -5 7]. Note that A is of size


(n × m). The same problem can be solved by using while-loops follows:

n = length(x);
m = length(y);
i = 1; j = 1; % initialize i and j
while i <= n
while j <= m
A(i,j) = x(i) * y(j);
j = j+1; % increment j; it does not happen automatically
end
i = i+1; % increment i
end

Exercise 5.10.
Determine the sum of the first 50 squared numbers with a control loop. 

Exercise 5.11.
Write a script to find the largest value of n for which the sum 12/3 + 22/3 + . . . + n2/3 is less
than 1000. Can you also output the value of the sum for that value of n, without evaluating the
summation twice and without making use of an array? 

Exercise 5.12.
Use a loop construction to carry out the computations. Write short scripts.

1. Given the vector x = [1 8 3 9 0 1], create a short set of commands that will:
• add up the values of the elements (check with sum);
• computes the running sum (for element j, the running sum is the sum of the elements
from 1 to j; check with cumsum);
• computes the sine of the given x-values (should be a vector).

2. Given x = [4 1 6 -1 -2 2] and y = [6 2 -7 1 5 -1], use loops to create matrices


whose elements are created according to the following formulas:
5.4. Comments on logical and relational expressions 47

• aij = yi /xj ;
• bi = xi yi , and sum the elements in btot;
• cij = xi /(2 + xi + yj );
• dij = 1/ max(xi , yj ).

3. Write a script that uses loops to transposes a matrix A.

4. Create an m-by-n array of random numbers (use rand). Move through the array, element
by element, and set any value that is less than 0.5 to 0 and any value that is greater than
(or equal to) 0.5 to 1.

5. Write a script that will use the random-number generator rand to determine:
• the number of random numbers it takes to add up to 10 or more;
• the number of random numbers it takes before a number between 0.8 and 0.85 occurs;
• the number of random numbers it takes before the mean of those numbers is within
0.01 and 0.5.
It will be worthwhile to run your script multiple times, using a loop, because you are
dealing with random numbers. Can you predict/explain any of the results?

Exercise 5.13.
Write a script that asks for a temperature in centigrade Tc and computes the equivalent tem-
perature in Fahrenheit Tf , using the formula Tf = 9/5Tc + 32. The script should keep running
until no number is provided to convert. The functions input and isempty (use help to learn
more) should be useful here. 

Exercise 5.14.
Matlab is flexible in allowing non-integer indices in for loops. This is not without risk, however.
Try what happens when you run the following code:

for i = 0 : 1/7 : 1
j(7*i) = i
end

Can you explain why this fails, and suggest (trivial) remedies? 

5.4 Comments on logical and relational expressions

As relational and logical expressions get increasingly more complex, one can easily run into
situations where the evaluation of the second part of an expression becomes conditional to the
result of the first part of that expression. Consider the following example to determine whether a
matrix A is invertible, which requires the matrix to be square and have a non-zero determinant:

s = size(A)
invble = ( s(1) == s(2) ) & ( det(A) ∼= 0 )

This code works fine for square matrices, but for non-square matrices terminates with the error
message ‘Error using det, matrix must be square.’ What happens is that the two relational
5.4. Comments on logical and relational expressions 48

operations on the second line are both evaluated, followed by a logical operation combining the
partial results. Hence, the determinant is evaluated even if the negative result of the ‘preceding’
size check already establishes that the matrix is non-invertible. The solution is know as ‘short-
circuiting’, forcing the code to evaluate the second condition only when its outcome is relevant
for the overall result, that is, when the first part of an AND is true or when the first part of an
OR is false. To force Matlab to use short-circuiting, the logical bitwise & or | operators must
be doubled to && or ||,4 as in

invble = ( s(1) == s(2) ) && ( det(A) ∼= 0 )

Matlab defaults to short-circuiting in if and while statements.

Important: The fact that computers make use of finite-precision arithmetic means that you
should be careful when comparing two floating-point numbers. The code block in the following
if statement will only be executed if x and y are identical down to the last digit,

if (x == y)
block of statements
end

This construction is fine if x and y are integers or have both been assigned the same value (y = x),
but if x and y are the results of two distinct calculations there is a good chance that they are
not completely identical, even if they should be identical following an analytic calculation. In
stead of the above construction, one is advised to use

if (abs (x − y) < tolerance) % e.g. tolerance = 1e−10


block of statements
end

Exercise 5.15.
Consider the following example:

max iter = 50;


tolerance = 1e−4;
iter = 0;
xold = 0.1;
x = 1;
while (abs (x − xold) > tolerance) & (iter < max iter)
xold = x;
x = cos(xold);
iter = iter + 1;
end

This short program iteratively solves the equation cos(x) = x, with x holding the best approxi-
mation. Note that the while-loop is repeated as long as both conditions are true: when either
condition is met, the loop aborts. Run the script for various values of the tolerance parameter,
e.g.: 10−2, 10−4 , 10−6 10−8 , 10−10 . Compare the final values of x and cos(x), by using format
long and by calculating their difference. How does the number of iterations, iter, vary with
the requested tolerance? 
4
Note that & and | will work on arrays, returning an array of logicals, while && and || will only work on
scalars, returning a single logical.
5.4. Comments on logical and relational expressions 49

Figure 5.1: Sectioning of a circle into triangles to approximate π. (Copied from the BEAM-B
handout.)

Exercise 5.16.
Modify the above script by replacing the while-loop condition with

while (abs (x − xold) > tolerance) | (iter < max iter)

Try to understand the difference between the two codes, and verify your expectations by running
the second script. What happens to iter? 

Exercise 5.17.
One can approximate 2π, the circumference of a unit circle (radius = 1), as follows: Section the
circle into triangles, as in figure 5.1. Starting at n = 1 with four identical triangles running from
(0, 0) to (±1, 0) and (0, ±1), the √ lengths sn of the bases of these triangles (i.e. the sides facing
the circumference) equals s1 = 2. As a first approximation for the circumference of the circle,
one obtains 4s1 ≈ 5.66. Next, the number of triangles is doubled. Then, length a equals half
the length sn . Lengths b and c can be computed – without using goniometric functions – so the
length of the new bases, sn+1 , is also known. An improved approximation for the circumference
of the circle is readily obtained. Write a script to evaluate the approximate circumferences while
the number of triangles is doubled at least 20 times. 
Chapter 6
Functions

Matlab M-files were introduced in chapter 4 to collect commands in scripts. In this chapter
m-files are used to define functions.

6.1 Function m-file

Function m-files are true subprograms, taking input arguments and/or returning output pa-
rameters. They can call other functions as well. Variables defined and used inside a function,
different from the input/output arguments, are not visible to other functions nor to the command
environment. The general syntax of a function is:

function [outputArgs] = function name (inputArgs)


block of statements
end % or: return

outputArgs are enclosed in [ ]:


– a comma-separated list of variable names;
– the brackets [ ] are optional when only one argument is returned;
– functions without outputArgs are legal.1

inputArgs are enclosed in ( ):


– a comma-separated list of variable names;
– functions without inputArgs are legal, in which case the brackets ( ) are optional.

Matlab provides a structure for creating your own functions. The first line of the file should
contain the definition of the new function, also called the header. Next follows a continuous
sequence of comment lines, to explain what the function does, especially when this is not trivial.
1
In other programming languages, functions without output arguments are called procedures.

– 50 –
6.1. Function m-file 51

You are advised to also discuss the expected input parameters and the format of the output,
to make life easier on the user (which includes you in a couple of months). These comment
lines, up to the first non-comment line, will be displayed in response to the help command. The
remainder of the function, the body, contains the main code of the function. Function m-files
terminate execution and return to their invoker when they reach the end of the function or,
alternatively, when the command return is encountered. As an example, the function average
is defined as follows:

output argument function name


input argument
the first line must be
the function definition function avr = average (x)
%AVERAGE computes the average value of a vector x
comment % and returns it in avr
% Notes: an example of a function
n = length(x); a blank line within the comment;
avr = sum(x)/n; Notes information will NOT appear
function body
when you ask: help average
return;

Important: Matlab identifies functions in m-files by the name of the m-file; the name in the
header is ignored. It is good practice, however, to keep these two names identical.

Exercise 6.1.
Create the function average and store it on disk as average.m. Test whether average.m
functions properly by typing avr1 = average(1:10); What message appears when you call
help average?  Here is an another example of a function:
function [avr,sd] = stat(x)
%STAT Simple statistics.
% Computes the average value and the standard deviation of a vector x.
n = length(x);
avr = sum(x)/n;
sd = sqrt(sum((x − avr).ˆ2)/n);
return; % or: end

Try invoking the above function by issuing the commands

v = rand(10,1);
stat(v)
j = stat(v);
[j,k] = stat(v)

Note that the first two invocations return a single value, i.e. the average, which is displayed on
screen and stored in j, respectively. The last invocation returns two values, the average is stored
in j and the standard deviation is stored in k. In sending and receiving information between
an invoker and a function, the names of the variables are unimportant – these are ‘private’ to
the sender and receiver, see section 6.2 – but it is the order of the variables that determines the
communication of values: j receives the value of avr and k receives the value of sd. If one is
interested in the second, but not the first, returned argument: [~,k] = stat(v).

Warning: The functions mean and std already exist in Matlab. If the name of a function is
also used as a variable name, it becomes impossible to access that function. Many other easily
6.1. Function m-file 52

appealing names, such as sum and prod, are also reserved by Matlab functions, so be careful
when choosing your names (see section 9.3).

The return statement can be used to force an early return. An example:

function d = determinant(A)
%DETERMINANT Computes the determinant of a matrix A
[m,n] = size(A);
if (m ∼= n)
disp ('Error. Matrix should be square.');
return; % exits the function immediately
else
d = det(A); % standard Matlab function
end
return;

The use of the return command in combination with a check on the number of input arguments
is given in the function checkarg in section 6.5.

In controlling the proper use of parameters, the function error may prove useful. It displays
an error message, aborts function execution and returns to the command environment. Here is
an example:

if (a >= 1)
error ('a must be smaller than 1');
end

Exercise 6.2.
Change some scripts that you created into functions, e.g. create the function drag to computing
the drag coefficient (see section 5.2), or the function solve cos (see section 5.4) or the function
cubic roots (see section 4). 

Exercise 6.3.
Write the function [elems, mns] = nonzero(A) that takes as the input argument a matrix A
and returns all nonzero elements of A in the column vector elems. The output parameter mns
holds values of the means of all columns of A. 

Exercise 6.4.
Write the function [meanrow, meancol] = allmeans(A) that takes as the input argument a
matrix A and returns the means of all its rows and columns respectively. 

Exercise 6.5.
Create the function [A,B,C] = sides(a,b,c) that takes three positive numbers a, b and c. If
they are sides of a triangle, then the function returns its angles A, B and C, measured in degrees.
Display an error when necessary. 

Exercise 6.6. p
The area of a triangle with sides of length a, b and c is given by: A = s (s − a) (s − b) (s − c),
where s = (a + b + c)/2. Write a function that accepts a, b and c as input and returns the area A
as output. Note that the sides should be non-negative and should obey the triangle inequality.
Make use of the error command to report violations. 
6.2. Local and global variables 53

Exercise 6.7.
Create the function randint that generates random matrices of integer numbers (use the com-
mand rand). The integers should come from the interval [a, b]. Exercise in documenting the
function. Use the following function header:

function r = randint(m,n,a,b) % an (m x n) matrix

If this is too difficult, start with a fixed interval, e.g. [a, b] = [0, 5] (and remove a and b from
the function definition), before attempting the arbitrary interval. 

6.2 Local and global variables

Each m-file function has access to a part of memory separate from Matlab’s workspace. This is
called the function workspace. This means that each m-file function has its own local variables,
which are separate from those of other functions and from the workspace. To understand this
better, analyze the following diagram:

Matlab workspace myfun.m


>> a = -1; function z = myfun(x,y)
>> b = 20; (a, b) −→ (x, y) w = x - y
>> c = 5; i = 25
>> i = 12; d ←− z z = x + cos(w);
>> d = myfun (a,b) return;

In the Matlab workspace, only the variables a, b, c, d and i are available. The variables
w, x, y, z and i are available only in the function myfun. Because the variables are local, it
is impossible for commands in the workspace to alter the values of variables in the function
(with the exception of the values being passed as arguments at the invocation) and likewise it is
impossible for commands in the function to alter the values of variables in the workspace (with
the exception of the values being returned when the function finishes). We can therefore use
the same variable name(s) multiple times, like i in the above example, without the danger that
changing the value of i in the function has (potentially disastrous) consequences for the value of
i in the workspace, and vice versa. Each function has its private set of variables. The arrows in
the center highlight the sending and receiving of values between the workspace and the function,
with the value of a transferred to x and the value of b transferred to y; the same order-based
protocol also applies for function output and for communication between functions.

It can sometimes be useful for several functions and/or the workspace to have access to the same
variable. This can be realised by declaring a particular variable as global in the functions (and
the workspace) that require access to this variable, see help global. Note that it is very easy
to end up with serious errors.

The values of the variables within a functions are typically lost when the function terminates.
Variables that are to be reused in a later invocation of a function must be declared persistent.
6.3. Subfunctions 54

6.3 Subfunctions

A function m-file may contain multiple functions. The function appearing first in the m-file
shares the file name, as mentioned before. Subsequent functions are subfunctions and can be
called from the primary function only: they can not be accessed from outside the file in which
they are defined, neither from the Command Window nor via any other m-file. A subfunction is
created by defining a new function with the function statement after the body of the preceding
function. The use of subfunctions is recommended to keep the main function readable when
it becomes too long and/or too complicated. In the below example, average is a subfunction
within the file stat.m:

function [a,sd] = stat(x)


%STAT Simple statistics.
% Computes the average value and the standard deviation of a vector x.
n = length(x);
a = average(x,n);
sd = sqrt(sum((x − avr).ˆ2)/n);
return;

function a = average (x,n)


%AVERAGE subfunction
a = sum(x)/n;
return;

Frequently-called small functions are best included as subfunctions, so they reside in memory
simultaneously with the invoker. This enables quick access to the (sub)function, and avoids
Matlab repeatedly scanning your disk for the function m-file and repeatedly loading the file
into memory.

Subfunctions can also be appended to script files.

Exercise 6.8.
Modify the function stat presented above by using the subfunction average for the computation
of variable sd as well. 

6.4 Nested functions

Related to sub-functions are the ‘nested’ functions, i.e. functions that are fully contained within
another function. Try for example

function parent
x = 4
y = 3
disp('In parent')
nested(y)
x,y
function nested(z)
disp('In nested')
x = x + z;
end % nested
end % parent
6.5. Special function variables 55

The main difference between nested and sub-functions is that nested functions can see the data
of the parent function(s). Therefore the code above is perfectly valid and the function nested
changes the value of x in parent. Note that the variable z is local to nested, and that the
commands in nested are only executed when the function is actually called.

6.5 Special function variables

Every function has two internal variables: nargin - the number of function input arguments
that were used when call the function and nargout - the number of output arguments expected
by the call. Analyze the following function:

function [out1,out2] = checkarg (in1,in2,in3)


%CHECKARG Demo on using the nargin and nargout variables.
if (nargin == 0)
disp('no input arguments');
return;
elseif (nargin == 1)
s = in1;
p = in1;
disp('1 input argument');
elseif (nargin == 2)
s = in1+in2;
p = in1*in2;
disp('2 input arguments');
elseif (nargin == 3)
s = in1+in2+in3;
p = in1*in2*in3;
disp('3 input arguments');
else
error('Too many inputs.');
end

if (nargout == 0)
return;
elseif (nargout == 1)
out1 = s;
else
out1 = s;
out2 = p;
end

The cell arrays (see section 7) varargin and varargout allow an indefinite number of input and
output arguments to a function.

Exercise 6.9.
Construct the function checkarg and call it with various numbers of input and output arguments
to try and understand its behavior. For example:

>> checkarg
>> s = checkarg(−6)
>> s = checkarg(23,7)
>> [s,p] = checkarg(3,4,5)


6.6. Indirect function evaluation 56

optional

6.6 Indirect function evaluation

Using indirect function evaluation makes programming even more general, since functions can
become input arguments. The Matlab command here is feval, an abbreviation of function
evaluation. The feval command allows execution of a function specified by a string. The
general definition is as follows:

[y1,..,yn] = feval (F,x1,...,xn),

where F is a name of a function, x1,...,xn are input arguments and y1,...,yn are output
parameters. Consider the example:

>> x = pi; y = cos(x);


>> z = feval('cos',x);

The last command is also equivalent to the following two expressions:

>> F = 'cos';
>> z = feval(F,x)

Indirect function evaluation is a nice tool to build a program with a function given as an
argument.

Exercise 6.10.
Create the function funplot and try to understand how it works:

function funplot (F, xstart, xend, col);


%FUNPLOT makes a plot of the function F at the interval [xstart, xend].
% The plot should be made in one of the standard Matlab colors, so
% 'col' is one of the following value: 'b','k','m','g','w','y' or 'r'.
% default values:
% [xstart,xend] = [0,10]
% col = 'b'

% Note: illustrates the use of feval command

if (nargin == 0)
error ('No function is provided.');
end
if (nargin < 2)
xstart = 0;
xend = 10;
end
if (nargin == 2)
error ('Wrong number of arguments. You should provide xstart and xend.');
end
if (nargin < 4)
col = 'b';
end

if (xstart == xend),
error ('The [xstart, xend] should be a non−zero range.');
6.7. Scripts versus functions 57

elseif (xstart > xend),


exchange = xend;
xend = xstart;
xstart = exchange;
end

switch col
case {'b','k','m','g','w','y','r'}
; % do nothing; the right color choice
otherwise
error ('Wrong col value provided.')
end

x = linspace(xstart, xend);
y = feval(F,x);
plot (x,y,col);
description = ['Plot of ', F];
title (description);
return;

Note the use of comments, the nargin variable and the switch-construction. Call funplot for
different built-in functions, like sin, exp, etc. Test it for your own functions as well: write for
example a function myfun that computes sin(x cos(x)) or log( |x sin(x)| ). Explain why it would
be wrong to use the fragment given below instead of its equivalent part in funplot.

if nargin < 2
xstart = 0;
xend = 10;
elseif nargin < 3
error ('Wrong number of arguments. You should provide xstart and xend.');
elseif nargin < 4
col = 'b';
end

We will encounter more versatile forms of indirect function evaluation in section 12.2.1 and
12.3.2, where an inline function and a function handle @, respectively, are passed as argument
to a function.

end optional

6.7 Scripts versus functions

The most important difference between a script and a function is that all parameters and
variables in the script are externally accessible (i.e. in the workspace), while function variables
are not easily accessed. Therefore, a script is a good tool for documenting work, designing
experiments and testing. In general, functions are created to solve a given sub-problem for
arbitrary parameters; in many cases functions are operated as black boxes, e.g. the in-built
functions of Matlab (though it is highly recommended to test them before you use them, to
make sure that you understand their functioning, the structure of the input and output, and
whether they are suitable for your sub-problem). Use a script to run functions for the specific
parameters required by the problem at hand.
6.8. Exercises 58

6.8 Exercises

Exercise 6.11.
Create a Matlab function to evaluate the expression
1 n
 
f (n) = 1 +
n
as a function of n. Next check the outcome of this expression for increasing n. Can you verify
that lim f (n) = e? 
n→∞

Exercise 6.12.
Create the function binom that computes the value of the binomial symbol nk . Make the


function header: function b = binom (n,k). Note that in order to write this function, you
will have to create the factorial function, which computes the value of n! = 1 ∗ 2 ∗ ... ∗ n. This
may become a separate function (enclosed in a new file) or a subfunction in the binom.m file. Try
to implement both cases if you got acquainted with the notion of a subfunction. Having created
the binom function, write a script that displays on screen all the binomial symbols for n = 8 and
k = 1, 2, ..., 8 or write a script that displays on screen the following ’triangle’ (use the fprintf
command; try help fprintf. Note fprintf is a c-command, which is in the header cstdio
(with the same syntax), but C++: streams are much better for dealing with input/output, so
its use is not recommended in C++:.
1

1
2 2

1 2
3 3 3

1 2 3
4 4 4 4

1 2 3 4

Exercise 6.13.
Solve the following exercises by using either a script or a function. The nature of the input/out-
put and display options is left to you. Problems are presented with the increasing difficulty;
start simple and add complexity. If possible, try to solve all of them.

1. Write a function that computes the cumulative product of a vector elements.


Q The cu-
mulative product up to the j-th element of the vector x is defined by Cj = jk=1 xk for
j = 1 : length(x). Check your results with the built-in function cumprod.

2. Write
P a function P m = wmean (x,w) to compute the weighted arithmetic mean, defined as
( ni=1 wi xi )/( ni=1 wi ), given the vector x and a vector of nonnegative weights w. Include
error messages to terminate execution of the function in case:
– x and w are of different lengths,
– any element of w is negative,
– the sum of all weights is equal to zero.

3. What is the largest value of n for which the sum

12 + 22 + 32 + . . . + n2

is less than 100?


6.8. Exercises 59

4. Compute the value of π using the series:



π2 − 8 X 1
=
16 n=1
(2n − 1) (2n + 1)2
2

How many terms are needed to obtain an accuracy of 10−12 ? How accurately does the
sum of 100 terms approach π?

5. Write a program that approximates π by computing the sum:



π X (−1)n
=
4 n=0 2n + 1

The more terms are included in the summation, the higher the accuracy (although this
is not an efficient formula, since you add and subtract numbers). How many terms are
needed to approximate π with 5 decimals? Use the sum to approximate π using 10, 100,
103 , 104 , 105 and 016 terms. For each of these numbers, compute the approximation error.
Plot the error as a function of the number of terms used in the summation.

6. The Fibonacci numbers are computed with the following relation:

Fn = Fn−1 + Fn−2 , with F0 = F1 = 1.

– Compute the first 10 Fibonacci numbers.


– For the first 50 Fibonacci numbers, compute√the ratio Fn /Fn−1 . It is claimed that
this ratio approaches the golden mean, (1 + 5)/2. What do your results show?

7. Consider the problem of computing the n-th Fibonacci number. Find three different
ways to implement this and construct three different functions, say fib1, fib2 and fib3.
Measure the execution time of all functions (use the commands tic and toc) for, say,
n = 20, 40 and 100.

8. The Legendre polynomials Pn (x) are defined by the recurrence relation:

(n + 1) Pn+1 (x) − (2n + 1) x Pn (x) + n Pn−1 (x) = 0

with P0 (x) = 1, P1 (x) = x and P2 (x) = (3x2 − 1)/2. Compute the next three Legendre
polynomials and plot all six over the interval [−1, 1].

9. Write a script that asks for an integer n (or a function that has n as the input argument)
and then runs the following algorithm: While the value of n is greater than 1, replace an
even n with (n/2) and an odd n with (3n + 1). Count the number of values in the sequence
that results.
Example: For n = 10, the sequence reads as 5, 16, 8, 4, 2, 1 and the number of values is 6.
For n = 10, the sequence counds 17 elements.
Make a plot of the length of the sequence as a function of n for n = 2 to 30. Is there any
pattern? Try larger numbers to see whether the pattern persists. Are there n’s for which
the sequence does not terminate?

10. Provide all prime numbers smaller then a given N .


Chapter 7
Cell arrays and structures

7.1 Cell arrays

Cell arrays are arrays whose elements are cells. Each cell can contain any data, including numeric
arrays, strings, cell arrays etc. For instance, one cell can contain a string, another a numeric
array etc. Below, is a schematic representation of an exemplar cell array:

cell 1,1 cell 1,2 cell 1,3

3 1 -7 John Smith
7 2 4 35 1 + 3i
0 -1 6
7 3 7 5900 6000 6100

cell 2,1 cell 2,2 cell 2,3

’Hi’ [7,7] ’Living’


’this is a text’
-1 0 ’Bye’ ’implies effort’
0 -1

Cell arrays can be built up by assigning data to each cell. The cell contents are accessed by
brackets {}. For example:

>> A(1,1) = {[3 1 −7;7 2 4;0 −1 6;7 3 7]};


>> A(2,1) = {'this is a text'};
>> B(1,1) = {'John Smith'}; B(2,1) = {35}; B(3,1) = {[5900 6000 6100]}
>> A{1,2} = B; % cell array B becomes one of the cells of A
>> C(1,1) = {'Hi'}; C(2,1) = {[−1 0;0 −1]}; C(1,2) = {[7,7]}; C(2,2) = {'Bye'};
>> A(2,2) = {C}; % cell array C becomes one of the cells of A
>> A % A represents now the first 2 columns of the exemplar
% cell array

– 60 –
7.2. Structures 61

A =
[4x3 double] {3x1 cell}
'this is a text' {2x2 cell}
>> A(2,2) % access the cell but not its contents
ans =
{2x2 cell}
>> A{2,2} % use {} to display the contents
ans =
'Hi' [1x2 double]
[2x2 double] 'Bye'
>> A{2,2}{2,1} % take the (2,1) element of the cell A{2,2}
ans =
−1 0
0 −1

There are also two useful functions with meaningful names: celldisp and cellplot. Use help
to learn more.

The common application of cell arrays is the creation of text arrays. Consider the following
example:

>> M = {'January';'February';'March';'April';'May';'June';'July';'August';
'September';'October';'November';'December'};
>> fprintf ('It is %s.\n', M{9});
It is September.

Exercise 7.1.
Exercise with the concept of a cell array, first by typing the examples presented above. Next,
create a cell array W with the names of week days, and using the command fprintf, display on
screen the current date with the day of the week. The goal of this exercise is also to use fprintf
with a format for a day name and a date, in the spirit of the above example. 

7.2 Structures

Structures are Matlab arrays with data objects composed of fields and are very similar to
classes in c++, see section 22. Each field contains one item of information. For example, one
field might include a string representing a name, another a scalar representing age or an array
of the last few salaries. Structures are especially useful for creating and handling a database.
One of the possible ways to create a structure is by assigning data to individual fields. Imagine
that you want to construct a database with some information on workers of a company:

>> worker.name = 'John Smith';


>> worker.age = 35;
>> worker.salary = [5900, 6000, 6100];
>> worker =
name: 'John Smith'
age: 35
salary: [5900 6000 6100]

In this way, a 1×1 structure array worker with three fields: name, age and salary is constructed.
To expand the structure, add a subscript after the structure name:
7.2. Structures 62

>> worker(2).name = 'Linda Murphy'; % after this, a 2nd subarray is created


>> worker(2).age = 41;
>> worker(2).salary = [7301, 7301]; % field sizes do not need to match!
>> worker
1x2 struct array with fields:
name
age
salary

Since this structure has now the size of 1 × 2, Matlab does not display the contents of all fields.
The data are now organized as follows:

worker array

worker(1) worker(2)

.name John Smith .name Linda Murphy

.age 35 .age 41

.salary .salary
5900, 6000, 6100 7301, 7301

Structures can also be build by using the struct function. For example:

>> employee=struct( 'name','John Smith','age',35,'salary',[5900, 6000, 6100]);

To create an empty structure with fields field1, field2

s = struct('field1', {}, 'field2', {})

To create an empty structure with no fields

struct([])

To access an entire field, include a field name after a period. To access a subarray, follow the
standard way of using subscripts:

>> worker(1).age
35
>> worker(2).salary(2)
7301
>> worker(2)
name: 'Linda Murphy'
age: 41
salary: [7301 7301]

An alternative way is to use the getfield function:


7.3. Object handles and the internal set and get functions 63

>> getfield(worker,{2},'salary')
7301 7301

There exists also a function setfield, which assigns values to a given field. New fields can be
added or deleted from every structure. To delete a field, use the command rmfield. Analyze
the following example:

>> worker2 = worker;


>> worker2 = rmfield (worker, 'age');
>> worker2(2).street = 'Bakerstreet 5';
>> worker2(2)
name: 'Linda Murphy'
salary: [7301 7301]
street: 'Bakerstreet 5'
>> worker2(1)
name: 'John Smith'
salary: [5900 6000 6100] % in all other substructures address field is empty
street: [] % you should assign new values for each substructure

Operating on fields and field elements is done in the same way as on any other array. Consider
the following example, where the average salary for each worker is computed.

avr salary(1) = mean (worker(1).salary);


avr salary(2) = mean (worker(2).salary);

Remark: structures as a concept are common organisations of data in other programming


languages. They are created in different ways, but the intention remains the same.

Exercise 7.2.
Construct a structure friend, with the following fields: name, address, age, birthday. Insert
a few friends with related information. Remove e.g. the field age and add the field phone. 

Concerning the use of lists and parentheses in Matlab, please see help lists and help paren.

General remark: Classes and objects allow for adding new data types and new operations to
Matlab. For instance, the class of a variable describes the structure of the variables and the
operations permitted as well as functions to be used. An object is an instance of a particular
classs. The use of classes and objects is the base of object-oriented programming, which is also
possible in Matlab.

7.3 Object handles and the internal set and get functions

Everything MATLAB creates is an object, with children and parents very similar to OOP in
C++. Understanding how this works allows very fine control over the internal working of
MATALB. Everything in MATLAB has a unique handle (a way of identifying it). A simple
handle example would be a figure handle,

>> a=figure;
a=
7.3. Object handles and the internal set and get functions 64

The value assigned to a is the handle of the new figure. Note, figure are always assigned integers,
starting at 1 for the first figure you create. Now you can view all the properties of this figure
using the get command, which is the internal version of getfield. The same information is
also obtained by double clicking on f in the workspace.

>> get(a)
Alphamap = [ (1 by 64) double array]
CloseRequestFcn = closereq
Color = [0.8 0.8 0.8]
Colormap = [ (64 by 3) double array]
CurrentAxes = []
CurrentCharacter =
CurrentObject = []
CurrentPoint = [0 0]
DockControls = on
DoubleBuffer = on
FileName =
FixedColors = [ (3 by 3) double array]
IntegerHandle = on
InvertHardcopy = on
KeyPressFcn =
KeyReleaseFcn =
MenuBar = figure
MinColormap = [64]
Name =
NextPlot = add
NumberTitle = on
PaperUnits = inches
PaperOrientation = portrait
PaperPosition = [0.25 2.5 8 6]
PaperPositionMode = manual
PaperSize = [8.5 11]
PaperType = usletter
Pointer = arrow
PointerShapeCData = [ (16 by 16) double array]
PointerShapeHotSpot = [1 1]
Position = [360 280 560 420]
Renderer = None
RendererMode = auto
Resize = on
ResizeFcn =
SelectionType = normal
ToolBar = auto
Units = pixels
WindowButtonDownFcn =
WindowButtonMotionFcn =
WindowButtonUpFcn =
WindowScrollWheelFcn =
WindowStyle = normal
XDisplay = localhost:10.0
XVisual = [ (1 by 59) char array]
XVisualMode = auto

BeingDeleted = off
ButtonDownFcn =
Children = []
Clipping = on
CreateFcn =
7.3. Object handles and the internal set and get functions 65

DeleteFcn =
BusyAction = queue
HandleVisibility = on
HitTest = on
Interruptible = on
Parent = [0]
Selected = off
SelectionHighlight = on
Tag =
Type = figure
UIContextMenu = []
UserData = []
Visible = on

These are all the properties of a figure in MATLAB, and manipulating these allows you too fine
tune many things from within your script files. This brings us to the set command which allows
us to set properties of anything internal in MATLAB (that does not have to be a figure). For
example

>> set(a,'name','MyFigure');
>> a.Name = 'MyFigure';

gives your figure the name ‘MyFigure’. The second way of assigning a value to a built-in handle,
which unlike the first is case sensitive, was introduced recently to conform with the accessing of
structures.

Now lets plot something on out figure. Type the following

>> figure(a);
>> b = ezplot('sin');
b=
317.0021

The first line makes sure that the figure with handle a is the active figure, the second command
plots the sin function in this figure. This time the returned value is 317.0021 and the handle
is assigned to the variable b. In recent versions of Matlab, rather than a ‘random’ numerical
value you receive some more informative information,

>> figure(a);
>> b = ezplot('sin')

b =

Line with properties:

Color: [0 0.4470 0.7410]


LineStyle: '−'
LineWidth: 0.5000
Marker: 'none'
MarkerSize: 6
MarkerFaceColor: 'none'
XData: [1 4 3 4 double]
YData: [1 4 3 4 double]
ZData: [1 0 double]

Show all properties


7.3. Object handles and the internal set and get functions 66

You can now make the line of this plot thicker via the either command

>> set(b,'LineWidth',10);
>> b.LineWidth = 10;

7.3.1 Parents and children

MATLAB has a hierarchal structure: a figure can have many axes and each axis can have
many plots. The relationship between figure, axes and plots is maintained by the Parent and
Children fields. This is illustrated by the following example.

fig1 = figure;
plot1 = ezplot('sin');
hold on;
plot2 = ezplot('cos');

The hold on makes sure the plots are on the same axes. Now notice that get(fig1,’Children’)
returns the same as get(plot1,’Parent’) and get(plot2,’Parent’): all three yield the han-
dle of the axes in the figure. Now get a hold on this axes handle using one out of three options,
e.g. axes1 = get(fig1,’Children’) or axes1 = plot2.Parent. Notice that axes1 has a number
of fields specifying the properties of the axes, as well as two children referring to the two plots
on these axes. Try what happens when you type

>> axes1.YLabel.String='Sin and Cos';


>> axes1.Children(1).LineWidth = 5;
>> fig1.Children.Children(2).LineWidth = 5;
>> axes1.Parent.Name = 'EZplot';

This has been a very superficial overview of the power of the set and get commands, but once
you understand the basics it is a simple job to manipulate these figure properties to give you
very fine control.

Exercise 7.3.
Write a function which takes a figure handles and will change the line width of all plots on the
figure to 10. Hint, you need to get all axes first and then all plots on each of the found axes. 

Exercise 7.4.
Check the default value for the following figure properties

• PaperUnits

• PaperType

• Units


7.3. Object handles and the internal set and get functions 67

Exercise 7.5.
The default for Matlab is American units. Write a script file that takes a figure file and changes
all the setting to metric standards, that is,

• Paper Units to centimeters

• Paper type to A4

• Units to centimeters

Exercise 7.6.
Write a function that takes an initially unknown list of figure handles and places then together
on one subplot matching as closely as possible the aspect of 3 plots across to 2 plot down. 
Chapter 8
File input/output operations

The easiest way to write data to a formatted file is the save -ascii command described in
chapter 1. It creates a file containing the data, but you have no control over the format nor
can you add a header clarifying the content of the file. To read a file created this way, simply
type load(’filename.txt’). In this section we will discuss commands that provide much more
control over writing to reading from file.

Matlab’s file input and output (I/O) functions read and write arbitrary binary and formatted
text files. This enables you to read data collected in other formats and to save data for other
programs as well. Before reading or writing a file, you must open it with the fopen command:

>> fid = fopen (file name, permission);

The permission string specifies the type of access you want to have:

• ‘r’ - for reading only


• ‘w’ - for writing only
• ‘a’ - for appending only
• ‘r+’ - both for reading and writing

Here is an example:

>> fid = fopen ('results.txt','w') % tries to open the file results.txt


% for writing

The fopen statement returns an integer file identifier, which acts like a handle to the file: it will
be used, rather than the file name, to refer to a specific file for input and output. When fopen
fails, e.g. when trying to open a non-existing file, the file identifier becomes −1. It is possible
to get a more detailed error message, by storing the second (optional) output argument.

– 68 –
8.1. Formatted files 69

It is good practice to test the file identifier every time you open a file. The example below keeps
asking the user for a file name, until the name of a readable file is given:

fid = 0;
while fid < 1
fname = input ('Open file: ', 's');
[fid, message] = fopen (fname, 'r');
if (fid == −1)
disp (message);
end
end

Exercise 8.1.
Create a script with the above code and check its behavior when you give a name of a non-
existing file (e.g. noname.txt) and that of an existing readable file (e.g. one of your functions).


When you finish working on a file, use fclose to close it. Matlab automatically closes all open
files when you exit it. However, you should close your files when you finish using them:

fid = fopen ('results.txt', 'w');


...
fclose(fid);

as this, among others, informs the operating system that the file is again available to other users.

Type also help fileformats to find out which file formats are readable in Matlab.

8.1 Formatted files

Files using the American Standard Code for Information Interchange (ASCII) contain text and
numbers in a human-readable format, hence they are referred to as ‘formatted’. This makes
them user-friendly, but also bulky if you want to store floats up to machine precision. The more
compact ‘binary files’ are preferred when storing large amounts of data, but they are not easily
read (try reading a Matlab figure file) and are therefore called ‘unformatted’. We will here
stick with formatted files, and briefly discuss one type of binary files (for Excel) in section 8.2.

8.1.1 Writing formatted files

For more control over the output file we use fprintf. This command converts data to character
strings and displays the resulting string on screen or writes it to a file. The general syntax is:

fprintf (fid,format,a,...)

For a more detailed description, consult Matlab’s ‘Reference page for fprintf’ (the link can be
found at the bottom of help fprinf). Consider the following example:
8.1. Formatted files 70

>> x = 0:0.1:1;
>> y = [x; exp(x)];
>> fid = fopen ('exptab.txt','w');
>> fprintf(fid, 'Exponential function\n');
>> fprintf(fid, '%6.2f %12.8f\n',y);
>> fclose(fid);

Exercise 8.2.
Prepare a script that creates the sintab.txt file containing a short table of the sinus function.


8.1.2 Reading formatted files

Reading a formatted data file requires no more effort than

>> fid = fopen('filename.txt','r');


>> C = textscan(fid, '%s', 'delimiter', '\n');
>> fclose(fid);

where ’%s’ tells Matlab to interpret the file as a collection of strings, and ’delimiter’,’\ n’
specifies that all information on the same line belongs together. The entire file is now loaded
into the cell array C, with the fifth line of the file stored as a string in C{1}{5}. This string is
readily converted into numbers using str2num. Note that this command can also be used to
distinguish between the (text-based) header lines and (number-based) data lines.

Exercise 8.3.
Extend the above script to read your sintab.txt file and plot the data. 

When the fixed format of the data file is known, one may also use

>> fid = fopen('filename.txt','r');


>> A = textscan(fid, '%s', 1, 'delimiter', '\n'); % 1 header line
>> B = textscan(fid, '%6.2f %12.8f', 'delimiter', '\n'); % data lines
>> fclose(fid);

The data are now contained, as numbers, in the cell array B.

Exercise 8.4.
Extend the above script to read your sintab.txt file and plot the data. 

Exercise 8.5.
Create a script that reads your sintab.txt file and at the end of that file adds, after a blank
line, a matching series of cosine values. Note that you should open the file both for reading and
writing. 

The older Matlab commands to read files, like are fscanf, fgetl and dlmread, are less user-
friendly.
8.2. Excel files 71

8.2 Excel files

Using xlswrite and xlsread you can use Matlab to exchange data with Microsoft Excel via
a spreadsheet file (.xls)

This example writes the following mixed text and numeric data to file,

>> d = {'Time', 'Temp'; 12 98; 13 99; 14 97};


>> xlswrite('tempdata.xls', d, 'Temperatures', 'E1')

Exercise 8.6.
Run the above script and open the resulting file in Excel. 

Exercise 8.7.
Prepare a script that creates the costab.xls file containing a short table of the cosine function.


Exercise 8.8.
Create a table of data in Excel, save the data as an xls-file, and import the data in Matlab. 
Chapter 9
Writing and debugging Matlab programs

The recommendations in this section are general for programming in any language. Learning
them now will turn out to be beneficial in the future and while learning ‘real’ programming
languages like C/C++, where structured programming is indispensable.

9.1 Structural programming

Never write all code at once; program in small steps, and make sure that each of these small
steps works as expected, before proceeding to the next one. Each step should be devoted to
only one task. Do not attempt to solve too many tasks in one module, because you may easily
end up with a mess. This is called a structured or modular way of programming. Formally,
modularity is the hierarchical organisation of a system or a task into self-contained subtasks and
subsystems, each having a prescribed input-output communication. It is an essential feature of
a well designed program. The benefits of structural programming are: easier error detection and
correction, modifiability, extensibility and portability.

A general approach to program development:

1. Specification.
Read and understand the problem. The computer can not do anything itself: you have to
tell it how to operate. Before using the computer, some level of preparation and thought
is required. Some basic questions to be asked are:
• What are the parameters/inputs for this problem?
• What are the results/outputs for this problem?
• What form should the inputs/outputs be provided in?
• What sort of algorithms is needed to find the outputs from the inputs?

2. Design.
Split your problem into a number of smaller and easier tasks. Decide how to implement

– 72 –
9.1. Structural programming 73

them. Start with a schematic implementation to solve your problem, e.g. create function
headers or script descriptions (and decide about the input and output arguments). To do
this, you may use, for example, a top-down approach. You start at the most general level,
where your first functions are defined. Each function may be again composed of a number
of functions (or subfunctions). While ‘going down’ your functions become more precise
and more detailed.
As an example, imagine that you have to compare the results of a given problem for two
different datasets, stored in the files data1.dat and data2.dat. Schematically, such a
top-down approach could be designed as:

• At the top (the most general) level, a script solve it is created:

d1 = read data( 'data1.dat' );


d2 = read data( 'data2.dat' );
[res1, err1] = solve problem( d1 );
[res2, err2] = solve problem( d2 );
compare results( res1, res2, err1, err2 );

• At the second level one defines the functions called at the first level, read data,
solve problem and compare results. Each of them is contained in a separate m-
file:
◦ function d = read data( fname )
% Here should be some description.
%
fid = fopen( fname,'w' );
.... % check whether the file fname exists
fclose( fid1 );
d = ... % read the data from file
return;

◦ function [res, err] = solve problem( d )


% Here should be some (possibly detailed) description.
%
....
res = ... % the data d is used to compute res
err = compute error( res );
return;

◦ function compare results( res1, res2, err1, err2 )


% Some description.
tol = 1e−6; % always place 'constants' at the top
....
if abs( err1 − err2 ) > tol
fprintf('The difference is significant.')
else
fprintf('The difference is NOT significant.')
end;
return;

• The third level is the last level in this simple example. Here we define the funtion
compute error called from the second level by compare results.
◦ function err = compute error( res )
% Here should be some (possibly detailed) description.
%
....
err = .... % here res is used to compute err
return;
9.2. Debugging 74

3. Coding.
Implement the functions sequentially, i.e. one by one. Turning your algorithm into an
efficient code is not a one-shot process. You will have to try, make errors, correct them
and even modify the algorithm. So, be patient and test your functions one by
one. While implementing, make sure that all your outputs are computed at some point.
Remember to insert comments and stick with the style requirements (see section 9.3).

4. Running and debugging (see also section 9.2).


Bugs will exist in any newly written program. Never, ever, believe or assume that a code
you just created will work. Always check the correctness of each function or script,
twice if not thrice. You may add extra lines to your code to present intermediate results
(simple displays, plots, writes to files) to help you verify what is going on. Those lines can
be out-commented for re-use, or at a later stage can be removed entirely.

5. Testing and Verification.


After the debugging process, the testing stage starts. Prepare a number of tests to verify
whether your program does what it is expected to do under well-defined conditions. Re-
member that good tests are those for which the answers are known. Your program should
produce correct results for normal test conditions as well as boundary conditions.
When writing large code, the amount of code written for testing purposes often exceeds
the actual number of lines in the application, and likewise the time spend testing the code
often well exceeds the time it took to write the code.

6. Maintenance.
In solving your task, new ideas or problems may appear. Some can be interesting and
creative, while others can help you to understand the original problem better; you may
see an extension to your problem or a way to incorporate new things. If you have a well-
designed code, you will be able to easily modify it after some time. Take the responsibility
to improve your code and correct any errors you detect when running it.

9.2 Debugging

Debugging is the process by which you isolate and fix any problem(s) with your code. Four
kinds of errors may occur:

• Syntax errors.
These are violations against the ‘grammar’ of a language. Already while editing a script or
function m-file, the Matlab editor will indicate possible syntax errors. Add for instance
the following line to one of your m-files:

x = 2pi;

There should appear a marker on the right side of the edit window. Moving the cursor over
this mark will reveal a message ‘Parse error at ‘pi’: usage appears to be invalid MATLAB
syntax’.

• Runtime errors
These are errors that surface when you perform an incorrect command, like accessing the
9.2. Debugging 75

zeroth element of an array, division by zero, etc. These are fairly easy to detect, as they
cause your code to crash. Read the error message and solve the problem. If there are
multiple messages, always start at the top; the second message is often a consequence of
the first error. Note that the actual error may have occurred one or several lines before
the error message.

• Coding errors
It is easy to make typos (or worse) in a code that prove non-fatal, like replacing an i
with a j or a 1. That is, your code will ‘successfully’ run to the end but the output is
incorrect. These errors are more difficult to track down because they do not shout ‘I am
here.’ Always try to test your code (and individual functions) with input for which you
know the correct output. Look at intermediate results to see where things start to go
wrong.

• Algorithmic errors
The worst errors are those where, after a long time of rereading and testing whether the
implementation is correct, you arrive at the conclusion that algorithm is flawed. You
have to improve the algorithm, or come up with a new one, implement it, and restart the
debugging process all over (minus those functions that already passed the tests).

Debugging is an inevitable process. The best way to reduce the possibility of making errors
is defensive programming:

• Do not assume that input is correct, always check.


• Where reasonable and possible, provide a default option or value.
• Provide diagnostic error messages.
• Optionally print intermediate results to check the correctness of your code.

Defensive programming is a part of the early debugging process. Another important part is
modularity, i.e. breaking large task into small subtasks, which allows for developing tests for
each of them more easily. You should always remember to run the tests again after changes have
been made. To make this easy, include extra print statements that can be turned on or off.

Matlab provides an interactive debugger. It allows you to set and clear breakpoints, specific
lines in an m-file at which the execution of a program will halt (click on the minus-sign in front
of a line, it turns into a red circle when a breakpoint is set). You can then run the code till this
point, to gain access to the local workspace of a function and to step through the next lines one
by one. The debugging process can also be started from the command line. Use the dbstop
command to determine what errors to ‘trap’. Particularly useful options are

dbstop if error % stop at fatal error


dbstop if infnan % stop at numerical errors

This will stop your code when an error of the specified type(s) occurs. Rather than returning
just the error message, you are dropped in the code at the location of the error. At the command
prompt, which has changed into K>>, you can ask for the values of specific variables, to advance
a step (dbstep), continue execution (dbcont), etc, to help you find the bug. To leave the debug
mode, type dbquit. To clear all debugging flags, and thereby return to Matlab’s default error
handling, use dbclear all.
9.3. Recommended programming style 76

9.3 Recommended programming style

Programming style is a set of conventions that programmers follow to standardise their code to
some degree and to make the overall program easier to read and to debug. This will also allow
you to quickly understand what your program does when you look at it weeks or months from
now. The style conventions are for the reader only, but you will become that reader one day.

Some style requirements and style guidelines are presented below. These are recommendations,
and some personal variations in style are acceptable, but you should not ignore them. It is
important to organise your programs properly since it will improve the readability, make the
debugging task easier and save time of potential readers.

1. You should always comment difficult parts of the program! But ... do not explain the
obvious.

2. Comments describing tricky parts of the code, assumptions or design decisions, are best
placed above the part of the code you are documenting. Try to avoid big blocks of com-
ments, except for the description in the m-file header.

3. Indent a few spaces (preferably 2 or 3) all lines of code and comments inside control flow
structures. Here is an example:

x = 0:0.1:500;
for i=1:length(x)
if x(i) > 0
s(i) = sqrt(x(i));
else
s(i) = 0;
end
end

The Matlab m-file editor will introduce such spaces by default. To reset the indenting,
select all lines (¡ctrl¿¡a¿) and press ¡ctrl¿¡i¿.

4. Avoid the use of magic numbers; use a constant variable instead. When you need to change
the value, you will have to do it only once rather than search throughout your code. An
example:

% A BAD code with magic numbers % This is the way it SHOULD be


r = rand(1,50); n = 50; % number of points
for i = 1:50 r = rand(1,n);
data(i) = i * r(i); data = (1:n) .* r;
end
y = sum(data)/50; avr = sum(data)/n;
disp(['Number of points is 50.']); disp(['Number of points is ',...
int2str(n)]);

Note that a hard-coded 50 will often also give rise to hard-coded 49s and 51s, making it
difficult to track down all occurances of your ‘50’. And this gets worse if there are two
hard-coded numbers that both happened to be 50 when you wrote the code.

5. Avoid the use of more than one code statement per line in your script or function m-files.
9.4. Commenting and publishing in MATLAB 77

6. No line of code should exceed the screen width (it is a rare case when this is not possible).
When necessary, use the Line Continuation Symbol, i.e. the characters ..., at the end of
a line of to indicate that the expression continues on the next line.
7. Avoid declaring global variables. You will hardly ever encounter a circumstance under
which you will really need them. Global variables can easily get you into trouble without
you noticing it!
8. Variables should have meaningful names. You may also use the standard notation, e.g.
x, y are real-valued, i, j, k are indices or n is an integer. This will reduce the number
of comments and make your code easier to read. However, here are some pitfalls when
choosing variable names:
• A meaningful variable name is good, but when it gets longer than 15 characters it
tends to obscure rather than improve the code readability.
• Be careful with names since there might be a conflict with Matlab’s built-in functions
or reserved names like mean, end, sum etc. (check in index or ask which <name> in
Matlab– if you get the response <name> not found it means that you can safely
use it). Note that even the obvious examples i and j overwrite the built-in complex
imaginary unit i.
• Avoid names that look similar or differ only slightly from each other.

9. Use white spaces, both horizontally and vertically, since it will greatly improve the read-
ability of your program. Use blank lines to separate larger blocks of the code.

9.4 Commenting and publishing in MATLAB

There are various special ways Matlab code can be commented that both aid readability and
the ability to find your code (if it forms part of a library).

• Firstly the block of code at the top as automatically picked up by Matlabhelp and
lookfor commands.
• The code can be divided into cells or blocks by inserting two percentage signs %%. For
testing purposes each block of code can be separately executed using shift-enter.
• The code on the line with %% is the title of that code block

9.4.1 Publishing Matlab code

Matlab code can now to automatically published i.e. converted in to an html document, latex
or even word document. This is done via the publish button in the toolbar. When publishing
Matlab code there is a few each commenting conventions:

• Variables should be preceded and succeeded with an underscore i.e. k .


• Latex equations can be included using $$ i.e. % $$ sin x = 5 $$
• Each block will appear as a separate section in the published version of the code.
Chapter 10
Matlab and execution speed

Matlab is an interpreted high-level interpreted language. Consequently it is easy to write pow-


erful code, but the execution time of this code can be orders of magnitude larger than that of
a similar code written in C++, a low-level compiled language. In an compiler, the whole code
is translated from human-readable instructions into the instructions that the processor under-
stands, creating an executable (in windows recognisable by the exe-extension). This executable
can then be run directly, without requiring any interaction with the compiler (and you do not
even need to have a compiler installed to run the code). An interpreter, on the other hand,
translates only one line of code at a time, and does so when you want to execute that line.
Hence you spent a lot of effort on translating lines (basically, the inner code in a for loop is
translated very often, while some lines in an if might never be translated) which makes the
execution of your program a slow affair. And running the code outside the interpreter is not
possible. The people at Matlab are aware of this, so they offer possibilities to make your code
run quicker if you stick to certain conventions.

To recover some of the loss of speed when using Matlab, there are four golden rules:

1. Remove all for-loops where possible; see section 10.1.


2. Use the internal Matlab functions where possible; these are compiled.
3. Pre-allocate all vectors and matrices; see section 10.2.
4. Suppress all non-required output; writing to the screen is very slow.

Note that these rules only apply to Matlab code.

10.1 Vectorizing your code

Matlab is slow in executing explicit for loops. It is often possible to avoid loops all together

– 78 –
10.2. Pre-allocation of arrays 79

by using the implicit loops available in Matlab. Consider the following code:

>> clear all;


>> tic; k=1e7; x=rand(k,1); for i = 1:k; x(i) = sqrt(exp(sqrt(x(i)))); end; toc
Elapsed time is 2.020193 seconds.

This calculation can be vectorised by simply writing

>> clear all


>> tic; k=1e7; x=rand(k,1); x = sqrt(exp(sqrt(x))); toc
Elapsed time is 0.532375 seconds.

The second form runs faster.

10.2 Pre-allocation of arrays

Vectors that grow inside a for-loop can become very slow. A notorious example is concatenation:

>> clear all


>> tic; k = 1e5; x = []; for i = 1:k ; x=[x i]; end; toc
Elapsed time is 9.809436 seconds.

The run time of this piece of code goes like k!, making it extremely slow for large k. A major
performance improvement is obtained by rewriting the code as

>> clear all


>> tic; k = 1e7; for i = 1:k ; x(i) = i; end; toc
Elapsed time is 1.261517 seconds.

Note that in this second example the value of k is 100 times as high as in the first example, yet
the run time is nearly an order of magnitude shorter. One can gain another order of magnitude
by claiming the maximum array size of x before entering the loop,

>> clear all


>> tic; k=1e7; x(k)=0; for i = 1:k ; x(i) = i; end; toc
Elapsed time is 0.104670 seconds.

Exercise 10.1.
Write a function to sort a set of n numbers into order. Measure the run time of your code as
a function of n, and plot the run time against n on a double logarithmic plot. Compare the
performance of your code with that of the internal sort function. 

Exercise 10.2.
Create an (n × n) random matrix. Use a for loop and an if statement to count how many
elements in the matrix are greater than 1/2. Measure and plot the run time of your as a function
of n. Compare the performance of you code against that of a code using internal function only.

Chapter 11
Visualisation

Matlab includes powerful features for easy figure creation, plotting and image display. These
can be used to visualise the results of an experiment or calculation in Matlab. We will start
by introducing the most basic features here.

11.1 2D plots

The most important commands for basic 2-dimensional plotting are illustrated in the following
example:

x=0:0.1:10; % x ranges from 0 to 10 in steps of 0.1


y=sin(x); % y contains the sin of each value of x
figure % create an empty figure window
plot(y) % plots all of the y values (the values on the x−axis are
% indexes from 1 to 101)
figure % create an empty figure window
plot(x,y) % plots y against x (replacing the old plot on the same
% figure, now showing the units of x on the x−axis)
close % closes the active figure window

Note that x and y can be row and/or column vectors, but must be of the same length.

The plot command produced a plot in the active figure window, replacing the existing plot in
that window. A new window can be created with figure or figure(5); the latter command
can also be used to reactivate figure 5 (which is not necessarily the 5th figure).

To plot a graph of a function, it is important to sample the function sufficiently well. Compare
the following examples:

– 80 –
11.1. 2D plots 81

1 % coarse sampling 0.8

0.6
2 n = 5; 0.4

3 x = 0:1/n:3; 0.2

0
4 y = sin(5*x); −0.2

5 plot(x,y) −0.4

−0.6

−0.8

−1
0 0.5 1 1.5 2 2.5 3

0.8

0.6

1 % good sampling 0.4

0.2
2 n = 25; 0

3 x = 0:1/n:3; −0.2

−0.4
4 y = sin(5*x); −0.6

5 plot(x,y) −0.8

−1
0 0.5 1 1.5 2 2.5 3

The plot command has many additional possible arguments, as can be seen by typing help
plot. A list of common auxiliary commands is provided in Table 11.1. There are also many
other plotting commands for 2-dimensional plotting (help graph2d) and also for 3-D plotting
(help graph3d). You can close a figure window by clicking on the upper right X box, using the
‘close’ command on the figure’s file menu, or by typing close at the command prompt. Use
close all to close all figures and start a new task, or use close 3 to close Figure no.3. To
clean a plot without closing the window, use cla.

The colour and point marker can be changed on a plot by adding a third parameter (in single
quotes) to the plot command. A list of colours and styles is reported in Table 11.2. For example,

Command Result
grid on/off adds a grid to the plot at the tick marks or removes it
box off/on removes the axes box or shows it
axis([xmin xmax ymin ymax]) sets the minimum and maximum values of the axes
xlabel(’text’) plots the label text on the x-axis
ylabel(’text’) plots the label text on the y-axis
zlabel(’text’) plots the label text on the z-axis
title(’text’) plots a title above the graph
text(x,y,’text’) adds text at the point (x,y)
gtext(’text’) adds text at a manually (with a mouse) indicated point
legend(’fun1’,’fun2’) plots a legend box (move it with your mouse) to name
your functions
legend off deletes the legend box
clf clear the current figure
figure(n) creates a figure #n or activates existing figure #n.
subplot creates a subplot in the current figure

Table 11.1: Useful commands when making plots.


11.2. Several functions in one figure 82

Symbol Color Symbol Line style


r red ., o point, circle
g green * star
b blue x, + x-mark, plus
y yellow - solid line
m magenta -- dash line
c cyan : dot line
k black -. dash-dot line

Table 11.2: Plot colors and styles.

to plot the function as a red, dotted line,

x = 0:0.1:100;
y = 3*x;
plot(x,y,'r:')

11.2 Several functions in one figure

You can plot more than one function in the same figure. To plot a sine wave and cosine wave
on the same set of axes, using a different color and point marker for each, the following m-file
can be used:

x = 1:0.1:2*pi;
y = sin(x);
z = cos(x);
plot(x,y,'r', x,z,'gx')

By adding more sets of parameters to plot, you can plot as many different functions on the
same figure as you want. The same effect can also be achieved using the hold on and hold off
commands. The same plot shown above could be generated using the following m-file:

x = linspace(0,2*pi,50);
y = sin(x);
z = cos(x);
hold on
plot(x,y,'r')
plot(x,z,'gx')
hold off

Always remember that if you use the hold on command, all plots from then on will be generated
on one set of axes, without erasing the previous plot, until the hold off command is issued.
When plotting many data sets in the same graph it is useful to differentiate the various functions
by colour and markers.
11.3. Adding text 83

It is also possible to produce several subplots in one figure window. With the command subplot,
the window can be horizontally and vertically divided into x × y subfigures, which are counted
from 1 to x ∗ y, row-wise, starting from the top left. The commands: plot, title, grid etc
work only in the current subfigure. So, if you want to change something in another subfigure,
use the command subplot to switch there.

x = 1:.1:4;
y1 = sin(3*x);
y2 = cos(5*x);
y3 = sin(3*x).*cos(5*x);
figure
subplot(1,3,1);
plot(x,y1,'m');
title('sin(3*x)')
subplot(1,3,2);
plot(x,y2,'g');
title('cos(5*x)')
subplot(1,3,3);
plot(x,y3,'k');
title('sin(3*x) * cos(5*x)')

11.3 Adding text

Another thing that may be important for your plots is labeling. You can give your plot a title
(with the title command), x-axis label (with the xlabel command), y-axis label (with the
ylabel command), and put text on the actual plot. All of the above commands are issued after
the actual plot command has been issued.

Text can be put on the plot itself in one of two ways. The text(xcor,ycor,’textstring’)
command involves knowing the coordinates of where you want the text string to appear (in
terms of the coordinate values along the axes of the plot). With gtext(’textstring’) you use
the mouse to select a position.

To add a title, grid and to label the axes, one uses:

x=0:0.1:3;
y=sin(x);
z=cos(x);
hold on;
plot(x,y);
plot(x,z);
title('Sine and Cosine')
xlabel('x')
ylabel('sin(x) and cos(x)')
gtext('unnecessary labeling')
legend('sin','cos')

To drop the text ‘unnecessary labelling’, place the mouse in the figure window and click on
the desired spot. Note that LATEX-style commands are accepted, e.g. xlabel(’\alpha^2’) to
produce the label α2 .
11.4. Changing the axes 84

11.4 Changing the axes

The commands loglog, semilogx and semilogy are similar to plot, except that they use either
one or two logarithmic axes.

An important way to customise your plots to meet your needs is by the axis, xlim and ylim
commands. They change the range of the plot to be shown, so only the desired part of the graph
is displayed. The command(s) apply to the currently active plot.

axis([xmin, xmax, ymin, ymax])


axis('auto x')
xlim([−Inf,3])
ylim('auto')

The options -Inf, +Inf and auto leave the decision to Matlab. The axes can also be adjusted
interactively.

11.5 Fine-tuning plots

Matlab automatically formats a graph to provide readability, sets the scales of the axes, includes
tick marks on the axes, and uses color and line style to distinguish the plots in the graph.
However, you may want to change this default formatting or add descriptive labels, titles,
legends and other annotations to help explain your data. Matlab supports three ways to edit
the plots you create:

• Property Editor to select and edit objects interactively.

• Matlab functions at the command-line or in an M-file (look at ”Line Properties” in the


help for the list of properties).

figure
hold on
x = 1:.1:4;
h1 = plot(x,cos(x))
h2 = plot(x,sin(x))
set(h1,'LineWidth',2,'LineStyle','.','Color','g')
set(h2,'LineWidth',2,'LineStyle','ˆ','Color','r')
hold off

In this example, h1 and h2 are handles (basically pointers to objects, see the C++ part
of the course). We happily ignore the values Matlab returns to command window when
the handle is created. The function get(h1) returns all properties of the handle h1, which
can then be adjusted by set(h1,...) to touch up the plot. Alternatively, click on h1 in
the workspace to interactively set the values.

• One may also use figure handle for additional tuning, see Section 7.3.
11.6. Saving graphics 85

11.6 Saving graphics

To store a figure, so one can resume editing at a later time, simply type savefig(’filename’)
and Matlab will add the extension ‘.fig’. This will store the plotted data as well as all make-
up. Use openfig(’filename’) to open the figure and continue where you left off. One can also
use open(’filename.fig’), where the extension is obligatory. Similar save and open options
are also available interactively.

When handles are available to access figures, one may use either hgsave(h1,’filename’) or
saveas(h1,’filename’) to save the figure and h1=hgload(’filename’) to reload it.

11.7 Exporting graphics

To copy the plot into Word you can select directly on the figure

Edit → Copy Figure

You can also ‘print’ to file by specifying a file name. From the command line, print achieves
the same result. Since they are many parameters, they will not be explained here (check help
print to learn more). Instead, try to understand the examples:

% print the current Figure to the current printer in color


print −dwinc
% print Figure no.1 to file in encapsulated postscript, black and white
print −f1 −deps myfile.eps
% print Figure no.1 to file in encapsulated postscript, color
print −f1 −depsc myfilec.eps
% print the current Figure in a picture format
print −dtiff myfile1.tiff
% print the current Figure in postscript, color
print −dpsc myfile1c.ps
% print Figure no.2 in a picture format
print −f2 −djpeg myfile2

11.8 Plotting surfaces

Matlab provides a number of commands to plot 3D data. Some surfaces can be defined by a
function f (x, y), where for each pair of (x, y), the height z is computed as z = f (x, y). To plot
a surface, a rectangular domain of the (x, y)-plane should be sampled. The mesh (or grid) is
constructed by using the command meshgrid as follows:

[X, Y] = meshgrid (−1:.5:1, 0:.5:2)


X =
−1.0000 −0.5000 0 0.5000 1.0000
−1.0000 −0.5000 0 0.5000 1.0000
11.8. Plotting surfaces 86

−1.0000 −0.5000 0 0.5000 1.0000


−1.0000 −0.5000 0 0.5000 1.0000
−1.0000 −0.5000 0 0.5000 1.0000
Y =
0 0 0 0 0
0.5000 0.5000 0.5000 0.5000 0.5000
1.0000 1.0000 1.0000 1.0000 1.0000
1.5000 1.5000 1.5000 1.5000 1.5000
2.0000 2.0000 2.0000 2.0000 2.0000

Next, we calculate the heights z corresponding to these (x, y) pairs and plot the surface with
the command mesh or surf:

[X,Y] = meshgrid(−1:.05:1, 0:.05:2);


Z = sin(5*X) .* cos(2*Y);
mesh(X,Y,Z);
title ('Function z = sin(5x) * cos(2y)')

Use colormap to define different colours for plotting.

More general, a 2D surface in a 3D space can be described by two curvi-linear coordinates (u, v)
with the 3D Cartesian coordinates calculated as x = x(u, v), y = y(u, v) and z = z(u, v). The
ensuing calculations are similar to the above example, see exercise 11.11.

Returning to z = f (x, y), a 2D contour plot displays isolines calculated from the matrix z.

[X,Y] = meshgrid(−2:.05:2,−2:.05:3);
Z = X.*exp(−X.ˆ2−Y.ˆ2);
figure
contour(X,Y,Z,15) % just the contour lines
figure
contourf(X,Y,Z,25) % with 'filled' area
colormap hsv
close

3 3

2.5 2.5

2 2

1.5 1.5

1 1

0.5 0.5

0 0

−0.5 −0.5

−1 −1

−1.5 −1.5

−2 −2
−2 −1.5 −1 −0.5 0 0.5 1 1.5 2 −2 −1.5 −1 −0.5 0 0.5 1 1.5 2

Figure 11.1: Output of the contour and contourf example

If you like the coloured filling but don’t like the contour lines, they can be turned off by adding
the two (comma separated) keywords ’EdgeColor’ and ’none’ to contourf [ or contour :-) ].
11.9. 3D line plots 87

To locate e.g. the minimum value of the function the function z = x exp(−x2 − y 2 ) on the grid,
you can proceed as follows:

[X,Y] = meshgrid(−2:.05:2,−2:.05:3);
Z = X.*exp(−X.ˆ2−Y.ˆ2);
[mm,I] = min(Z); % a row vector of the min. elements from each column
% I is a vector of corresponding
[∼, j] = min (mm); % j is the index of the minimum value; the tilde sign
% suppresses the output of the minimum value itself
xpos = X(I(j),j); %
ypos = Y(I(j),j); % position of the minimum value
contour (X,Y,Z,25);
xlabel('x−axis'); ylabel('y−axis');
hold on
plot(xpos,ypos,'*');
text(xpos+0.1,ypos,'Minimum');
hold off

11.9 3D line plots

The command plot3 to plot lines in 3D is equivalent to the command plot in 2D. The format
is the same as for plot, be it with an extra coordinate. An example is plotting the curve r
defined parametrically as r(t) = [t sin(t), t cos(t), t] over the interval [−10 π, 10 π].

t = linspace(−10*pi,10*pi,200);
plot3(t.*sin(t), t.*cos(t), t, 'md−'); % plot the curve in magenta
title('Curve r(t) = [t sin(t), t cos(t), t]');
xlabel('x−axis');
ylabel('y−axis');
zlabel('z−axis');
grid

11.10 Animations

You can make a movie using Matlab by saving a sequence of graphs into a video file. To do this,
create a VideoWriter variable that stores the properties of the video file, such as frame rate, con-
tainer type (typically avi), compression type (if in doubt, use ’none’). Use open(videoWriter)
to create the video file and writeVideo(videoWriter,frame); to write frames into a video file,
then close it with close(videoWriter). Frames are rgb images, and can be created from a
figure using the get frame command (see doc getframe). All frames need to be the same size,
which is enforced by the command set(gca,’nextplot’,’replacechildren’).
Example 11.1:
Create a movie of an evolving function curve in the interval 4 π.

videoWriter = VideoWriter('video.avi'); %create VideoWriter object


videoWriter.FrameRate=10; %change properties like the frame rate
open(videoWriter); %open avi file for writing
11.11. Exercises 88

%Generate initial data and set axes and figure properties.


x=linspace(−pi,pi,30);
y=x;
[X,Y]=meshgrid(x,y);
Z=sin(X).*cos(Y);
surf(X,Y,Z)
set(gca,'nextplot','replacechildren'); %enforces a constant axis size
%set(gcf,'Renderer','zbuffer'); %needed on some windows systems
axis tight

% Create a set of frames and write each frame to the file.


for t = 0:0.02:1
surf(X,Y,sin(2*pi*t)*Z)
frame = getframe % converts figure content into rgb values
writeVideo(videoWriter,frame); %write a frame into the avi file
end

close(videoWriter); % close the avi file

11.11 Exercises

Exercise 11.1.
Make a plot connecting the coordinates: (2, 6), (2.5, 18), (5, 17.5), (4.2, 12.5) and (2,12) by a
line. 

Exercise 11.2.
Plot the function y = sin(x) + x − x cos(x) in two separate figures for the intervals: 0 < x < 30
and −100 < x < 100. Add a title and axes description. 

Exercise 11.3.
Plot a circle with the radius r = 2, knowing that the parametric equation of a circle is
[x(t), y(t)] = [r cos(t), r sin(t)] for t = [0, 2π]. 

Exercise 11.4.
Plot an ellipse with semiaxes a = 4 and b = 2. 

Exercise 11.5.
2
Plot the functions f (x) = x, g(x) = x3 , h(x) = ex and z(x) = ex over the interval [0, 4] on
the normal scale and on the log-log scale. Use an appropriate sampling to get smooth curves.
Describe your plots by using the functions: xlabel, ylabel, title and legend. 

Exercise 11.6.
Make a plot of the functions: f (x) = sin(1/x) and f (x) = cos(1/x) over the interval [0.01, 0.1].
How do you create x so that the plots look sufficiently smooth? 

Exercise 11.7.
Produce a nice graph which demonstrates as clearly as possible the behavior of the function
y2
f (x, y) = xx2 +y 4 near the point (0, 0). Note that the sampling around this points should be
dense enough. 
11.11. Exercises 89

Exercise 11.8.
Plot a sphere, which is parametrically defined as [x(t, s), y(t, s), z(t, s)] = [cos(t)∗cos(s), cos(t)∗
sin(s), sin(t)] for t, s = [0, 2 π], using surf. Make first equal axes, then remove them. Use
shading interp to remove the grid of black lines (to restore the original picture, use shading
faceted). 

Exercise 11.9.
Plot the following parametric function of r and θ: [x(r, θ), y(r, θ), z(r, θ)] = [r cos(θ), r sin(θ),
sin(6 cos(r) − nθ)] for θ = [0, 2 π] and r = [0, 4]. Choose n to be constant. Observe, how the
graph changes depending on different n. 

Exercise 11.10.
2 2
Plot the surface f (x, y) = x y e−x −y over the domain [−2, 2] × [−2, 2]. Find the values and the
locations of the minima and maxima of this function. 

Exercise 11.11.
Make a 3D smooth plot of the curve defined parametrically as: [x(t), y(t), z(t)] = [sin(t), cos(t),
sin2 (t)] for t = [0, 2π]. Plot the curve in green, with the points marked by circles. Add a title,
description of axes and the grid. You can rotate the image by clicking Tools at the Figure
window and choosing the Rotate 3D option or by typing rotate3D at the prompt. Then by
clicking at the image and dragging your mouse you can rotate the axes. Experiment with this
option. 

Exercise 11.12.
Write a script that makes a movie consisting of 5 frames of the surface f (x, y) = sin(nx) sin(ky)
over the domain [0, 2π] × [0, 2π] and n = 1 : 5. Add a title, description of axes and shading. 

Exercise 11.13.
Plot an equilateral triangle with two vertices [a a] and [b a]. Find the third vertex. Use fill to
paint the triangle. 
Chapter 12
Numerical analysis

Numerical analysis can be used whenever the analytic solution to a problem is difficult or im-
possible to determine. This is often the case when analysing experimental results. Matlab
can be used to find, for example, the minimum, maximum or integral of a certain function
or of a set of experimental data. In this section we will briefly discuss some methods on nu-
merical differentiation and integration, as well as the possibility to solve differential equations
numerically.

12.1 Differentiation

The derivative of a function f (x),


df (x)
f ′ (x) =
dx
measures the slope of the function at point x. Assuming out x values are equidistant, as
illustrated in figure fig:numdiff, the three common approaches to calculating the derivative at
xk are:
f (xk ) − f (xk−1 )
backward difference : f ′ (xk ) ≈
xk − xk−1
f (xk+1 ) − f (xk )
forward difference : f ′ (xk ) ≈ (12.1)
xk+1 − xk
f (xk+1 ) − f (xk−1 )
central difference : f ′ (xk ) ≈
xk+1 − xk−1
The Matlab function diff(x) computes the differences between adjacent values of the vector
x. If the values of f (x) are contained in vector y and the corresponding x values in vector x,
the derivative of the function can be estimated using

>> dydx = diff(y) ./ diff(x);

– 90 –
12.1. Differentiation 91

Figure 12.1: Three points that can be used in the numerical evaluation of the derivative of
function f at point xk , see equation 12.1.

The resulting vector dydx contains one element less than x. The corresponding x values are
obtained from the original x vector by trimming either the first or the last value:

• trimming the last value results in the forward difference estimate.


• trimming the first value results in the backward difference estimate.

To obtain and plot the derivative of a function f (x) = 5 cos(10x) + x3 − 2x2 − 6x + 10,

>> x = 0:.01:4;
>> y = 5*cos(10*x) + x.ˆ3 − 2*x.ˆ2 − 6*x + 10;
>> subplot(2,1,1)
>> plot(x,y)
>> title('f(x)')
>> dydx = diff(y) ./ diff(x);
>> xx = x(2:end); % Backward difference x values
>> subplot(2,1,2)
>> plot(xx,dydx)
>> title('df/dx')
>> hold on
>> yy = −50*sin(10*x) + 3*x.ˆ2 − 4*x − 6; % The exact derivative
>> plot(xx,yy,'r') % Nice agreement, hopefully

Exercise 12.1.
Type and run the above script. Try and explain the following calculation of the derivative:

>> dydx = ( y(3:end) − y(1:end−2) ) ./ ( x(3:end) − x(1:end−2) );


>> plot(x(2:end−1,dydx)

Exercise 12.2.
Measurement data often contains noise. We can simulate this by adding random numbers to
our smooth data,
12.2. Integration 92

>> z = y + ( rand(1,length(y) − 0.5 )


% >> dzdx = diff(z)./diff(x);

Include the calculation and plot commands of z and its numerical derivative dzdx in the above
script and run it. Does your result improve upon decreasing the step size? What do you conclude
from the graphs, and can you explain this? 

12.2 Integration

The integral of a function f (x), i.e the surface between the x-as and a 2D plot of this function,
can also be determined numerically. A number of algorithms exists to calculate the numerical
values of definite integrals, some of which are displayed in figure fig:integ and explained below.

• Rectangle rule: the interpolating function is a constant function, i.e. a polynomial of


degree zero, passing through the point (m, f (m)), with m = (a + b)/2. Then
Z a
f (x)dx ≈ (b − a) · f (m).
b

• Trapezoidal rule: the interpolating function is a straight line, i.e. a polynomial of degree
one, passing through the end points (a, f (a)) and (b, f (b)). Then
Z a
1
f (x)dx ≈ (b − a) · [f (a) + f (b)] .
b 2

Figure 12.2: Illustrations of numerical integration by, from left to right, the rectangle rule,
trapezoidal rule and Simpson’s rule. In the top row the range from a to b is treated as one
interval, in the bottom row as two equal-width intervals.
12.3. Solving differential equations - the ODE toolbox 93

• Simpson’s rule: the interpolating function is a polynomial of degree two passes through
the end points (a, f (a)) and (b, f (b)) as well as the midpoint (m, f (m)). Then
Z a
1
f (x)dx ≈ (b − a) · [f (a) + 4f (m) + f (b)] .
b 6

As can be clearly seen in the figure, the accuracies of the various methods can be increased
by dividing the interval (a, b) into multiple sub-intervals, computing approximated areas for all
sub-intervals and then adding up all the partial results.

12.2.1 Matlab commands

Matlab has several commands to determine the integral of a function. One of these commands
is trapz, which uses the trapezoidal rule,

>> x = 0:0.5:10; y = 0.5 * sqrt(x) + x .* sin(x);


>> int1 = trapz(x,y)
int1 =
18.1655

>> x = 0:0.05:10; y = 0.5 * sqrt(x) + x .* sin(x);


>> int2 = trapz(x,y)
int2 =
18.3846

Evidently, the accuracy of the computed integral depends on the distance between consecutive
data points.

A more accurate result is obtained by using the command integral, which numerically evaluates
the integral of a function using an adapted Simpson’s rule. Where the input for trapz consists
of two vectors, we sent a function as input to integral, as illustrated by the following example.

>> f = @(x) 0.5*sqrt(x) + x.*sin(x) % Integral requires dot operators


f =
function handle with value:
@(a)0.5*sqrt(x)+x.*sin(x)
>> f([1 2 3]) % Test of dot operators
>> int3 = integral(f,0,10)
int3 =
18.3876

12.3 Solving differential equations - the ODE toolbox

Without going into mathematical details, we want to point out that one has to be very careful
when using Matlab’s ODE toolbox as a black box solver for ordinary differential equations
(ODEs). It is e.g. important to distinguish between so-called stiff and non-stiff ODEs. Nu-
merical methods that work perfectly fine for non-stiff ODEs can become numerically unstable
when applied to stiff equations, unless the integration step is taken to be extremely small. Here
12.3. Solving differential equations - the ODE toolbox 94

we discuss the ode45 solver, based on the Runge-Kutta method, which can be used for non-
stiff problems only. Note that Matlab provides dedicated solvers for stiff ODEs, like ode15s,
ode23s, ode23t and ode23tb.

12.3.1 First order ODE

Example 12.1:
Solve the following ODE of first order

dy
= x y 2 + y, with boundary condition y(x = 0) = 1,
dx
in the interval x ∈ [ 0, 0.5 ].

For any differential equation of the form dy/dx = f (x, y), we begin by defining the function
f (x, y). In this particular case, f (x, y) is sufficiently compact to be defined as an inline
function, which simplifies the procedure. The basic usage for Matlab’s solver ode45 is

ode45(function,domain,initial condition)

Thus, we can formulate the problem as

>> f = inline('x*yˆ2+y'); % ode45 does not require dot operators


>> [x,y] = ode45( f, [0 0.5], 1 );
>> plot(x,y)

To ‘solve’ the ODE numerically, ode45 feeds an intermediate point (x, y) to your function, so
upon receiving the derivative at that point in reply it can take an integration step to arrive at the
next point (x, y), and so on. Note that ode45 has selected a certain optimized (non-equidistant)
discretization x on the interval [ 0, 0.5 ] and it has returned in y the approximate values of y(x)
at each point in this x-partition.

Exercise 12.3.
Create a handle to a function f accepting two input arguments x and y for the above function
f (x, y). Pass this handle to ode45 to numerically solve the ODE. 

Rather than the array of x values selected by ode45, we are often interested in the value of
y at values of x that we select ourselves. For example, we might only want to approximate
the solution at six equidistant points, x = 0, 0.1, . . . , 0.5. We can specify this by entering the
corresponding x vector as the domain in ode45,

>> f = inline('x*yˆ2+y');
>> [x,y] = ode45( f, [ 0 : 0.1 : 0.5 ], 1 );
>> plot(x,y)

Note that Matlab continues to use roughly the same partition of x values that it originally
chose, as that was the set required to approximate the solution to within the requested accuracy.
The only thing that has changed are the x values at which ode45 returns an approximation of y.
12.3. Solving differential equations - the ODE toolbox 95

Several options are available for Matlab’s ode45 solver, thereby providing the user limited
control over the algorithm. Two important options are the relative and absolute tolerances,
RelTol and AbsTol respectively. In each step of the ode45 algorithm, the error in that step is
approximated. If yk is the approximation of y(xk ) at step k, and ek is the approximate error at
this step, then ode45 chooses its partition of x to insure that

ek ≤ max(RelTol ∗ yk , AbsTol),

where the default values are RelTol = 1e-3 and AbsTol = 1e-6. As an example where we
might want to change these values, observe that for large yk the error ek may be allowed to
grow quite large. In this case, one can increase the value of RelTol. For the above problem
dy/dx = xy 2 + y with y(0) = 1, the values of y become quite large as x approaches 1:

>> f = inline('x*yˆ2+y');
>> [x,y] = ode45( f, [0 1], 1 );
Warning: Failure at t=9.999897e−001. Unable to meet integration tolerances
without reducing the step size below the smallest value allowed (1.776357e−015)
at time t.
> In ode45 (line 308)

In order to fix this problem,1 we can choose a smaller value for RelTol,

>> f = inline('x*yˆ2+y');
>> options = odeset( 'RelTol', 1e−10 );
>> [x,y]= ode45( f, [0 1], 1, options );

Plot this result; you might want the terminate the vertical axis at, say, y = 100.

12.3.2 Systems of ODE

Solving a system of coupled ODEs in Matlab is quite similar to solving a single equation.
Since a system of equations is often not readily defined as an inline function, we supply the
derivatives to ode45 in an m-file. As an example, let’s solve the system of Lorenz equations
(these equations are a simplified model for atmospherics; their solutions have long served as an
example of chaotic behaviour),
dx
= −σx + σy,
dt
dy
= ρx − y − xz, (12.2)
dt
dz
= −βz + xy.
dt
For the purposes of this example, we will take σ = 10, β = 8/3 and ρ = 28, in combination with
the starting point x(0) = −8, y(0) = 8 and z(0) = 27.

First, a Matlab M-file lorenz.m is created that contains the Lorenz equations

function v = lorenz(t,w);
%LORENZ: Defines the Lorenz equations.
1
Note that ode45 refers to the independent coordinate, our x, as ‘time’ and t.
12.4. Exercises 96

sig = 10;
beta = 8/3;
rho = 28;
v = [ −sig*w(1) + sig*w(2); rho*w(1) − w(2) − w(1)*w(3); −beta*w(3) + w(1)*w(2)];

Observe that the three dependent variables x, y and z are combined into the vector w, and that
the derivatives are returned (to ode45) in the column vector v. Additionally, any function used
in combination with the ode family must receive the independent and dependent coordinates
as the first and second input argument, respectively, even if these coordinates are not actually
used (as is t in the current example).

Now, the solution of this system of ODEs over the interval t = [0, 20] can be calculated:

>> x0 = [ −8 8 27 ];
>> tspan = [ 0, 20 ];
>> [ t, xyz ] = ode45( @lorenz, tspan, x0 );

Note that on the last line a handle to our function is passed to ode45. The output consists of a
column t of times and a matrix xyz with three columns containing the values of x, y and z at
these times.

Exercise 12.4.
Create a figure with three subplots and plot the three coordinates as functions of t. Create a
separate figure for a 3D line plot of the three coordinates. 

Exercise 12.5.
Simply type the following

>> x0 = [ −8 8 27 ];
>> tspan = [ 0, 20 ];
>> ode45( @lorenz, tspan, x0 );

That is, do not store the output of ode45 and simply observe what happens. 

Exercise 12.6.
Now type

>> x0=[−8 8 27];


>> tspan=[0,20];
>> MyObject=ode45(@lorenz,tspan,x0);

Have a look ‘inside’ MyObject to see what information it contains about the calculation. 

12.4 Exercises

Exercise 12.7.
Determine the first and second derivative of the line through (x,y) with x = 4:13 and y
= [12.84 12.00 7.24 -0.96 -11.16 -20.96 -27.00 -24.96 -9.56 25.44]. Make a figure
12.4. Exercises 97

containing the plot of the initial data, the first derivative, and the second derivative in separate
sub-plots. 

Exercise 12.8.
Make a figure containing 2 sub-plots, and plot the function sin(x)/x and its integral on the
interval [0, 10]. Find the location of the roots of f(x) and mark the values corresponding to the
roots in each figure. 

Exercise 12.9.
Write scripts that compute the integral of the function f (x) = (1 + x2 )−1 using the Rectangle
rule, the trapezoidal rule and Simpson’s rule. Use the scripts to find the integral over the interval
[0, 4]. Exercise with different accuracies (number of subintervals) and compare the results with
the analytical value of the integral. 

Exercise 12.10.
Adapt the scripts you prepared for the trapezoidal rule and the Simpson’s rule to determine the
integral of f (x) = sin(x) over the interval [0, π2 ]. Do this with different numbers of subintervals;
n=[2 4 8 16 32 64 128 256]. For both the trapezoidal rule and Simpson’s rule, create a
matrix with 4 rows containing the values of n, the approximation of the integral, the error of
the approximation, and the ratio between the errors of consecutive approximations. What does
this tell you about the accuracy of both methods? 

Exercise 12.11.
2
Find the integral of the function f (x) = e−x /2 over the interval [−3, 3]. 

Exercise 12.12.
Make an m-file defining the function y = sin(x5 + x3 ). Then use integral to determine the
integral of this function over the interval [0, 2]. Also try to find the exact value of the integral
using the symbolic toolbox. Why can numerical integration be useful, even though it results in
an approximation of the integral? 

Exercise 12.13.
Solve the following ODE of 1st order
dy
= x y 2 + y, y0 := y(x = 0) = 1,
dx
in the domain x ∈ [ 0, 0.9 ] with an equidistant discretization of ∆x = 0.01. Use a m-file
firstode.m to define the function. Plot the result. 

Exercise 12.14.
The predator-prey model describes the evolution of the number of predators and preys over
time. With prey defined as x and predator as y, the number of predators and preys can be
modelled with the following system of ODE:
dx
= αx(1 − y)
dt (12.3)
dy
= βy(x − 1)
dt
where for the purposes of this example, we will take α = 5 and β = 1 in combination with the
starting point x(0) = 3 and y(0) = 1. Solve the predator-prey model over the interval t = [0, 10]
and plot the populations of preys and predators in a single graph. 
Chapter 13
Symbolic computation

In the previous chapters we used Matlab as a numerical toolbox. Recent versions of Matlab
also permit symbolic manipulations of mathematical
√ expressions. That is, Matlab can solve
the roots of f (x) = x2 + 2x − 1 = 0 as −1 ± 2, rather than as -2.4142. . . and 0.4142. . . , and it
can return the derivative and integral of this function as 2 ∗ x + 1 and (x ∗ (x2 + 3 ∗ x − 3))/3,
respectively. In this chapter we explain how this works.1

13.1 Symbolic objects

A symbolic object can be a variable, a number or an expression made of symbolic variables and
numbers. These objects can be defined using sym or syms, as in

>> a = sym('a')
a =
a
>> syms b c % identical to b = sym('b'), c=sym('c'), but no 'echo'
>> d = a+5
d =
a+5
>> e = 3;
>> f = a+d+e
f =
2*a + 8

As usual, Matlab displays the result of the expressions if this is not suppressed by a semi-colon.
A difference is that displayed symbolic objects are not indented.

Exercise 13.1. √
Clear your workspace and define the symbolic variables x, y and z, where z = x + y + 5.
1
This section contains some examples from the tutorial of W.R. Wilcox, Clarkson University.

– 98 –
13.2. Solving symbolic expressions 99


Furthermore, define the (normal) variable a as 5. Finally, try who and whos and note in what
respect(s) symbolic variables differ from the non-symbolic ones. 

Creating symbolic expressions is easy:

>> syms x y
>> f = xˆ2 + yˆ2 + 3/2 % A symbolic expression
f =
xˆ2 + yˆ2 + 3/2
>> g(x) = (1/3)*xˆ2 − 5/4 % Another symbolic expression
g(x) =
xˆ2/3 − 5/4
>> h = f+g
h(x) =
(4*xˆ2)/3 + yˆ2 + 1/4
4/3*xˆ2+yˆ2+1/4

So we see that it does these simple calculations exactly. Note that g and h are of type symfun,
while f is of type sym; Matlab will evaluate g(5) but not f(5). Symbolic functions can also
be defined directly, syms f(x).

Exercise 13.2.
Define the symbolic expressions f = x3 + 3x2 + 3x + 1 and g = (x + 1)2 . Next calculate
f + g, f − g, f ∗ g, and f /g. 

As you might have noticed in the last exercise, the symbolic expression are not simplified and
only simple calculations are performed directly.

Exercise 13.3.
Use simplify to simplify the answers to the previous exercise. 

13.2 Solving symbolic expressions

A recurring problem is the solution of symbolic expressions. This is made easy with the solve
command. By default the command solve(eq) solves the equation eq = 0.

>> syms x y
>> solve( exp(x)−5 ) % This solves exp(x)=5
ans =
log(5) % Note: log = ln, log10 = log
>> solve( x+y−5 ) % This solves x+y=5 for x
ans =
5−y
>> solve( x+y == 5, y ) % This solves x+y = 5 for y
ans =
5 − x
>> f = xˆ2 + 3*x + 2;
>> xzero = solve(f)
xzero =
−2
−1
>> yzero = solve( yˆ2 + 3*y + 6 )
yzero =
13.3. Matrix and and vector operations 100

− (15ˆ(1/2)*1i)/2 − 3/2
(15ˆ(1/2)*1i)/2 − 3/2

We see that the solutions to these expressions are again symbolic objects. The results in xzero
are easy to understand, but those in yzero are not immediately clear. For a slightly prettier
presentation of these results, use pretty. To recover numerical values, use double.

Exercise 13.4.
Find the roots of x2 + 4x + 2 and those of x2 + 2x + 4. Calculate the absolute values of all four
roots. Which root has the largest absolute value? 

It is also possible to solve systems of coupled equations, as in

>> syms x y
>> [x,y] = solve( x+y == 5, x−y == 3, x, y )
x =
4
y =
1

Exercise 13.5.
Determine the intersection points of the line x + 3y = 1 with the circle x2 + y 2 = 2. Note that
this will not work when the old solutions x and y are still in memory; you have to clear the
workspace often for the symbolic manipulations to operate properly. 

13.3 Matrix and and vector operations

Since Matlab is matrix-based, it ought not surprise us that it can symbolically manipulate
matrices. For example, for the matrix A and the vector x in two dimensions:

>> syms a11 a12 a21 a22 x1 x2


>> A=[a11 a12;a21 a22];
>> x=[x1;x2];
>> x'
ans =
[ conj(x1), conj(x2)]
>> x.'
ans =
[ x1, x2]
>> A'
ans =
[ conj(a11), conj(a21)]
[ conj(a12), conj(a22)]
>> A.'
ans =
[ a11, a21]
[ a12, a22]
>> det(A)
ans =
a11*a22−a12*a21
>> simple(inv(A))
ans =
[ a22/(a11*a22−a12*a21), −a12/(a11*a22−a12*a21)]
13.4. Differentiation and integration 101

[ −a21/(a11*a22−a12*a21), a11/(a11*a22−a12*a21)]
>>A*x
ans =
a11*x1+a12*x2
a21*x1+a22*x2

Note that Matlab considers each declared variable as a complex number. However, in many
cases we know that the declared variables are real numbers, and we can tell Matlab so by
adjusting the variable declarations. As in illustration, we calculate the dot and cross products
of two three-dimensional vectors x and y,

>> sysm x1 x2 x3 real;


>> syms y1 y2 y3 real;
>> e1 = [1;0;0]; e2 = [0;1;0]; e3 = [0;0;1]; % Cartesian basis vectors
>> x = x1*e1 + x2*e2 + x3*e3 % combine components and basis
x =
[ x1, x2, x3]
>> y = y1*e1+y2*e2+y3*e3;
>> dot(x,y)
ans =
x1*y1+x2*y2+x3*y3
>> cross(x,y)
ans =
[ x2*y3 − x3*y2, x3*y1 − x1*y3, x1*y2 − x2*y1]

Exercise 13.6.
Evaluate the dot and cross products of two complex-valued three-dimensional vectors x and y.
Note the difference(s) to the above answers. 

13.4 Differentiation and integration

The symbolic toolbox is nice for solving calculus problems. For example, to differentiate the
function f = e−ax x3b sin(cx), with unspecified constants a, b and c, we type

>> clear, syms a b c x;


>> f(x) = exp(−a*x)*xˆ(3*b)*sin(c*x);
>> Df = diff(f) % Or: diff(f,x)
Df(x) =
3*b*xˆ(3*b − 1)*exp(−a*x)*sin(c*x) + c*xˆ(3*b)*exp(−a*x)*cos(c*x) ...
− a*xˆ(3*b)*exp(−a*x)*sin(c*x)
>> Df = simplify( Df )
Df(x) =
xˆ(3*b − 1)*exp(−a*x)*(3*b*sin(c*x) + c*x*cos(c*x) − a*x*sin(c*x))

Higher order derivatives are also available, e.g. d2 f /dx2 becomes diff(f,x,2). For more infor-
mation on symbolic differentiation, see help sym/diff (not to be confused with help diff).

f (x′ ) dx′ as follows:


R
For a given function f (x), we solve the indefinite integral F (x) =

>> syms a b x;
>> f(x) = exp(−a*x)*sin(b*x);
>> If(x) = int(f); % Or: int(f,x)
If(x) =
−(exp(−a*x)*(b*cos(b*x) + a*sin(b*x)))/(aˆ2 + bˆ2)
13.5. Limits 102

Verify this result by asking Matlab to differentiate the integral, diff(If,x). This should
recover f , but the result appears to be different because Matlab does not always present the
simplest format. Agreement is observed once we simplify the integral.

Note that Matlab does not automatically add the constant of integration, c, customarily in-
cluded in indefinite integrals (whose value is to be deduced from the boundary conditions). If a
constant of integration is required, you must add this yourself to If.

For integrals Matlab is unable to solve symbolically, it returns a trivial result,

>> clear, syms a b c x;


>> f(x) = exp(−a*x)*xˆ(3*b)*sin(c*x);
>> If = int(f) % Or: int(f,x)
If(x) =
int(xˆ(3*b)*exp(−a*x)*sin(c*x), x)

When this happens, you’re out of luck – but you can still obtain a numerical approximation
using the methods of the previous chapter. It can happen that the symbolic integral becomes
solvable after subsequent manipulations.
Rb
For definite integrals, F = a f (x′ ) dx′ , one appends the range to the integration command,

>> clear, syms a c x;


>> f(x) = exp(−a*x)*sin(c*x)
>> If = int(f,−pi,pi) % Or int(f,x,−pi,pi)
If =
(exp(pi*a)*(c*cos(pi*c) − a*sin(pi*c)))/(aˆ2 + cˆ2) ...
− (exp(−pi*a)*(c*cos(pi*c) + a*sin(pi*c)))/(aˆ2 + cˆ2)

Exercise 13.7.
Solve the integral from section 12.2.1 analytically, and compare the result with the numerical
values calculated in that section. 

13.5 Limits

The symbolic toolbox is also able to solve finding limits, e.g.

>> clear, syms x a;


>> limit( sin(a*x)/x, x, 0 )
ans =
a

There are cases where the limit depends on the direction from which it is approached. Consider
for instance tan(x) in the limit of x = π/2 [if you forgot the shape, try ezplot(’tan’)]. We
can use MATLAB’s numeric engine,

>> tan(pi/2), tan(pi/2+eps)


ans =
1.6331e+16
ans =
−6.2184e+15
13.6. Solving ordinary differential equations 103

which shows that a very small increment of the angle makes a huge difference, as expected. The
symbolic engine finds the two correct solutions,

>> limit( tan(x), x, pi/2 )


ans =
NaN % That's a kind of warning
>> limit( tan(x), x, pi/2, 'left' )
ans =
Inf
>> limit( tan(x), x, pi/2, 'right' )
ans =
−Inf

Exercise 13.8.
Find the limit of (1 + a/x)x for x → ∞ (in Matlab: inf). The result may surprise you! 

13.6 Solving ordinary differential equations

An ordinary differential equation can be solved symbolically with the command dsolve.

>> syms f(x) a


>> dsolve( diff(f) == a*f )
>> dsolve( diff(f,x) == a*f(x) )
ans =
C1*exp(a*x)

The arbitrary constant C1 remains to be determined from the boundary conditions. For the
ODE we solved numerically in the previous chapter, including the boundary condition,

>> syms y(x)


>> dsolve( diff(y) == x*yˆ2 + y, y(0) == 1 )
ans =
−1/(x − 1)

Exercise 13.9.
Solve the differential equation y ′′ (t) + 3y ′ (t) + 3y(t) = e−t with y(0) = y(1) = 0. 

Exercise 13.10.
Solve the differential y ′′ (t) + 3y ′ (t) + 2y(t) = t with y(0) = 0, and y (1) (0) = 3.
Hint: the second boundary condition requires an auxiliary function. 

The solution to a differential equation can be long and complicated, so it would be nice if one
can plot the solution. Since the answer is symbolic expression, it takes a little manipulation
before one can use plot. The ezplot command does work with symbolic expressions.

>> syms f(x)


>> g = dsolve( diff(f) == −4*f + x, f(0) == 1 )
g =
x/4 + (17*exp(−4*x))/16 − 1/16
>> ezplot(g)
13.7. Summations 104

>> ezplot(g,[−3:3]) % user−supplied range


>> g(x) = dsolve( diff(f) == −4*f + x, f(0) == 1 ) % Note the g(x): matlab does
g(x) = % not automatically recognise the output as a function
x/4 + (17*exp(−4*x))/16 − 1/16
x = [−3:.1:3],; plot(x,g(x));

Exercise 13.11.
Plot the solution of the differential equation of the previous exercise. 

Exercise 13.12.
Type the following commands and see what happens.

>> syms x y t
>> S = xˆ2 + 3*x*y + yˆ2 − 10
>> ezplot(S)
>> f = cos(2*t)
>> g = sin(4*t)
>> ezplot(f,g)

13.7 Summations

Matlab’s symbolic engine is also capable of doing symbolic summations.

>> syms x i n
>> s = symsum( xˆi, i, 0, n )
s =
piecewise(x == 1, n + 1, x ∼= 1, (x*xˆn − 1)/(x − 1))

Here piecewise indicates that there are two answers, depending on the value of x: for x = 1
the summation equals s = n + 1, for x 6= 1 one has s = (xn+1 − 1)/(x − 1).

On may even add up infinitely many terms,

>> clear, syms x k;


>> symsum( 1/kˆ2, k, 1, Inf)
ans =
piˆ2/6
>> f(x) = symsum( (−1)ˆk*xˆ(2*k+1) / factorial(2*k+1), k, 0, inf )
f(x) =
sin(x)

Exercise
P∞ 13.13.
Solve k=1 1/k2 and ∞ k
P
k=0 x /k!. The results may surprise you! 
13.8. Symbolic substitution 105

13.8 Symbolic substitution

Matlab also has a nice command for symbolic substitution: in expression one may replace
old by new using the command subs(expression, old, new). For instance,

>> syms x y z;
>> z = xˆ2 * y;
>> subs(z, x, 4)
ans
y + 16
>> subs(z,y,3)
ans
xˆ2 + 3
>> subs(z,x,yˆ2)
ans
yˆ4 + y
>> z = subs(z, x, 4)
z =
y + 16
>> z = subs(z,y,3)
z =
19

It is also allowed to make multiply substitutions at once by using a vector or matrix as the new
object. For example

>> syms x y;
>> x = yˆ2;
>> subs(x,y,[0 1 2 3 4 5 6])
ans =
[ 0, 1, 4, 9, 16, 25, 36]

Exercise 13.14.
Use subs to work out what x is as function of z when you know x = y + y 3 − 5 and y = z + z 3 .


Exercise 13.15.
Symbolic differentiate the function x = y 5 + sin y + ln y and evaluate it for the points y =
4, 10, 20, 40. 
Part B
C++

– 106 –
Chapter 14
Introduction to C++

14.1 Objective of the course

The goal of this short course in C++ is not to become a perfect C++ programming guru. For
this we refer to special courses and a broad range of expert literature – see below in section 26.1.

The goal of this introduction to C++ is to better understand computer hardware and software,
to perform basic tasks, operations, and programming within the framework of the programming
language C++. We will first install on your computer an advanced integrated development
environment (IDE) software, that will let you edit, compile, and run C++ programs. Then
you will learn how to read simple C++ programs, how to write own code, and to get used to
error-searching/debugging of code.

14.2 Installation of a C++ compiler/IDE

C++ is a compiled programming language: Before you can execute the algorithm that you have
written, it has to be compiled into an executable. There are many commercial C++ compilers,
for various operating systems. While many Unix-type operating systems, like modern Linux
distributions and MacOS, have C++ compilers and debuggers embedded (g++ and gcc), this
is not the case for a Windows operating system.

We also recommend you to download an IDE, i.e., a smart editor that helps you to write and
compile C++ files. They usually can be downloaded together with a compiler, so make sure
you include the compiler if you are a Windows user. There are many freely available IDE’s (e.g.
Netbeans, Orwell C++, Netbeans) that you can download for free (under the GNU General
Public License). For academic users, we recommend CLion, which requires you to apply for
a free license, but offers very good code analysis and debug tools, which allows you to avoid
common programming mistakes.

– 107 –
14.3. A short history of C++ 108

Follow the following steps to get started:

• Download from https://www.jetbrains.com/clion/ execute the setup file and follow


the installation instructions. Select Evaluate for free (you can later apply for an academic
license)

• Ready to start.
To create your first C++ program, click on New Project, then replace the directory name
untitled with a sensible name, e.g. FirstProgram, then click Create. The file main.cpp
should now appear on the screen, containing the following:
#i n c l u d e <i o s t r e a m >

i n t main ( )
{
s t d : : cou t << ” H e l l o , World ! ” << s t d : : e n d l ;
return 0;
}

You can now modify the file, and compile and run it. To do so, use the buttons at the top
right of the screen:

The first button is called Build and compiles the program; the second-last button is called
Run) and executes the program; you will see the output of the compilation and run at the
bottom of the screen.

14.3 A short history of C++

C was developed in the 70’s by K. Thompson, B. Kernighan, and D. Ritchie, and was introduced
together with the operating system UNIX. Today’s popular operating system LINUX is the free
derivate of UNIX, and, like its ancestor, is based on C, i.e., the operating system is – in big parts
– written in C. The original goal was a standardised language for the structured programming.
However, the so-called ANSI-standard was only introduced as late as 1988 as ANSI-C.

C++ can be seen as an extension of C, developed, propagated and introduced between 1983
and 1985 by B. Stroustrup. Besides the goal to develop a higher, object-oriented language,
down-ward compatibility with C was desired. Therefore, C is to be seen as a fraction/part of
C++. The ANSI Standard for C++ was fixed in June 1998. In the framework of this course,
we will use C++ syntax whenever this is simpler than C, e.g. for I/O (input/output).

The C++ language is being actively developed, and new standards have being published in
2003, 2011 and 2014. These new standards extended the language capabilities, while preserving
backwards compatibility. In particular, the C++11 standard has introduced many new features
that make it easier to create and manipulate datasets. You will learn many of these new features
in this course.
14.4. Why use C++? 109

14.4 Why use C++?

Some reasons for the use of C++ are

• it is free – both compiler and IDE’s are available under the GPL licence

• it is system-independent – from micro-processors to super-computers

• it is rather low level – close to the operating system

• it is extendable, re-usable, and robust, ...


Chapter 15
Programming-style

This section briefly discusses some issues related to a good style of programming. Good style
means that programs are simple and easy to read. It involves some rules like indentations that
make the program also optically structured and, finally, it involves comments that describe in
words what the program is doing.

Note that a good style does not only help other people reading and understanding your program,
it also will help you to understand your own program – after you have not looked at it for a
while. Think not of the few 100 lines we will write in this course, think of several 10,000 lines
of code that a programmer can write, during a thesis for example.

In “real life” programmers do NOT spend most of the time programming; instead, they debug
(search for errors) and update, change, optimise and re-use existing codes and code-fragments.
For these tasks, a clean, proper, and consistent style is not only helpful, but absolutely necessary.

This is – by the way – true for all programming languages, including MATLAB.

15.1 Comments (see also §16.1)

There are two things a program should do: First, it tells the computer what to do and, second,
it also tells the (human) reader of the program what it does.

A working program without comments is a time-bomb. Even the simplest ideas flowing into
the program will be forgotten after some time ... and without comments, a program can not be
re-used. Without comments, a program cannot be understood or changed so that either it has
to be program anew, or a lot of time is spent re-understand the exciting program; both are a
waste of time.

In C++ there are two types of comments.

– 110 –
15.2. Clear style 111

The first, traditional comments begin with /* and end with */. They can enclose single charac-
ters or many lines and are most convenient for larger comments, or for making old code invisible
to the compiler.

/∗ Use comments t o make t h e r e a d e r under sta nd


what your program do es . ∗/

Alternatively, you can write line-comment that begin with two forward-slashes // and end at
the end of a line. It can start anywhere in the line and is thus convenient for commenting single
commands.

// Use l i n e comments t o comment co de s n i p p e t s , o r s i n g l e l i n e s o f co de .

As a suggestion, each program should have a comment block at the beginning, containing the
most important information:

• Header
Name of program and what is it supposed to do.
• Author
Author and (e-mail) contact address
• Date
Date of creation.
• How to use the program
Describe the mode of usage.
• Files (I/O)
File format and of input files and output data-files
• License/Restrictions
Are there any restrictions to the use of this program?
• Revisions
Dates and type of changes performed.
• Error management
What happens when a program detects an error.
• Other remarks
...

15.2 Clear style

A program should be readable like a thesis or a scientific paper. It should contain an introduction,
like the header comment above, and it should be clearly separated in chapters, paragraphs, etc.
with clear boundaries. Comments can be used as a way to optically separate paragraphs within
the program.
Chapter 16
The basics

16.1 Language Elements

The first language element are comments. They do not affect the function of the program or
the computer – they enhance the understanding of the program when read by another (human)
user. A comment is everything between ’/*’ and ’*/’ or after ’//’.

The second essential element is the data, i.e., constants and variables. These can be of different
type: booleans, integers, doubles, characters, or self-defined data structures (classes). It is
necessary to tell the computer which data is required for the program to work. This could be
done anywhere in the program, however, this is neither efficient nor clean or clear programming.
It is recommended to define data (only) at the beginning of a function/program. Exceptions to
this rule will be discussed below.

Other elements, like operators, control structures, and functions, are required to manipulate the
data. Examples for operators are the assignment operator =, the basic arithmetic operations +,
-, *, or /, and comparison operators (==, !=, >, <, >=, <=). However, there are many more, as
summarised in table 16.1 and discussed in more detail later in §16.4.

Examples for control structures are for, do and while-loops, situation dependent execution
with if, else if, and else or switch, local scopes with begin and end brackets { and }, and
many others as defined in the next subsections.

Examples for functions are mathematical functions like sin, cos, or pow, but functions can
also be user-defined, containing sequences of operations that are repeated many times. Use of
functions makes the program shorter and better readable.

In C++, the so-called main program is also a function – it marks the beginning of your program,
and is always called main() (that means no other function can use this name). Begin and end
of a function are marked by the curly brackets ‘{’ and ‘}’.

– 112 –
16.2. Hello World 113

Operator type Operators


Assignment =
Arithmetic operators +, -, *, /, %
Increment operators ++, --
Relational operators ==, !=, >, <, >=, <=
Logical operators !, &&, ||
Bitwise Operators ~, &, |, ^, <<, >>
Compound assignment +=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=
Other operators sizeof(), (type), ? :, ,, ::, (), [], ., ->, *, &, . . .

Table 16.1: Examples of operators, sorted by type

The next class of language elements are those used for the communication between the user and
the computer, the so-called I/O (input/output) functions and operators. In C++, standardised
libraries exist that contain the definitions of the I/O commands.

The simplest way of I/O is output on the screen and input via the keyboard. The next way
– especially when a lot of information has to be input into the program or is returned – is via
data-files (for both input and output).

Finally, there are organisational elements, that do not per-se belong to the programming lan-
guage, but can be used for management of the program before compilation and execution, e.g.,
by the so-called pre-processor. This allows to shorten and clarify the program by just moving
big, un-clear code-fragments out of the program, or by conditionally selecting alternative parts
of the code.

16.2 Hello World

Your first program (CLion −→ Create Program) looks like this:

#i n c l u d e <i o s t r e a m >

i n t main ( )
{
s t d : : cou t << ” H e l l o , World ! ” << s t d : : e n d l ;
return 0;
}

• The first line includes a file, iostream, from the C++ standard library that provides
definitions for input and output operations (I/O). Important for us, this library provides
objects like std::cin and std::cout that can be used to read and write to the console.1
There is a whole set of C++ standard libraries that provide additional functionality to
1
std is a so-called namespace and is prepended to most functions that are included in the standard libraries.
As many common functions are in the std name space, many programs include the line using namespace std
which allows you to call the function without the std:: prefix.
16.3. data types, Variables, Constants 114

C++ programms2 . Including libraries is done at the beginning of the source file – outside
the main() function.

• int main(){...} is a function of type int, that is the program will return an integer value.
Every program contains exactly one such function (there can be many more functions, but
only one main function. The ()-brackets are used to denote that the program takes no
input arguments. Note, C++ programs can take input arguments,, however, we delay the
discussion of this to later.

• The brackets {...} enclose the main-program, i.e. the commands, the main function
main(...) consists of. In general, program blocks are enclosed by these curly brackets,
and each begin-bracket { must be accompanied by an end-bracket }.

• The next line is the hardest to understand, and we will leave the details for later. For now,
it is important to know that this line passes the string "Hello, World!" to the console
output, followed by an end-of-line character.

• The main function ends with return 0;. Thus the main function, will return 0 to the op-
erating system, indicating that the programm ran sucessfully (without errors). Returning
any value other than zero tells the operating system that your program has failed.

• Note that a new line is not the end of a command in C++. Instead, every command has
to be ended by a semicolon ‘;’. In fact, C++ allows you to freely format your program
using newlines, whitespaces and tab, except in comments and commands beginnning with
#. The following programm would have been acceptable C++ code:

#i n c l u d e <i o s t r e a m >
i n t main ( ) { s t d : : cout<< ” H e l l o , World ! ”
<<s t d : : e n d l ; r e t u r n 0 ; }

For readability, however, it is best to not use several commands within a single line in
order to keep the program clean and readable. Since the semicolon has the function to
separate two commands, it is not found at the end of program-blocks, that are already
clearly terminated by the end-bracket of the pair {...}.

16.3 data types, Variables, Constants

16.3.1 Numbers

Computers process numbers (and also symbols) in binary representation. The binary system was
developed by G.W. Leibniz when studying Chinese letters. Based on the binary representation,
also octal (3 bits) or hexa-decimal (8 bits) representations are used in the computer.

Example – if you really want to know:


The integer 496 can be represented in different bases as follows (where the subscript indicates
2
If you click on iostream while holding the Ctrl button (Command on MacOS) in Clion, you can see the header
file; these are written by hardcore programmers, so don’t be scared if you don’t (yet) understand the contents.
16.3. data types, Variables, Constants 115

the base, and superscipts are mathematical powers):

49610 = 4 · 102 + 9 · 101 + 6 · 100


= 1 · 28 + 1 · 27 + 1 · 26 + 1 · 25 + 1 · 24 + 0 · 23 + 0 · 22 + 0 · 21 + 0 · 20
= 1111100002
= 7 · 82 + 6 · 81 + 0 · 80
= 7608 = 0760 (octadecimal numbers have 0 prepended in C++)
= 1 · 16 + 15 · 16 + 0 · 160
2 1

= 1F 016 = 0x1F0 (octadecimal numbers have 0x prepended in C++) (16.1)

Try this for yourself by running the following program:

#i n c l u d e <i o s t r e a m >
i n t main ( ) {
int n = 496;
s t d : : cou t << s t d : : dec << n << s t d : : e n d l ;
s t d : : cou t << s t d : : o c t << n << s t d : : e n d l ;
s t d : : cou t << s t d : : hex << n << s t d : : e n d l ;
return 0;
}

Numbers x in floating-point representation (0.496e+03) are transformed to fixed-point notation


using the formula

x = mbe (16.2)

with the “mantissa” m (here 496), the basis b (b = 10 could be also b = 2, 8, 10, 16), and the
exponent e (here 3). The in-fact implementation of floating-point numbers is machine/processor-
dependent and will not be discussed here.

16.3.2 Basic data types and their declaration

The built-in, primitive data types in C++ are: bool, char, int, float, and double. His-
torically processors were optimised to deal with these data types – however, the development
of processors has progressed so much that also other data types are efficiently treated. Usually,
a compiler can optimise a code such that a user does not feel anymore the difference between
different types of data.

The type bool is a logical data-type that can be used, e.g. to deal with the result of a logical
comparison using logical operators, see Sec. (16.4). It can only have two values: true or false.
Its freely transformable to data-type int, where true corresponds to 1 and false to 0. This
transformation was introduced for compatibility reasons, to old programs where instead of bool
just int’s were used. Some simple declarations are:

bool t e s t ; // d e c l a r e t e s t with out i n i t i a l i s i n g i t s v a l u e


16.3. data types, Variables, Constants 116

t e s t = (0 < 5 ) ; // t e s t i s s e t to r e s u l t o f com p ar is on ( t r u e )
i n t i ( t e s t ) ; // i i s d e c l a r e d and s e t to v a l u e o f t e s t ( t r u e )
i n t j =0; // j i s d e c l a r e d and s e t to f a l s e

Initialisation/Construction of a variable can be performed as type variable = type constant or


equivalently as type variable(type constant). For experts: The symbol ’=’ does not denote the
assignment operator if the variable was just declared (created); instead, the copy-operator () is
called.

The type int is recognised by the compiler (i.e. the compiler-programmer) as most appropriate
for dealing with integer numbers. Its size is not fixed in the standard, but usually 4 bytes
(32 bit). However, with help of the operator sizeof, one can determine the size of a type or
variable in bytes. Different computers also support other integer data types, e.g., 2, 8, or 16
bytes. These are defined using short and long or (not ANSI conform) long long. In addition
there is the unsigned type for storing non-negative integers (the longer form of declaration
short int, long int, unsigned int is not required).

short i = 0;
int j , k , l ;
l o n g m=0, n=1;
unsigned u ;
s t d : : cou t << ” S i z e of v a r i a b l e i : ” << s i z e o f ( i )
<< ” S i z e of v a r i a b l e k : ” << s i z e o f ( k )
<< ” S i z e of v a r i a b l e m: ” << s i z e o f (m) << s t d : : e n d l ;
s t d : : cou t << ” S i z e of typ e b o o l : ” << s i z e o f ( b o o l ) << s t d : : e n d l ;

Note that an integer variable always has an integer value – even if one assigns a real (floating-
point) value to it.

int i = 38.5674 , j = 10; // ATTENTION !


s t d : : cou t << i << ” ” << i / j << s t d : : e n d l ; // ou tp u t i s 38 3

The data types float and double are the single- and double-precision floating point data types
that are implemented optimally in the processor. The type long double can be used to get
quad-precision (if supported). The in-fact representation of floating-point numbers is hardware
dependent, e.g., in 1998 at least the double-precision basic operations were hardware imple-
mented. With the current 64-bit processors, more and faster operations with larger numbers are
possible. Type float should only be used if memory is a problem, since for processor operations,
float often has to be modified to double anyway.

C++ does not specify how variables are represented in memory and the use of memory is not
specified per type either. However, at least the relations:
1 = sizeof(char) = sizeof(bool) ≤ sizeof(short) ≤ sizeof(int)
= sizeof(unsigned) ≤ sizeof(long)
and
sizeof(float) ≤ sizeof(double) ≤ sizeof(long double)
are always true.
16.3. data types, Variables, Constants 117

In general, on UNIX-machines, int-variables are 4, short 2, and char 1 byte long. Double-
precision double requires 8, float only 4 bytes. The values used are different from machine to
machine, but also can be different from compiler to compiler.

One can check the range of the basic data type using the numeric_limits library:

#i n c l u d e <i o s t r e a m>
#i n c l u d e <l i m i t s >
u s i n g namespace s t d ;

i n t main ( ) {
co ut << ”Minimum i n t : ” << n u m e r i c l i m i t s <i n t > : : min ( ) << e n d l ;
co ut << ”Maximum i n t : ” << n u m e r i c l i m i t s <i n t > : :max ( ) << e n d l ;
co ut << ”Minimum do uble : ” << n u m e r i c l i m i t s <double > : : min ( ) << e n d l ;
co ut << ”Maximum do uble : ” << n u m e r i c l i m i t s <double > : :max ( ) << e n d l ;
}

In the following example, different data types are declared:

#i n c l u d e <s t r i n g >

i n t main ( ) {
cha r c1 = ' x ' ; // one c h a r a c t e r : ' x '
cha r c2 [ ] = ” h e l l o ” ; // t e x t a r r a y with 5 c h a r a c t e r s
// ( no te : l e n g t h i s 6 due t o added ' \ 0 ' )
std : : s t r i n g s t r ( ” h e l l o ” ) ; // t h e C++ way , a r b i t r a r y l e n g t h s t r i n g s
// ( no te : l e n g t h i s 5 − no added ' \ 0 ' )
cha r c3 = ' \n ' ; // t h e new−l i n e c h a r a c t e r
int i var ; // i n t e g e r v a r i a b l e with name i v a r
long i n t il var = 1; // l o n g c o n s t a n t
long i n t j l v a r = 1L ; // a n o t h e r l o n g c o n s t a n t
short is var ; // s h o r t i n t e g e r v a r i a b l e ( i n t per d e f a u l t )
do uble d var = 3 4 . 2 ; // r e a l number 3 4 . 2 with do uble p r e c i s i o n
}

Note that for char variables single characters have to be enclosed by apostrophes, e.g. 'x',
whereas arrays of characters must be enclosed by a double apostrophe, e.g. "hello". Above,
the variables c1 and c3 both have length unity (1), whereas the chain "hello" is accessible in
the C-style array c2 and has length 6, since during its declaration, automatically, a symbol '\0'
is added. (Try the definition char c2 = 'hello'; that will lead to an error.) More flexible is
the C++ method to use string, which do not need the terminator '\0'. Note that for strings,
the standard-library string must be included, see above.

For a computer there are three types of single quotes: left quotes ‘, right quotes ’ and straight
quotes '. Characters must be enclosed by two straight quotes, or your code will not compile.
Some operating systems try and be clever and insert ‘ the first time you ask for a quote and ’
the second time. If you get this problem turn off sticky keys on your operating system and it
should disappear.

Declaration of variables is not limited to the beginning of a block, but can be done everywhere
at first occurrence of a variable – be it clear, useful, and efficient or not.
16.3. data types, Variables, Constants 118

Important and useful is the declaration within a for(;;) loop, as discussed in more detail later:

d ou b le a ;
c i n >> a ; // i n p u t a v i a keyboard
int i trunc = a ; // throw away th e f r a c t i o n a l p a r t
f o r ( i n t i =0; i < i t r u n c ; i++ )
{
// . . .
}

In the above program, the variable i does not exist outside of the for(;;) loop, neither before
nor after.

Summary
(i) Declarations can be located at arbitrary position in the program
(ii) Initialisation with () or = operator
(iii) sizeof(type) can be used if the size of a type must be known, e.g., for portability between
different computers/architectures.

16.3.3 Type conversion

It is possible it change one variable into another type

i n t p=2, q=3;
d ou b le r=p /( d ou b le ) q ;

Here this is necessary to make sure rounding does not take place in the answer of r.

Two very useful ones are for converting char arrays to double and integers; the commands are
atof and atoi respectively.

const ch ar ∗ s t r i n t = ” 777 ” ;
const ch ar ∗ s t r f l o a t = ” 3 3 3 . 3 ” ;
int i = atoi ( s tr in t ) ;
float f = atof ( s t r f l o a t ) ;

Please note in C++ this can be done using stringstream’s and this method is recommended
nowadays, see §16.3.6.

16.3.4 Variable-attributes

Besides the attributes short or long integer variables can be also modified by signed and
unsigned, that allow to use integers (positive or negative) or exclusively positive integers, re-
spectively. The int can be dropped here.
16.3. data types, Variables, Constants 119

Exercise 16.1.
Write a problem to find out the size of variables of different types on your computer. 

16.3.5 string type

String objects are a special type of container, specifically designed to operate with sequences of
characters. Each character of the string can be access using the [] operator i.e.

string a ;
a=” H e l l o ” ;
string b;
b=a [ 2 ] ;
cou t << b <<e n d l ;

would write out the letter ‘l’ , recall c++ arrays start numbering at 0.

Additional with the + operator can be used to concatenate two strings together; for example

string a ,b, c ;
a=” H e l l o ” ;
b=”World” ;
c=a+b ;
cou t << c << e n d l ;

would produce ‘Hello World’.

Note: The function c_str() returns a const pointer to a regular C string, identical to the current
string. The returned string is null-terminated. This is often required because a lot of routies
require C strings not C++ strings to be passed to them.

16.3.6 String stream

stringstream’s provide an interface to manipulate strings as if they were input/output streams.


They are declared in the header called sstream, as you would expect from the other stream names,
but the type is called stringstream.

This is described here, after string for ease of finding, but iostreams are described in more detail
in chapter 23, so please refer to this section for a more detailed explanation of streams.

Below is a small example code that creates a filename by passing information into a stringstream
and re-extract the string at the end.

#i n c l u d e <s s tr eam>
#i n c l u d e <f s t r e a m >
#i n c l u d e <i o s t r e a m >
16.3. data types, Variables, Constants 120

u s i n g namespace s t d ;

i n t main ( )
{
stringstream file name ;
s t r i n g s t r e a m problem name ( ” my problem ” ) ;
ofstream s c r i p t f i l e ;
f i l e n a m e << problem name . s t r ( ) <<” . d i s p ” ;
s c r i p t f i l e . open ( ( f i l e n a m e . s t r ( ) ) . c s t r ( ) ) ;
// . .
s c r i p t f i l e . close ( );
return 0;
}

The key commands are << which adds data to the stringstream this can be any type for which
the << operator is defined. The .str() method return a traditional C++ string, see section
16.3.5 were .c_str() is also described.

The nice thing about stringstreams is they automatically deal with type conversion. For example
the code below will convert a string to int via a stringstream.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s s tr eam>
u s i n g namespace s t d ;
i n t main ( )
{
int a ;
s t r i n g s = ” 456 ” ;
istringstream sin ( s );
s i n >> a ;
cou t << a << e n d l ;
return 0;
}

16.3.7 Life-time and position in memory

auto If there is no further declaration, variables are automatic. These variables have a finite
lifetime, or scope. This means they are assigned to memory as soon as the program reaches the
line where they are declared. As soon as the program leaves the scope where they are declared,
the memory is freed again. (The scope is, in general, the inner-most enclosing pair of brackets,
or like in the case of a for(;;) loop, the end of this object.)

For experts: Variables of this type are usually assigned by the compiler to the so-called stack
memory. The value of such a variable is random (!), if not explicitly assigned or initialised.
Thus make sure to initialise your variables!

Aside: stacks, heaps, etc.


16.3. data types, Variables, Constants 121

In computer science, a stack is a last in, first out (LIFO) abstract data type and data struc-
ture. A stack can have any abstract data type as an element, but is characterised by only two
fundamental operations, the push and the pop. The push operation adds to the top of the list,
hiding any items already on the stack, or initialising the stack if it is empty. The pop operation
removes an item from the top of the list, and returns this value to the caller. A pop either reveals
previously concealed items, or results in an empty list. (See Wikipedia for further reading).
A queue is a particular kind of collection in which the entities in the collection are kept in order
and the principal (or only) operations on the collection are the addition of entities to the rear
terminal position and removal of entities from the front terminal position. This makes the queue
a First-In-First-Out (FIFO) data structure. (See Wikipedia for further reading).
In computer science, a heap is a specialised tree-based data structure that satisfies the heap
property: if B is a child node of A, then key(A) ≤ key(B). This implies that an element with
the greatest key is always in the root node, and so such a heap is sometimes called a max-heap.
(Alternatively, if the comparison is reversed, the smallest element is always in the root node,
which results in a min-heap.) The several variants of heaps are the prototypical most efficient
implementations of the abstract data type priority queues. Priority queues are useful in many ap-
plications. In particular, heaps are crucial in several efficient graph algorithms. (See Wikipedia
for further reading).

static The keyword static makes a variable exist during the whole duration of the program.
For experts: Such variables are saved on the heap-memory. If not initialised otherwise, they get
the value 0 (zero). A static variable inside a function has thus the value 0, if the function is
called for the first time, and keep this (or another assigned value) between subsequent calls to
this function. In contrast, an automatic variable is every time newly created and initialised.
The following function counts how often it was called and returns this value.

int f count cal ls ()


{
s t a t i c i n t count ; // 0 at f i r s t f u n c t i o n c a l l
r e t u r n ++count ; // i n c r e m e n t b e f o r e u s e as r e t u r n v a l u e
// ( i . e . r e t u r n s one on th e f i r s t c a l l )
}

const Variables that are declared const, can only be assigned a value at initialisation and not
anymore thereafter. This is used to define constants within a namespace that – by the compiler
– can be optimised such that their use costs less time than using variables. Thus, if variables
can be defined as constants, this might lead to a faster program execution.

const int Size = 100;


c o n s t d ou b le Pi = 3.1415926; // S e l f −d e f i n e d v a l u e o f PI
// When i n c l u d i n g cmath one can u s e th e p r e d e f i n e d c o n s t a n t M PI

16.3.8 Fields

Fields are used to combine variables of the same type in a connected range of memory. For
experts: Access to variables can be faster if they are in such a connected range of memory and,
16.3. data types, Variables, Constants 122

on the other hand, using fields also can make a program shorter and more clear. Access to the
elements of a field is achieved by an integer index. A linear field (with one index) can be seen as
a vector, while a field with two indices represents a matrix. Mathematical formulas with indices
can often be represented in a program using fields.

A field is declared in C++ by adding brackets [] to the variable name. At the same time,
this operator is also used to access the elements of the field, see below. In C++ fields always
start with the index 0, so that the last valid index is the length of the field reduced by 1.
Multi-dimensional fields are declared by multiple (not enfolded) pairs of brackets, see below.

Such fields receive – at declaration – a fixed size. Thus, the argument in brackets [], must be
either a number, a const variable, or a well-defined variable with a known value for the compiler
(at compilation time).

#i n c l u d e <s t r i n g >

i n t main ( )
{
// a r r a y o f 20 i n t ' s
int a [ 2 0 ] ;
// i n i t i a l i s a t i o n o f f i e l d a −− ERROR!
f o r ( i n t i =0; i <= 2 0 ; i++ )
a[ i ] = i ;
// i n i t i a l i s a t i o n o f f i e l d a
f o r ( i n t i =0; i < 2 0 ; i++ )
a[ i ] = i ;

// a r r a y o f t h r e e s t r i n g s , i n i t i a l i s e d to some v a l u e s :
std : : s t r i n g s t r a 2 [ ] = { ” Katia ” , ” H o l g e r ” , ” S t e f a n ” } ;

// two d i m e n s i o n a l a r r a y o f 20 x30 e l e m e n t s o f i n t typ e


int ia [ 2 0 ] [ 3 0 ] ;
// i n i t i a l i z a t i o n o f f i e l d i a
f o r ( i n t i =0; i < 2 0 ; i++ )
f o r ( i n t j =0; j < 3 0 ; j++ )
ia [ i ] [ j ] = i ∗ j ;
return 0;
}

Later, we will see that fields and pointers are closely related. The use of pointers allows to define
“dynamic” fields of a size that is determined during run-time, e.g., following a user-decision and
-input.

C++ supports containers that can dynamically allocate memory and allows simple manipulation
of fields, such as vector or valarray. The C++ vector-container is discussed in more detail
22.5 . Nowadays the use of C++ vector over fields is often recommended; however, non careful
use can lead to slow code.
16.4. Operators 123

16.4 Operators

Operators allow us to make a program readable. Sometimes, unfortunately, they also make
a program un-readable, cryptic and unclear. A term like 3 * z + 5 is easily understandable,
whereas the term plus(mult(3,z),5) that is expressed using functions is much less clear.

There exist unary, binary, and ternary operators. Binary operators like the multiplication-
and addition-operators, have two arguments, while unary operators, like the address-operator
& require only one. Finally, ternary operators take three arguments, the discussion of these is
delayed until § 17.2.

Table 16.1 gives an overview of all operators in C++. We have already been using assignment
and arithmetic operator and next we will discuss these in more detail.

16.4.1 Arithmetic operators

The arithmetic operators are +, -, *, / and %. The Operator % (modulo) forms the integer
rest of the division of the left with the right operand (both integer). If both are positive, the
result is positive and strictly smaller than the right operand. For one or two negative operands,
the result depends on implementation.

Combining the above operators with the ’=’ allows to repeat the left operand, as for example:

int i =3, j =7; // initialise


i = 3 + j % i; // i = 3 + ( j mod i ) , i i s s e t to 4
i += 3 ∗ 4 + j ; // i = i + (3 ∗ 4 + j ) , i i s s e t to 23
i /= 5 ; // integer division , i is now 4
i /= 5 ; // integer division , i is now 0 !

The type that is returned by an operator expression depends on the type of the operand. If
both operands are type T, also the result is type T. For different operand-types the “better” type
wins; one operand is first transformed to the “better” type, then the operation is carried out.
C++ has the following “type promotions”:

bool -> char -> short -> int -> long


-> float -> double -> long double
signed -> unsigned (!)

These rule of type-transformation are also valid for the following operators.

The unary operators ++ and -- exist in postfix and prefix-form, and they lead to an increment
or decrement by one, respectively. In the postfix form, the value of the operand before the
operation is returned, whereas in the pre-fix form, the value after is returned.

i n t i =5, j ;
16.4. Operators 124

j = i ++; // j i s 5 now ( i b e f o r e i n c r e m e n t ) i i s i n c r e m e n t e d to 6

d ou b le a [ 2 0 ] ;
i=j ; // i=j =5
cou t << a[++ j ] << a [ j ++]; // p r i n t s a [ 6 ] tw ice , j i s now 7
cou t << a [ i ++] << a[++ i ] ; // p r i n t s a [ 5 ] and a [ 7 ] , i i s now 7

// j++ = i ; // ERROR: can n ot a s s i g n to a temporary


// i = ( j ++)++; // ERROR: can n ot ap p ly ++ to a temporary

16.4.2 Assignment and increment operators

expression short for:


x += y x = x + y
x -= y x = x - y
x *= y x = x * y
x /= y x = x / y
x %= y x = x % y
++x x = x + 1
--x x = x - 1

Table 16.2: Additional assignment operators, and the long form they replace

16.4.3 Comparison and logical operators

For operations between two integral datatypes, there exist bitwise, logical, and shift operators.
(C++ also provides keywords for these). These operators are summarised in table 16.3, and
they also can be combined with the =.

| bitor bitwise OR
& bitand bitwise AND
^ xor bitwise XOR
<< left-shift, n-times
>> right-shift, n-times
~ compl complement, bitwise NOT, unary
|= or_eq bitwise OR, to-left assignment
&= and_eq bitwise AND, with assignment
^= xor_eq bitwise XOR, with assignment
<<= left-shift, n-times with assignment
>>= right-shift, n-times with assignment

Table 16.3: Bit-manipulation-operators

The logical operators are && (and) and || (or) and the negation ! (not) . The operators && and
|| have the special property that the evaluation of this expression is terminated already if the
16.4. Operators 125

result is clear (so-called sequencing). This property is also shared by the comma-Operator , –
that sometimes is used to construct complicated for-loops. Its value is the same as the value of
the right expression.

i n t a =5;
i n t b=10;
i n t c =5;

bool i s i t t r u e ;

i s i t t r u e =(( a==c ) && ( a!=b ) ) // This i s t r u e

i s i t t r u e =((a>b ) | | ( b>c ) ) // This i s a l s o t r u e

The (arithmetic) comparison-operators are ==, !=, <, <=, > and >=. The value of a logical
operation and the result of a comparison in C++ are of type bool, i.e. either true or false.

16.4.4 Further operators

Here all other operators except the ternary operator, ?:, which is used to select alternative
expressions of the same type, will be discussed. See sec. 17.2 for this operator.

int i ;
cou t << ( i > 0) ? i : 0 ; // n e v e r p r i n t s a n e g a t i v e number

The operator () leads to a function-call, [] is the index-operator for fields and pointers, a
point '.' allows to select an element from a structure and -> is equivalent when a pointer to a
structure is given.

c l a s s Person {
public :
s t r i n g name ;
i n t age ;
};

void f (){
Person p;
Person ∗ p p = &p ;
p . age = 25;
p p−>age = 2 5 ; // e q u i v a l e n t
}

The unary operators * and & are used to find the value of the memory location where a pointer
points at, and to find an address of an arbitrary variable (see sec. 20).
16.5. Summary 126

Operator-expressions are (like in C) treated according to their priority and associativity, see
table 16.4.
P. Operator Description Associativity
1 :: Scope resolution Left-to-right
2 ++ -- Suffix/postfix increment and decrement
() Function call
[] Array subscripting
. Element selection by reference
-> Element selection through pointer
3 ++ -- Prefix increment and decrement Right-to-left
+ ? Unary plus and minus
! ~ Logical NOT and bitwise NOT
(type) Type cast
* Value-of (dereference)
& Address-of
sizeof Size-of
new, new[] Dynamic memory allocation
delete, delete[] Dynamic memory deallocation
4 .* ->* Pointer to member Left-to-right
5 * / % Multiplication, division, and remainder
6 + ? Addition and subtraction
7 << >> Bitwise left shift and right shift
8 < <= For relational operators < and ≤ respectively
> >= For relational operators > and ≥ respectively
9 == != For relational = and 6= respectively
10 & Bitwise AND
11 ^ Bitwise XOR (exclusive or)
12 | Bitwise OR (inclusive or)
13 && Logical AND
14 || Logical OR
15 ?: Ternary conditional Right-to-left
= Direct ass. (provided by default for C++ classes)
+= ?= Assignment by sum and difference
*= /= %= Assignment by product, quotient, and remainder
<<= >>= Assignment by bitwise left shift and right shift
&= ^= |= Assignment by bitwise AND, XOR, and OR
16 throw Throw operator (for exceptions)
17 , Comma Left-to-right

Table 16.4: Precedence (P.) and associativity of C++ operators. Operators are listed top to
bottom, in descending precedence.

16.5 Summary

So far we have introduced the basic element of a program: variables, and discussed the many dif-
ferent types that are available. Also a few other commands have been used with out explanation,
(but you can probably work out what they do) like cout, cin and for.
16.5. Summary 127

In the rest of this part, we will cover how to make decisions in a program, repeat sections of
program, interact with the users and how to store data in a permanent way.

Exercise 16.2.
Explain what each line of the following code does i.e. add the comments

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;

i n t main ( )
{
i n t n , m;
cou t << ” Enter two i n t e g e r s : \n” ;
c i n >> n >> m;

i n t sum=m+n ;

cou t << ”Sum o f th e two i n t e g e r s i s ” << sum << e n d l ;

return 0;
}

Exercise 16.3.
Modify the program to ask for three numbers 

Exercise 16.4.
Modify your program to ask for both a person first name and surname. Get the program to
output the persons initials, along with the sum of the three numbers they give. 
Chapter 17
Decision structures

For implementing algorithms into a certain programming language, this language has to provide
certain control-structures that allow repeated or conditional execution of parts of the program.

In C (and C++) the most-used control strucures are the if-statement for the conditional ex-
ecution, as well as the switch()...case:-statement, that jumps to one of many blocks of
commands, based on the value of a certain variable. Finally, there is the command goto, that
sometimes can be used to escape from (deeply nested) loops, see §18. (Actually I would not
recommend ever using a goto, deaply nested loops can be exited by making the outer loop a
function and using the return command, see §19).

17.1 The if-command

The if-command is used to execute parts of the program only under certain conditions. This
command can be (but does not have to be) complemented by an else-statement, that is vis-
ited/exectuted in case the condition in the if-command is false. The else-part can consist
of arbitrarily many else if and one else. As well if, else if, and else-branches can be
single lines (terminated by a semicolon) or blocks, enclosed in curly brackets {}. An else-block
always relates to the previous, actual if-command, i.e., also if it is part of an else if. In the
following example, the second if-command is a statement by its own, outside the else-part of
the first if.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <cmath>
u s i n g namespace s t d ;

i n t main ( )
{

– 128 –
17.2. The ternary ?: operator 129

// s o l u t i o n o f q u a d r a t i c e q u a t i o n s xˆ2 + p x + q = 0

d ou b le p = 2. , q = 3 . ; // or o t h e r v a l u e s
d ou b le s o l 1 , s o l 2 ;
d ou b le r o o t a r g = 0 . 2 5 ∗ p∗p − q ; // c a l c u l a t e th e argument f o r th e r o o t

i f ( root arg > 0. )


{ // b e g i n o f i f −b l o c k
sol1 = 0.5∗ p + sqrt ( root arg ) ;
sol2 = 0.5∗ p − sqrt ( root arg ) ;
} // end i f −b l o c k
else i f ( root arg < 0. ) // ' e r r o r ' c o n d i t i o n , ' e l s e ' p a r t
cou t << ”no r e a l s o l u t i o n e x i s t s ” << e n d l ;
else // r e f e r s to l a s t i f ( r o o t a r g < 0 . )
sol1 = sol2 = 0.5 ∗ p ; // a s s i g n m e n t from r i g h t to l e f t

cou t << ” S o l u t i o n s 1 , 2 : ” << s o l 1 << ' ' << s o l 2 << e n d l ;

i f ( sol1 > 0. ) // ok , e l s e branch m i s s i n g


cou t << ” graph c u t s p o s i t i v e x−a x i s ” ;
return 0;
}

17.2 The ternary ?: operator

For completeness, also the ternary ?: operator is treated here. Ternary means that this operator
requires three arguments and is used to conditionally evaluate parts of expressions.

i n l i n e i n t abs ( i n t number ) {
// compute a b s o l u t e v a l u e
r e t u r n number > 0 ? number : −number ;
// E q u i v a l e n t form with b r a c k e t s
// r e t u r n ( number > 0) ? ( number ) : (−number ) ;
}

Is the term before the question-mark true, then the term before the colon is examined. Oth-
erwise, the term after the colon will be used. The two alternatives must be of the same type.
Note that here, the use of brackets is recommended – partly because the ternary operator is of
low priority and also because the terms that belong together should be made clear.

int i1 = 3 > 4 ? 0 : 1; // i1 is 1
int i2 = 3 ∗ ( 3 > 4 ? 0 : 1 ); // i2 is 3
int i3 = 3 ∗ 3 > 4 ? 0 : 1; // i3 i s 0 , s i n ce ∗ binds
// s t r o n g e r than >
17.3. switch-command 130

This operator always can be avoided by using an if-command, however, it could be more clear
or at least shorter in some situations. In any case it is a possibility to write un-readable code
and therefore should be used sparsely.

(As final remark, the ternary operator is also embedded in the graphics program gnuplot.)

17.3 switch-command

A command related to the if and the goto commands is the switch-command. Dependent on
the value of an integer variable, several case-blocks are visited. This construct is often used
when there is a larger number of possible alternatives to be chosen from.

In principle, a switch can always be replaced by if...else if-constructs, but often the switch
is more clear and helps understanding and structuring the program.

ch ar c ;
c i n >> c ;
switch ( c )
{ // b e g i n c a s e b l o c k
c a s e ' a ' : cou t << ” h e l l o world ! ” ;
b r eak ;
c a s e ' b ' : cou t << ”HELLO ” ; // f a l l t h r o u g h in ten d ed , comment m i s s i n g b r ea
c a s e ' c ' : cou t << ”WORLD! ” ;
b r eak ;
d e f a u l t : cou t << ”unknown i n p u t ” ;
b r eak ; // not n e c e s s a r y , but good s t y l e
} // end c a s e b l o c k

The above program-segment returns in small letters "hello world!" if the letter 'a' is typed.
In case c the word WORLD! is printed, but in case b the full sequence HELLO WORLD!. This strange
behaviour comes from the missing break in the block b. This behaviour, namely that a execution
is performed until a break, is called (“fallthrough”). Since this is often not desired, using this
option required a comment whenever a break is missing. The default-label ist optional and is
visited if none of the other labels is valid in the case-list.

Exercises

Exercise 17.1.
Modify the program from Exercise 15.4, so that it asks the users if he/she wants to enter 2 or
3 numbers. Read in the correct number of inputs and compute the sum. 

Exercise 17.2.
Write a program that reads in a date in the format dd/mm/yyyy format and prints out 12th of
March 2010 etc... 
Chapter 18
Loop control structures

Often you want to repeat sections of a program, the most common way is using for-loops.
Alternatively, the rejecting while()- and the accepting do{...}while()-loops exist.

18.1 (do) while-loops

Loops that are constructed using while are executed until the condition in the condition part of
the loop is not true anymore. Is the condition already false at first occurence of the while-loop,
the loop will not be executed at all.

ch ar c =0; // ' l o o p i n i t i a l i s a t i o n '


w h i l e ( c != ' y ' && c != ' n ' ) // f i r s t time c==0, s o we e n t e r th e l o o p
c i n >> c ; // can a l s o be a b l o c k { }

The symbol/character variable has to be initialised such that the loop is entered. In such cases,
the do ... while(...) loop might be more intuitive.

ch ar c ;
do {
c i n >> c ;
} w h i l e ( c != ' y ' && c != ' n ' ) ;

– 131 –
18.2. for-loops 132

18.2 for-loops

When working with fields, one often needs loops that access all elements of a field, one by one.
One can program this with while:

const int Size = 20;


// . .
int a [ Size ] ;
// . .
i n t i =0; // l o o p i n i t i a l i s a t i o n
while ( i < Size ) // l o o p c o n d i t i o n , r e j e c t i n g i f f a l s e
{
a[ i ] = i ;
i ++; // l o o p c o n t r o l , p er f or m ed a f t e r each p a s s
}

A shorter alternative used the for(;;) loop. The following is almost equivalent to the above,
but shorter by avoiding the line with i, and more clear, since the begin, end, and stepsize of the
loop are defined at its start.

int a [ 2 0 ] ;
// . .
f o r ( i n t i =0; i < 2 0 ; i++ )
a[ i ] = i ; // work on e l e m e n t s 0 . . 19

There are two advantages: First, the loop-beginning, -ending, and stepping is nicely combined
in one line and, second, the variable i is only defined within the loop and not used (and not
needed) outside.

18.3 break and continue

In order to exit a single, not-nested for or while loop, one can use the break command. The
loop is terminated and the program continues directly after the loop. Thus break can be used
to terminate loops under certain conditions, earlier than the loop implies, or it can be used to
exit “endless” loops.

// copy i n p u t to ou tp u t
while ( true )
{
ch ar c ;
c i n >> c ;
i f ( c i n . f a i l ( ) ) b r eak ; // end o f i n p u t or s om eth in g wrong
cou t << c ;
}
18.3. break and continue 133

The command continue terminates the processing of the present block and continues, dependent
on the type of the loop, at the corresponding control-command (for(;;)), or ((do{}) while()).

#i n c l u d e <cmath> // f o r s q r t ( ) f u n c t i o n

d ou b le a [ 2 0 ] ;
// . . .
d ou b le s u m s q r t = 0 . ;
f o r ( i n t i =0; i < 2 0 ; i++ )
{
i f ( a [ i ] < 0. ) continue ; // work on n ext elem en t
s u m s q r t += s q r t ( a [ i ] ) ;
}

Note again that continue and break only exit the innermost loop-block and cannot be used to
exit nested loops.

Exercises

Exercise 18.1.
Write a code which reads in N numbers and computes their sum. 

Exercise 18.2.
Write a program to compute the squares of all integers between two numbers. 

Exercise 18.3.
Write a program that computes the factorial of an inputed number N . Recall the factorial of
N = N ∗ (N − 1) ∗ (N − 2) ∗ ... ∗ 1. 
Chapter 19
Functions and Operators

Longer programs usually contain parts or blocks that are repeated a certain (large) number of
times. These parts can then be defined elsewehere (as a function) and within the program are
replaced by a short-cut or place-holder, i.e., the name of the function. It is wise to give the
function a name that already implies its function.

A function (also called procedure or subroutine in other languages), has input and output
variables/parameters. In the simplest case the transfer of input-parameters is done as argument,
and the output as a return-value.

C++ enforces that the types of input and output are specified. In the following example, the
function power computes from a double base value and an integer number exponent a new
number in double precision that is returned to the calling function/program. The name already
implies the algorithm used here.

// r a i s e ' b as e ' to th e power ' exponent ' , with exponent b e i n g i n t e g e r ,


// b as e b e i n g d ou b le ; a c c e p t a l s o n e g a t i v e exp on en ts and ch eck . . .
d ou b le power ( d ou b le base , i n t exponent ){
d ou b le r e s u l t = 1 . ; // w i l l m u l t i p l y t h i s b as e ' exponent ' t i m e s
bool n eg exp = f a l s e ;
i f ( exponent < 0 ) // f o r n e g a t i v e exp on en ts we u s e a s i n g l e
{ // d i v i s i o n at th e end o f th e f u n c t i o n
n eg exp = t r u e ;
exponent = −exponent ;
}
f o r ( i n t i =0; i < exponent ; i++ )
r e s u l t ∗= b as e ; // s u c c e s s i v e m u l t i p l i c a t i o n

i f ( n eg exp ) // have to t a k e th e i n v e r s e
r es u lt = 1./ r es u lt ;

– 134 –
135

return r e s u l t ; // r e t u r n th e r e s u l t to th e c a l l i n g program
}

Exercise 19.1.
Search for the explanation of Flow-Chart in, e.g., Wikipedia, and plot the Flow-Chart of the
Power-Function. 

Note that C++ already has a function pow that is described by


double pow(double base, double exponent),
only different in the type of the exponent.

The names of the arguments are free to be chosen. Inside the function block these names are to
be used. Note that like for loops, there is no semicolon after the function.

The keyword return terminates the function at the specified position, moves the value of the
variable specified after it on the stack, and returns to the calling program. In the case above,
the expression consists only of a single variable result. Round brackets are not required here.
A subroutine can contain several return keywords at different places in the function block. This
can be a useful tool to deal with problems/errors. Hence the return command can be used to
exit deeply nested for loop to forcing the exit of the whole function.

Finally, one has to define or declare a function before it can be used in the program. This
declaration is essentially the first line of the function (with semicolon). This so-called prototype
tells the compiler the name of the function and the types of it and its arguments. Actually, if
you careful about the order you do not need to prototype functions, but you must place the full
function definition before the first call (use) of the function. This is often tricky to keep track
of and prototyping is recommended.

d ou b le power ( d ou b le base , i n t exponent ) ;

At first definition, the command block is replaced by the single semicolon. Note that the type
is required, but the name of the arguments in the function is not needed here. However, a clear
program specifies variables that tell something about their purpose.

Declarations can (in principle) be repeated arbitrarily often in a program – they are a promise
to the compiler that the function will be defined later. Unlike variables, functions are always
global – it is not allowed to define them inside a block with limited existence. Actually function
and varibles can be wrapped together in a very neat package, called a class, see §?? for more
details, solving this global scope problem.

A program that reads a number from the keyboard and then uses the function power to finally
write the result could look like this.

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;

d ou b le power ( d ou b le base , i n t exponent ) ; // d e c l a r a t i o n o f ' power '


19.1. Transfer of arguments 136

i n t main ( ) // d e f i n i t i o n o f main
{
d ou b le i n ;
c i n >> i n ; // r ead v a l u e from keyboard

cou t << ”−3rd to 3 rd power o f ” << i n << ” : ” ;


f o r ( i n t i= −3; i <= 3 ; i++ ){
cou t << power ( in , i ) << ” ” ; // c a l l power and u s e r e t u r n v a l u e
}
cou t << ” \n” ;

return 0; // r e t u r n to o p e r a t i n g system
}

d ou b le power ( d ou b le base , i n t exponent ) // d e f i n i t i o n o f power


{
d ou b le r e s u l t = 1 . ;
// . . . program t e x t as above

return r e s u l t ;
}

19.1 Transfer of arguments

The transfer of arguments to a function takes place “by value”, i.e., before the function is called,
the arguments are copied and the function uses these copies. This way, the variables that contain
the values that are transferred to the function can not be changed. If this is desired, e.g., because
one return value is not enough and many variables are to be changed in a function, then one
either use pointers, as disucssed later in section 20 or pass by reference.

If you add & after a variable name in the declaration the actually variable, not a copy, is passed
to the function, therefore changes to that variable within the function effect the original variable.

19.1.1 Example of passing by reference

#i n c l u d e <i o s t r e a m >
#i n c l u d e <v a l a r r a y >

u s i n g namespace s t d ;

i n t add ( i n t a , i n t b ) ;

i n t add2 ( i n t &a , i n t &b ) ;


19.2. Functions without arguments or return value – void 137

i n t main ( )
{
i n t a =1;
i n t b=2;
cou t << a <<” ”<<b << e n d l ;
cou t << add ( a , b ) << e n d l ;
cou t << a << ” ” <<b <<e n d l ;

cou t << a << ” ” << b <<e n d l ;


cou t << add2 ( a , b)<<e n d l ;
cou t << a << ” ” << b << e n d l ;
return 0;
}

i n t add ( i n t a , i n t b )
{
a=a+b ;
return a ;
}

i n t add2 ( i n t &a , i n t &b )


{
a=a+b ;
return a ;
}

Exercise 19.2.
Run this program and from the output explain the difference between the functions add and
add2. 

19.2 Functions without arguments or return value – void

The keyword void can be used like a type, but is not really a type. It is useful to mark functions
that do not have a return value. Examples are functions that just write something to the screen
or to a file and functions that modify the input-variables directly.

v o i d e r r o r ( s t r i n g message ){
cou t << ” e r r o r o c c u r e d : ” << message << ”\n” ;
}

Also functions without arguments sometimes can be useful. In C++ this is implied by an empty
list of arguments like for the pseudo-randomnumber generator as declared in the C library
stdlib.h:

v o i d s r an d ( u n s i g n e d i n t s e e d ) ;
i n t rand ( v o i d ) ;
19.3. Libraries 138

It is used by first selecting a sequence of random numbers by calling (once only) the initialisation
function srand(.) with a positive number. Then, for each call of rand() a new, integer number
is returned. In order to transform the integers to real numbers, one can e.g. divide by the
maximum.

Exercise 19.3.
Use the random number generator of C++ and later the random numbers in MATLAB to
generate a vector of 10 random numbers ri=1,...,10 ∈ [0, 1]. 

19.3 Libraries

As seen in previous examples, declarations/prototypes are sufficient for the compiler to translate
a program. Wherever called in the program, the function call is prepared during compilation.
The function itself can be then defined and “linked” to the program later. Function-definitions
are found in so-called object-files (*.o) or libraries (see section §24 for more information of code
organisation into small objects, which are compiled and linked independently).

The classical example for a library is the cmath file that was included at the beginning and
involves functions like the sqrt(). The declarations are found in cmath itself, and the translat-
ed/compiled definitions are found in libm.a. A program-block that uses the sqrt() function
can look like this.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <cmath>
u s i n g namespace s t d ;

i n t main ( )
{
d ou b le d ;
cou t << ” Enter a number : ” << e n d l ;
c i n >> d ;

i f ( d<0 )
cou t << ”Cannot compute th e r o o t o f n e g a t i v e numbers ” << e n d l ;
e l s e // compute s q r t ( d ) and p r i n t v a l u e
cou t << ” s q r t ( ” << d << ” ) = ” << s q r t ( d ) << e n d l ;
return 0;
}

The compiler must contain the linker-option “-lm” and must know the correct path where it can
find the library (note, some compilers do this automatically). As a remark, under LINUX, the
compilation would look like this:

g++ myprog.cc -o myprog -lm

In DevC++ the corresponding command can be found under “Compilation”.


19.4. inline functions 139

The short -l means “library” and m is the abbreviation for the file libm.a, that one gets by
adding lib, m and the ending .a.

19.4 inline functions

In general, several things happen when a function is either called or closed. Some of this can be
avoided or optimised by use of so-called inline-functions. However, we will not go into detail
here. (Further reading if needed).

19.5 Overloading of functions

In contrast to C and some other languages, in C++ not only the name and type of a function,
but also the types of the arguments are relevant. Therefore it is possible to define a function
for each type int, double or struct Date {...}, all with the same name. The name does not
have to contain type information thus. In C++, the compiler selects the right function with the
appropriate type by itself. One can think of an internal function-name used by the compiler
that also contains the argument-types.

v o i d swap ( i n t &a , i n t &b ) // i n t e r n a l name e . g . s w a p i n t i n t


{
i n t tmp = a ;
a = b ; b = tmp ;
}

v o i d swap ( d ou b le &a , d ou b le &b ) // s w a p d o u b l e d o u b l e


{
d ou b le tmp = a ;
a = b ; b = tmp ;
}

void f ( )
{
d ou b le a , b ;
int i, j;
// . . .
swap ( a , b ) ; // d ou b le v e r s i o n
swap ( i , j ) ; // i n t version
}

19.6 Templated functions

In C++ it is possible to right functions were the type of the variables is free.
19.6. Templated functions 140

tem p late<c l a s s T>


T add (T a , T b )
{
r e t u r n a+b ;
}

The following call to the functions add<int>(3,4) would automatically create the following
code.

i n t add ( i n t a , i n t b )
{
r e t u r n a+b ;
}

That is the above templated function can be used for any type T, well, for which the operator
+ is defined.

Multiply template arguments can be used, for example:

tem p late<c l a s s T1 , c l a s s T2>


T2 add (T1 a , T2 b )
{
r e t u r n a+b ;
}

The call add<int,double>(a,b) would add the double b to int a and return a double. That
is add<int,double>(2.3,4.3) would return 6.3; whereas add<double,int>(2.3,4.3) would
return 6.

Exercises

Exercise 19.4.
Write a program that reads in ten numbers, using the swap function above sort the numbers into
ascending order and write out the order list. See http://en.wikipedia.org/wiki/Bubble_sort
for more information. 

Exercise 19.5.
Write a function, which calls itself, to calculate the N th Fibonacci number. Recall f ib(N ) =
f ib(N − 1) + f ib(N − 2) and f ib(1) = 0, f ib(2) = 1. 
Chapter 20
Pointers, pointer-field duality, and references

20.1 Pointers

From the viewpoint of the computer, every memory-cell in the (virtual) memory is uniquely
marked by a certain number (address).

C++ allows to use these adresses in memory-space for programming purposes. Since it is
allowed to self-define names for these address-pointers, the program can also become much more
clear and readable. The declarations:

int i =5;
d ou b le a = 1 2 . 3 4 ;
ch ar ∗ c1=” h e l l o ” ; // d e c l a r a t i o n o f an a r r a y o f ch ar
int j =0;

create the memory-entries in Fig. 20.1 (left column). Only the memory-entries (the values of
the variables) occupy space in the computer memory. The names of variables do not occupy
space even if one would use instead of i the more meaningful name counter.

In general, there is no guarantee that sequentially defined varibales also occupy memory sequen-
tially (except for fields). The variable c1 of type char contains a pointer to another range of
memory where the values of the field are stored. The definition of *c1 reserves some range in
memory that is large enough to store the word "hello". The elements 'h', 'e', 'l', 'l', and
'o' can also be accessed using the form c1[0], c1[1], c1[2], c1[3], and c1[4]. Note again
that numbering in C++ always starts with 0.

If one has to insert or delete a range of a sorted list (quickly and efficiently), then this is not
possible using a linear field like the above *c1. A linear field is special in so far that all data
are stored in subsequent positions in memory. As well inserting as removing entries from this

– 141 –
20.1. Pointers 142

e f.) ef.)
p.d r-d
m se
s (co e (u
l ue res m
va ad na
5 0xfd10 i
12.34 0xfd18 a
0xff10 0xfd20 &c1
0 0xfd28 j
...
h 0xff10 c1[0]
e 0xff11 c1[1]
l 0xff12 c1[2]
l 0xff13 c1[3]
o 0xff14 c1[4]
\0 0xff15 c1[5]
...

Figure 20.1: (Schematic) memory occupations (left), computer-internal memory adress (mid),
and (user-defined) name of variables (right).

field requires copying the full range “above” the modified element. (In average that is half the
field-length to be moved). This is acceptable for short fields but not for long ones. A possible
solution to this is a linked list which contains not only the values of the elements but also the
information where the next element can be found. The actual location does not matter, i.e.,
only the names of the memory-cells have to be modified. For example, in order to remove an
element x from a linked list, only the name entry of the previous element has to be changed such
that it does not point to x anymore, but to the following element. This information is available
in the x-element and thus just has to be copied. Deleting several subsequent entries requires
the same effort and entering a (part of a) linked list from somewhere else is also rather efficient.
However, due to this additional options, a linked list also usually requires more memory than a
normal field.

In order to allow a computer independent dealing with such objects like linked lists, C++
provides also the type pointer. A pointer can point to an arbitrary data-type – which actually
could be a pointer itself. In order to declare a pointer, a (star) * is used. In order to get the
address of a variable, the &-operator is used. The declarations in the program-fragment:

// D e c l a r a t i o n p a r t
int i = 5; // i n i t i a l i s a t i o n
i n t ∗ p i = &i ; // p i i s a p o i n t e r to an i n t ,
// h e r e th e v a r i a b l e i
i n t ∗∗ p p i = (& p i ) ; // p o i n t e r to p o i n t e r to i n t

// How to u s e ∗ and & l e g a l l y i n th e program


20.1. Pointers 143

DATA DATA

DATA

DATA

11111
00000
00000
11111
00000
11111 DATA

00000
11111
DATA
00000
11111
DATA

Figure 20.2: Use of pointers in a linked list. (Top) the list before an element is removed,
(bottom) the list after, where the black element denotes the removed one that is not part of the
list anymore.

i = 0; // s e t i to 0
∗p i = 1; // s e t i to 1 , p i r em ain s unchanged
∗∗ p p i = 2; // s e t i to 2 , p i r em ain s unchanged
int j = 7; // d e c l a r e another i n t e g e r j
∗ pp i = &j ; // change p i to p o i n t on j , ∗ p i != i
p i = &i ; // l e t p i p o i n t to i a g a i n

lead to memory occupation as indicated in Fig. 20.3.

5 0xfa10 i
* ...
0xfa10 0xfc28 pi
* ...
0xfc28 0xfe08 ppi
...

Figure 20.3: Memory occupation as in Fig. 20.1.

In order to change the value of a variable a pointer points to, or in order to use this value in an
operation, also the * operator is used.
20.1. Pointers 144

∗ p i = 27; // i i s 27 now
∗ p i = 2 ∗ (∗ p i ) + 5; // e q u i v a l e n t to : i = 2 ∗ i + 5;

Constant pointers are declared by using a const right of the pointer-symbol *. They must be
initialised already at declaration, since they are fixed thereafter and cannot be changed anymore.

c o n s t i n t ∗ c p i = &i ; // ok , i can n ot be changed


// th r ou gh u s e o f c p i
// c p i can be changed
c o n s t ch ar n e w l i n e = ' \n ' ;
c o n s t ch ar ∗ c o n s t p n l = &n e w l i n e ; // c o n s t p o i n t e r to c o n s t ch ar
// n ote : p n l = ' 0 ' ; −> e r r o r !

The * operator has thus two meanings: In a variable declaration, it marks a pointer, whereas in
front of a variable (of type pointer) it leads to access on the memory (value) of the corresponding
memory space.

Analogously, also the & operator has two meanings: During variable declaration, it denotes a
reference, whereas in front of a variable, it is the so-called address of operator, i.e. it provides
the address of the variable.

Note that it is possible to do arithmetics/mathematics with pointers. Above, p_i = p_i + 5


would let the pointer point to 5 int memory entries further. For this, the compiler needs to
know how big the corresponding data-type is. Also the difference of pointers can be formed but
that makes only sense inside a field.

Navigation within a field can be done in the following way:

int p [ 3 0 ] ; // declare a f i e l d of int


∗ ( p i + 25) = 15; // th e v a l u e o f th e 25 th e n t r y ( p a s t th e one
// p o i n t e d to by p i ) i s s e t to 15
p i [25] = 15; // equivalent . . .

The language guarantees that 0 is never the address of a real data-element. A pointer with value
0 can thus be used to indicate an error or, e.g., the end of a list.

20.1.1 Pointer to void

The type pointer to void is generic. It is guaranteed that any pointer can be transferred into
a pointer to void, without loss of information. In C the void * was often used to transfer
information to functions/routines that can deal with arbitrary pointers. (e.g. sort-function
like quicksort, or the return value of malloc). In C++ it is recommended to use template-
functions that guarantee type-consistency and type-safety, see section 19.6 for more details.
20.2. pointer-field duality 145

20.2 pointer-field duality

Between pointers and fields exists a very close relation, see above the use of [] for the “indirect”
de-referencing of pointers. A field a[..] is internally transformed to a pointer on the first
element of the field. Access to the field is then dealt with via the pointer-arithmetics mentioned
above. This is also the reason why C++-fields always start with 0 (i.e. the localisation of field
entries can be done with less operations).

int a [ 2 0 ] ;
int ∗ p = a ; // ok , a i s name o f th e f i e l d and can
// be used as a d d r e s s to th e f i e l d
i n t ∗ p = &(a [ 0 ] ) ; // . . . e q u i v a l e n t

p [ 5 ] = 4; // a c c e s s to a th r ou gh p o i n t e r a r i t h m e t i c ,
// a [ 5 ] i s s e t to th e v a l u e o f 4
a [ 5 ] = 4; // . . . e q u i v a l e n t

int b [ 2 0 ] [ 3 0 ] ; // b i s now an a r r a y o f 20 a r r a y s o f
// 30 e l e m e n t s o f typ e i n t
// i n t ∗p = b ; e r r o r ! wrong type , s i n c e
// b i s o f typ e p o i n t e r to 30 i n t h e r e
int ∗ r = b [ 0 ] ; // ok , r p o i n t s to th e f i r s t i n t
// i n th e f i r s t ( o f 20) a r r a y ( s ) o f 30 i n t s
i n t (∗ q ) [ 3 0 ] = b ; // ok , q p o i n t s to th e f i r s t s e t o f 30 i n t ' s ,
// q and b can now be used synonymous
q [ 1 2 ] [ 1 5 ] = 26; // ok , s e t elem en t ( 1 3 , 1 6 ) to th e v a l u e 26
( ∗ ( q + 1 2 ) ) [ 1 5 ] = 2 6 ; // . . . equivalent
∗ ( ∗ ( q+12)+15) = 2 6 ; // . . . equivalent
b [ 1 2 ] [ 1 5 ] = 26; // . . . equivalent

Exercise 20.1.
Practice the use of pointers, using the above examples as a starting point. 

20.3 Transfer of field-variables to functions

In order to transfer a field to a function, it is sufficient to just transfer the pointer, see sec. 19.
For a one-dimensional field this is just the pointer to the first element, while for two-d fields it
is a pointer to a field with a compatible, fixed number of elements. Only the first dimension of
the field can be left out in this case, all others have to be specified at compile-time. This makes
the C-type fields rather in-practical to be used when dynamic memory management is desired.

void f ( i n t b [ ] [ 3 0 ] ) // f u n c t i o n p r o t o t y p e t h a t t r a n s f e r s b
void g ( i n t (∗ q ) [ 3 0 ] ) // f u n c t i o n p r o t o t y p e t h a t t r a n s f e r s

int b[20][30];
20.3. Transfer of field-variables to functions 146

int c [10][30];
int d[15][31];

f ( b ) ; g ( b ) ; f ( c ) ; g ( c ) ; // ok
f (d ) ; g(d ) ; // e r r o r s , s i n c e s econ d d im en s ion not ==30

Summary: Transfer of Variables to Functions

As summary and examples for the use of fields in functions, the example in exercise 7 is re-written
in order to use functions that use the field:

#i n c l u d e <c s t d l i b >
#i n c l u d e <i o s t r e a m >
#i n c l u d e <cmath>
u s i n g namespace s t d ;

int r e a d f i e l d ( int flen , int ∗ f i ) ;


void w r i t e f i e l d ( i n t flen , i n t ∗ f i ) ;
void s o r t f i e l d ( i n t flen , i n t ∗ f i ) ;

i n t main ( i n t ar gc , ch ar ∗ ar gv [ ] )
{
c o n s t i n t Mfmax=20;
i n t f i [ Mfmax ] ;
i n t ifmax =0;
i n t ftmp ;

ifmax = r e a d f i e l d ( ifmax , f i ) ; // g e t f i e l d from s u b r o u t i n e


w r i t e f i e l d ( ifmax , f i ) ; // c o n t r o l what you got

s o r t f i e l d ( ifmax , f i ) ; // s o r t th e f i e l d
w r i t e f i e l d ( ifmax , f i ) ; // c o n t r o l what you got

system ( ”PAUSE” ) ;
return 0;
}

// f u n c t i o n r e a d s th e f i e l d from a n o t h e r f i e l d and r e t u r n s i t back


int r e a d f i e l d ( int flen , int ∗ f i )
{
c o n s t i n t f i e l d l e n g t h =17;
i n t f i e l d [ f i e l d l e n g t h ] = {1 , 0 , −10, 12 , −2, 5 , 5 , 1 , −4, −2,
−4, −8, 3 , 25 , 51 , −4, −5};
f o r ( i n t i =0; i <f i e l d l e n g t h ; i ++)
{
f i [ i ]= f i e l d [ i ] ;
}
flen = field length ;
20.3. Transfer of field-variables to functions 147

return f l e n ;
}

// f u n c t i o n w r i t e s f i e l d to s c r e e n
void w r i t e f i e l d ( i n t flen , i n t ∗ f i )
{
f o r ( i n t i =0; i <f l e n ; i ++)
cou t << f i [ i ] << ” ” ;
cou t << e n d l ;
return ;
}

// f u n c t i o n s o r t s th e f i e l d and r e t u r n s i t
void s o r t f i e l d ( i n t flen , i n t ∗ f i )
{
i n t ftmp ;
f o r ( i n t i =0; i <f l e n ; i ++)
{
f o r ( i n t j=f l e n −1; j >=1; j −−)
{
i f ( f i [ j ]< f i [ j −1])
{
ftmp= f i [ j − 1 ] ;
f i [ j −1]= f i [ j ] ;
f i [ j ]= ftmp ;
}
}
}
}

Excerises

Exercise 20.2.
Consider the following code extract and explain the effect of each line, stating the value of a
and b at all points.

i n t a =15;
i n t b=10;

i n t ∗p1=&a ;
i n t ∗p2=&b ;

i n t ∗∗ p3=(&p1 ) ;

∗p1 =5;
∗p2 =20;
∗∗ p3 =1;
20.4. Dynamical Memory Management 148

∗p2=∗p1 ;
p1=p2 ;
∗p1 =10;
∗p2=5
∗∗ p3 =8;

cou t << a << ” \ t ” << b << e n d l ;

20.4 Dynamical Memory Management

In order to request memory, C++ provides the operators new and new [] for single variables or
for fields, respectively. This memory is allocated without a scope (see section 16.3.7) and must
be freed manually. In order to free the memory, delete and delete [] have to be used.

int ∗ p i = new i n t ; // d e c l a r e new v a r i a b l e w ith ou t s c o p e


int n = 40;
int ∗ p a i = new i n t [ n ] ; // d e c l a r e new a r r a y w ith ou t s c o p e
// . . .
delete p i;
delete [ ] pa i ;

The request for memory requires the type after new, and a pointer to this new element is
returned. For fields, new[] is used and the number of memory-elements within the brackets is
requested. The request returns a pointer to the first element in the field.

i n t ∗ p a i = new i n t [ n ] ;

pa i [0]=5;
pa i [1]=4;

The operator new returns an “exception” bad_alloc, if the request for memory does not succeed
and then terminates. It is possible to ’catch’ error and continue without ending the code, using
the commands try and catch (this will not be covered by this course).

Note that in many compilers it is possible to allocate memory dynamically using VLA’s (e.g.,
int N=10; int a[N]; allocates a dynamic array, since N is not constant). However, we discour-
age you from using this, as it is not supported by the C++ standard (see http://www.informit.com/guides/co
and can lead to segmentation faults when large dynamic arrays (> 106 bytes) are allocated.
Chapter 21
Object Oriented Programming I: Containers in the
Standard Template Library

21.1 C++ standard classes

A container is a data structure (specifically a ‘holder object’) which can store multiple other C++
objects (its ‘elements’) in an (ordered) structure. Containers can be used to create structures
which are commonly used in C++ (and indeed other programming languages) such as dynamic
arrays, queues, stacks , lists, associative arrays and many more... Different containers may be
used to provide a solution to the same problem; however, dependent on the specific problem
at hand, some may be much more efficient than others. Therefore it is important to have a
good knowledge of the various containers available to us, so that we can always choose the right
container for the task, and hence make our programs as fast and functional as possible!

In this chapter, we will learn how to use some of the most important STL containers (these
being the predefined, ‘ready to use’ container classes from the standard template library). Later
on, once we fully understand what classes are and how to work with them, we will learn how to
create our own classes.

Most of the objects found in the standard template library are templated to make them flexible
and usable with numerous different data types – a matter which we have discussed in previous
chapters. We have been using these for some time without exactly understanding the syntax.

The first example we have met so far was numeric_limits<int>::min(). So here clearly it
is templated with a type, in this example int, and we call the static member function min().
Note, :: calls static member function, whose purpose we have not covered in the discussion
above and will not in this short course.

A second example we have seen is

– 149 –
21.2. Arrays 150

#i n c l u d e <s s tr eam>
#i n c l u d e <f s t r e a m >
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;

i n t main ( )
{
stringstream file name ;
s t r i n g s t r e a m problem name ( ” my problem ” ) ;
ofstream s c r i p t f i l e ;
f i l e n a m e << problem name . s t r ( ) <<” . d i s p ” ;
s c r i p t f i l e . open ( ( f i l e n a m e . s t r ( ) ) . c s t r ( ) ) ;
// . .
s c r i p t f i l e . close ( );
return 0;
}

In this example str() is a member function of stringstream that return a string. Then
c_str() is a member function of string that returns a const char*, i.e. a constant character
array.

Full listing of all standard C++ libraries can be found at http://www.cplusplus.com. Note,
many of the higher classes inherit from the more basic ones. For example both isstream and
ifstream inherit from istream, this explains why both type of streams have similar methods
defined and can be interchanged so easily.

In the remainder of this section, we introduce and learn how to use some commonly-implemented
and highly useful standard classes.

21.2 Arrays

One of the most basic types of container is the std::array, which allows us to store and access
an ordered series of elements.

It is important to note here that a std::array is entirely distinct from the arrays you have
used thus far. The new C++11 version of an array is very different in terms of the syntax
used for its declaration, and – importantly – possesses many highly valuable new features
which cannot be used with the old-style C++ arrays. A std::array is written in the following
form:

std::array<TYPE,SIZE> name;

Here, the first and second terms inside the specialisation brackets, <>, can be used, respectively,
to choose the type of variable to be stored (i.e. int, float, char...) and the size of the array,
i.e. how many individual variables are stored. For instance, if we want an array that holds 10
21.2. Arrays 151

integer numbers, we would simply type:

std::array<int,10>

The entire phrase std::array<TYPE,SIZE> acts like a ‘normal’ type declaration, i.e. in the same
way that if we want an integer called ‘i’ we type ’int i’, if we want an array of integers with
size 10 called ‘a’ we type:

std::array<int,10> a

Note that once the size of an std::array has been declared, there is no way to change it (to
put it in C++ terms, an std::array cannot be ‘resized’).

Each element of an array can be treated as an individual variable. For instance, in our hy-
pothetical array of ints, each element is treated as an int, i.e. can be used to store a single
integer value. An individual element can be accessed using square brackets containing its po-
sition within the array. For example if we want to store a value of 3 in the 1st element of our
array, ‘a’, we would simply type:

a[0] = 3;

Note that the numbering in an array starts at zero!

Below, we see a very simple example of an array being declared, each of its members being
assigned a value, and then these values read out in turn:

#i n c l u d e <i o s t r e a m >
// n ote t h a t we need to i n c l u d e t h i s h ead er i f we want to u s e a r r a y s !
#i n c l u d e <ar r ay >
i n t main ( ) {
// d e c l a r i n g our ar r ay , such t h a t i t can t a k e up to 5 i n t e g e r v a l u e s
s t d : : ar r ay<i n t ,5> a ;
// a s s i g n i n g v a l u e s to each member o f th e a r r a y
a [ 0 ] = 1;
a [ 1 ] = 2;
a [ 2 ] = 3;
// n ote t h a t t h e s e v a l u e s do not have to be a s s i g n e d i n o r d e r
a [ 4 ] = 5;
a [ 3 ] = 4;
// o u t p u t t i n g our v a l u e s , i n o r d e r
f o r ( i n t i = 0 ; i < 5 ; i ++) {
cou t << ”a [ ”<< i << ” ] = ” << a [ i ] << e n d l ;
}
return 0;
}

std::arrays (like other STL containers) also possess several in-built methods, which are ef-
fectively ready-to-use functions that come ‘packaged’ with a given container. The methods
belonging to a container class can be accessed using the dot operator in the manner:
21.2. Arrays 152

std :: array<TYPE,SIZE> number; Define a list.


number[n] The nth element.
number.size() The length of the list.

Table 21.1: A summary of the array class

containerName.method

An example is the ”size()” method. For our array a, we can simply type:

a.size()

and this method will return, as the name implies, the size of our array (i.e. the number of
elements it possesses). Note that when calling the size function we do not include the square
brackets. The size method can be simply implemented in a code as follows:

#i n c l u d e <i o s t r e a m >
#i n c l u d e <ar r ay >

main ( ) {
// d e c l a r i n g an a r b i t r a r y p a i r o f a r r a y s
s t d : : ar r ay<i n t ,3> a ;
s t d : : ar r ay<f l o a t ,20 > b ;
// o u t p u t t i n g th e s i z e o f our a r r a y s u s i n g s i z e ( )
s t d : : cou t << ” Array a has ” << a . s i z e ( ) << ” e l e m e n t s ” << s t d : : e n d l ;
s t d : : cou t << ” Array b has ” << b . s i z e ( ) << ” e l e m e n t s ” << s t d : : e n d l ;
return 0;
}

Note that you can also intitialize an array while declaring it; for instance, by typing:

std::array<bool,100> c = {true};

you can, in one line, declare all 100 elements of an array of bools as ‘true’. This is very useful if,
for instance, you want to easily ‘clear’ an array. Note here the importance of the curly brackets
– the code will not compile without these!

Exercise 21.1.
Write an array to store the squares of all the numbers between 1 and 20 and another to store
the corresponding cubes. Output the data in columns alongside their root.

Harder: Write a program to find all the prime numbers between 1 and 100 as efficiently as
possible (Note: this question was once used as part of the interview process to become a
programmer for Google – so don’t be ashamed if you need a few hints!) 
21.3. Vectors 153

21.3 Vectors

std::vectors are arguably the most used, and most useful, of all container classes. std::vectors
can be used exactly like std::arrays but – unlike std::arrays, they have a variable size, mak-
ing them much more flexible. Vectors can either be resized ‘manually’ using the ‘resize()’
member function of the vector class. They will also automatically resize when elements are
added or removed from the vector array.

The resize() function, like the size() function from the previous section, is called with dot
operator, i.e. vectorName.resize(newSize);

where ‘newSize’ is simply the total number of elements you want your resized vector to possess.
The dot operator is always used to call functions that are members of the class on which they
are used. Given below is an example of the resize() function in action (as well as a reminder
of the size() function):

#i n c l u d e <i o s t r e a m >
// as with a r r a y s , we need to i n c l u d e th e r e l e v a n t h ead er which a l l o w s us to u
#i n c l u d e <v e c t o r >

i n t main ( ) {
i n t mySize ;
// d e c l a r i n g a v e c t o r with z e r o l e n g t h !
s t d : : v e c t o r <double> v ;
// o u t p u t t i n g th e s i z e o f th e v e c t o r
s t d : : cou t << v . s i z e ( ) << s t d : : e n d l ;
// i n c r e a s i n g th e s i z e o f th e v e c t o r . . .
v . resize (10);
// . . . and o u t p u t t i n g i t s new s i z e !
s t d : : cou t << v . s i z e ( ) << s t d : : e n d l ;
// prompting th e u s e r to g i v e a new s i z e f o r th e v e c t o r . . .
s t d : : cou t << ”How b i g do you want your v e c t o r ? ” << s t d : : e n d l ;
s t d : : c i n >> mySize ;
// . . . and ch an gin g th e v e c t o r s i z e a g a i n !
//As you p r ob ab ly e x p e c t by now , th e r e s i z e f u n c t i o n can t a k e u s er −d e f i n e d
v . r e s i z e ( mySize ) ;
s t d : : cou t << ”Your v e c t o r now has ” << v . s i z e ( ) << ” e l e m e n t s . ” << s t d : : e n d l
return 0;
}

Vectors in fact possess a number of useful member functions, such as the push back() and
pop back() functions that can be used, respectively, to add and remove elements of a given
array. Although we will not discuss these functions here, you should now know enough to learn
about (and use!) them on your own!

Exercise 21.2.
Define a zero-size vector. Based on user input, resize this vector to accommodate a given number
of values. Read in values from the console to fill your vector, and then calculate the average of
21.4. Strings 154

the numbers given.

Try writing a similar program using arrays – a nice example of how much more efficient vectors
can be! 

21.4 Strings

Another C++ function that has been ‘updated’ in the C++11 standard is the string, or now
std::string. As with arrays, the new-version strings possess a wealth of functionality not
available with the original version of the data type.

Our first example shows a simple application of an std::string, demonstrating that their basic
use is extremely similar to that of an ‘old-fashioned’ non-STL string. We use for our example a
very useful real-world application of strings – the verification of a username/password pair:

// once again , we need to i n c l u d e th e n e c e s s a r y h ead er i n o r d e r to u s e our new


#i n c l u d e <s t r i n g >
#i n c l u d e <i o s t r e a m >

i n t main ( ) {
// d e c l a r i n g a p a i r o f s t d : : s t r i n g s .
s t d : : s t r i n g username ;
s t d : : s t r i n g password ;
// d e c l a r i n g and d e f i n i n g a s t r i n g i n one s t e p
// n ote t h a t s t r i n g s w i l l a c c e p t p u n ctu ation , s p a c e s and i n d e e d any o t h e r c h
s t d : : s t r i n g savedUsername ( ”b . g a t e s ” ) ;
// n ote t h a t s t r i n g s can be d e c l a r e d and d e f i n e d i n th e above manner , but a l
s t d : : s t r i n g savedPassword = ” I h 8 a p p l e ” ;
// n ote i n both o f th e above t h a t th e s t r i n g to be s t o r e d must be s u r r ou n d ed
s t d : : cou t << ” Enter your username : ” << s t d : : e n d l ;
// n ote a l s o t h a t when r e a d i n g i n from th e c o n s o l e , you do NOT need to i n c l u
s t d : : c i n >> username ;
s t d : : cou t << ” Enter your password : ” << s t d : : e n d l ;
s t d : : c i n >> password ;
// c h e c k i n g i f username and password match
i f ( ( password == savedPassword ) && ( username == savedUsername ) ) {
s t d : : cou t << ” Password a c c e p t e d ” << s t d : : e n d l ;
}
else {
s t d : : cou t << ” I n c o r r e c t username / password com b in ation . Armed gu ar d s a r e
}
return 0;
}

Next, we introduce some of the more outlandish things we can do with a std::string, for instance
performing arithmetic to make phrases out of words or longer phrases out of phrases!
21.4. Strings 155

#i n c l u d e <s t r i n g >
#i n c l u d e <i o s t r e a m >
i n t main ( ) {
// d e f i n i n g a s e r i e s o f words t h a t can be combined to make a s e n t e n c e
s t d : : s t r i n g a = ” This ” ;
// ( remember you can i n c l u d e s p a c e s i n a s t r i n g ! )
std : : s t r i n g b = ” i s ” ;
s t d : : s t r i n g c = ”a ” ;
std : : s t r i n g d = ” sentence . ” ;
// u s i n g s i m p l e a d d i t i o n to combine a l l th e above s t r i n g s i n t o one
std : : s t r i n g e = a + b + c + d ;
s t d : : cou t << e << s t d : : e n d l ;

return 0;
}

6. Example - brute force password guesser! A nice reminder of why it is important to choose
a long password and include numbers (i.e. try with different lengths, and with one including
numbers. See how many steps each one takes on average and compare!)

”This sentence is just nonsense until you use some arithmetic.”

As with arrays and vectors, the string container class posseses a size() method which returns
the length of the string (i.e. how many individual characters it posseses). Again, just like the
previous examples, the ’[]’ operator can be used to access single characters belonging to the
string. For instance, simply typing:

stringName[5];

will access the 6th element of our string inventively named ‘stringName’ (remember our num-
bering starts at zero!). A more complete example may be seen below:

#i n c l u d e <s t r i n g >
#i n c l u d e <i o s t r e a m >
i n t main ( ) {
// d e f i n i n g a s t r i n g , s :
s t d : : s t r i n g s ( ”Can you code t h i s ? ” ) ;
s t d : : cou t << s << s t d : : e n d l ;
// o u t p u t t i n g i n d i v i d u a l c h a r a c t e r s from our s t r i n g , s :
s t d : : cou t << s [ 4 ] << s [ 1 1 ] << s [ 1 6 ] << s t d : : e n d l ;
return 0;
}

In fact, there are many ways you can play with strings, for instance inserting one string into
another using the insert() function:

// d e f i n i n g a s t r i n g
s t d : : s t r i n g s ( ”C++ i s hard . ” ) ;
21.5. Maps 156

s t d : : cou t << s << s t d : : e n d l ;


// i n s e r t i n g th e t e x t ” not ” at th e s t r i n g ' s 6 th elem en t .
// n ote how , j u s t l i k e v e c t o r s , s t r i n g s can r e s i z e when new e l e m e n t s a r e added
s . i n s e r t ( 5 , ” not ” ) ;
s t d : : cou t << s << s t d : : e n d l ;

Or swapping two strings using the swap() function:

#i n c l u d e <s t r i n g >
#i n c l u d e <i o s t r e a m >

i n t main ( ) {
// d e f i n i n g a s e t o f s t r i n g s . . .
s t d : : s t r i n g a = ”Romeo” ;
std : : s t r i n g b = ” l ov es ” ;
std : : s t r i n g c = ” J u l i e t ” ;
// . . . and o u t p u t t i n g ( n ote we a r e a g a i n u s i n g our s t r i n g a r i t h e m e t i c ! )
s t d : : cou t << a + b + c << s t d : : e n d l ;
// swapping our s t r i n g s a and b u s i n g th e swap ( ) method
a . swap ( c ) ;
// and o u t p u t t i n g a g a i n i n th e same o r d e r . . .
s t d : : cou t << a + b + c << s t d : : e n d l ;
return 0;
}

You can also convert a number to a string using the std::to string function:

s t d : : s t r i n g number = s t d : : t o s t r i n g ( 1 + 1 ) ;

Exercise 21.3.
Write a program which uses the ‘brute force’ method to guess a user-input password comprising
three letters. Include a function that records the number of ‘attempts’ your code makes in order
to break the password.

Extend your code to work with 6 letter passwords. Note the difference in the average number
of tries it takes for your code to break the password – this is (one reason) why longer passwords
are safer! 

21.5 Maps

Although the STL library contains a number of different containers, the last container class we
will discuss here is the map class template. maps can be thought of as similar to arrays, in that
they can store various mapped values in individual elements. Each mapped value is associated
to a given key value which identifies a single element. The key is used to retrieve the value must
be unique, but (unlike for arrays) can be of any type.
21.5. Maps 157

While a text-based description of maps make them sound rather complicated, their function and
use becomes much clearer with an example! For instance, it is possible to define a char to act
as a key for an int, allowing us to write things like:

s t d : : map<char , i n t > example ;


example [ ' a ' ] = 1 0 ;

...which assigns the (integer) value 10 to the element “a”, where the character a is the key and
10 the mapped value. In the declaration, the first term within the specialisation brackets, <>,
gives the type of the key to be used and the second term the type of the stored value itself. Note
the similarity to the definition of a simple array! In addition to chars, strings, floats and other
data types my be used to provide a key!

Below is a more complete – and thoroughly explained – example of how maps can be used:

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t r i n g >
// as u s u al , we need to i n c l u d e th e r e l e v a n t h ead er
#i n c l u d e <map>

i n t main ( ) {
// d e c l a r i n g th e map ; th e t y p e s g i v e n w i t h i n th e s p e c i a l i s a t i o n b r a c k e t s mea
// th e name o f th e map i s then g i v e n
s t d : : map<s t r i n g , i n t > example ;
// d e f i n i n g keys and mapped v a l u e s f o r two e l e m e n t s o f our map . Note how i t
example [ ”keyOne ” ] = 1 ;
example [ ”keyTwo” ] = 2 ;
// o u t p u t t i n g th e v a l u e s o f our two e l e m e n t s . Note t h a t th e d ou b le q u o t a t i o n
s t d : : cou t << example [ ”keyOne ” ] << ' \ t '
<< example [ ”keyTwo” ] << s t d : : e n d l ;
// d e c l a r i n g a n o t h e r map ; n ote t h a t both th e key and mapped v a l u e s can p o s s e
s t d : : map<s t r i n g , s t r i n g > anotherExample ;
// . . . and d e f i n i n g a s i n g l e elem en t
anotherExample [ ” t h e k e y ” ] = ” to g e t th e mapped v a l u e ” ;
std : : s t r i n g a ;
s t d : : cou t << ”Type i n th e key ” << s t d : : e n d l ;
s t d : : c i n >> a ;
// n ote t h a t th e key can be r ead i n from a c o n s o l e or an e x t e r n a l f i l e − eve
// be c a r e f u l when u s i n g s p a c e s and o t h e r b r eaks , though . . .
s t d : : cou t << anotherExample [ a ] ;
return 0;
}
21.6. Iterators 158

21.6 Iterators

So far, we have been introduced to several different C++ container classes. In this section, we
will introduce the concept of iterators which provide a handy – and uniformly applicable – way
in which to access the individual elements stored in a given container.

An iterator can be thought of as a pointer which can be ‘pointed at’ any given element belonging
to a given container. However, unlike a normal pointer, iterators also possess a series of over-
loaded operators and functions. This allows them to be applied to different types of container
using the same, uniform syntax!

In this section, we will introduce the most important of these operators and functions, before
showing them in action.

21.6.1 Iterator operators

• Dereferencing operator, * : Returns the element currently being ‘pointed to’.

• Increment operator, ++ : Tells the iterator to ‘point at’ the next element in the array.

• Decrement operator, -- : Tells the iterator to ‘point at’ the previous element in the
array. Note: this operator is not usable for all container types.

• Equality operator, == : Can be used to check if two iterators are pointing to the
same element of a container. Note that it does not compare the values stored in these
elements – this can instead be achieved by first dereferencing the iterator!

• Inequality operator, != : Can be used to check if two iterators are not pointing to the
same element of a container. As above, the comparison applies to the pointer and not the
values being pointed to.

• Assignment operator, = : Assigns the iterator to a new position within the container.
Note once again that this does not re-assign or otherwise change the value stored in the
element being pointed to. In order to change the stored value, the iterator must, as above,
first be dereferenced.

21.6.2 Iterator member functions

• begin() : Returns an iterator pointing to the first element in a given container – i.e.
returns the beginning of the container contents!

• end() : Returns an iterator corresponding to the element after the end of the elements
within the container. The reason that ‘end()’ does not simply return the last element
in the array but the one after it will become clear when we show some examples of how
iterators are typically used.

• cbegin() : Returns a constant, i.e. ‘read-only’ iterator pointing to the first element in
a given container.
21.6. Iterators 159

• cend() : Returns a constant iterator corresponding to the element after the end of the
elements within the container.

21.6.3 Declaring and using iterators

The generic declaration of an iterator follows the below form:

c o n a t i n e r t y p e : : i t e r a t o r name ;

So, as an example, if we want to create an iterator which works with std::vectors of integers,
and we want to name it ‘it’, we would simply type:

s t d : : v e c t o r <i n t > : : i t e r a t o r i t ;

In addition to ‘normal’ iterators, we can also create a constant or ‘read-only’ iterator, const iterator.
The declaration of these read-only iterators is the same as for a normal iterator, for example:

s t d : : v e c t o r <i n t > : : c o n s t i t e r a t o r i t ;

would provide a read-only iterator which we can apply to any std::vector-type containers
holding integer elements.

Now that we know how to declare an iterator, the next stop is to see one at work. The code
below shows a (very!) simple example of an iterator being used to cycle through the elements
of a vector:

#i n c l u d e <i o s t r e a m >
#i n c l u d e <v e c t o r >
i n t main ( ) {
// D e c l a r i n g an s t d : : v e c t o r , v , and s t o r i n g
// th e i n t e g e r v a l u e s 0−5
s t d : : v e c t o r <i n t > v = { 0 , 1 , 2 , 3 , 4 , 5 } ;
// d e c l a r i n g an i t e r a t o r , ' i t ' , s u i t a b l e f o r u s e
// with th e above−d e f i n e d s t d : : v e c t o r
s t d : : v e c t o r <i n t > : : i t e r a t o r i t ;
i t = v . begin ( ) ;
// c r e a t i n g a w h i l e l o o p which r u n s u n t i l we r e a c h
// th e end o f th e v e c t o r
w h i l e ( i t != v . end ( ) ) {
// O u tp u ttin g th e v a l u e a s s i g n e d to th e c u r r e n t
// elem en t b e i n g p o i n t e d to u s i n g th e
// d e r e f e r e n c e o p e r a t o r , ∗ .
s t d : : cou t << ∗ i t << ” ” << ' \ t ' ;
// i n c r e m e n t i n g ' i t ' to move on to th e n ext
// elem en t o f th e v e c t o r
21.6. Iterators 160

++i t ;
}
}

From this example it is easy to see why the ‘end()’ member function corresponds to one after
the end of the current container as described in section 21.6.2 – otherwise, a loop such as that
shown above would always ‘cut off’ the last element!

While the above code shows us how to use an iterator, this particular example does not do
a great job of showing why we should use them – i.e. what advantages they carry over other
methods. In short, there are two main advantages to iterators – efficiency and generality. For
example, passing an iterator to a function is much more efficient than passing an entire vector!

One of the real beauty of iterators, however, is their generality – i.e. the same basic code structure
will work for any container, irrespective of the functions it does or doesn’t possess, the way in
which it is populated or the manner in which it stores data.

For example, let’s say we want to write a code that sums all the elements of a given container.
Writing such a code that works for one type of container – say std::vectors – should, by now, be
quite simple for us:

d ou b le vectorSum ( s t d : : v e c t o r <double> v ) {
// d e c l a r i n g a v a r i a b l e to s t o r e our sum and
// i n i t i a l i s i n g i t with a v a l u e 0
d ou b le sum = 0 ;
// l o o p i n g o v e r a l l e l e m e n t s o f th e v e c t o r a r r a y . . .
f o r ( i n t i = 0 ; i < v . s i z e ( ) ; i ++) {
// . . . and , f o r each element , ad d in g i t s v a l u e
// to th e sum
sum += v [ i ] ;
}
// r e t u r n i n g th e sum o f th e v e c t o r to th e u s e r .
r e t u r n sum ;
}

While this implementation will work just fine for an std::vector, what if we wanted to do the
same for an std::array or an std::list, or indeed any other kind of container?

By taking advantage of the use of iterators, we can create a sum function that will work for
almost any container. One way of implementing such a function would be as follows:

// c r e a t e s a t e m p l a t e typ e c a l l e d ” C o n t a i n e r ” which can ,


//when th e code i s run , be used to r e p r e s e n t any c o n t a i n e r ,
// e . g . s t d : : v e c t o r s , s t d : : a r r a y s . . .
t e m p l a t e <typename C on tain er>
// A l l we t e l l th e code at t h i s p o i n t i s t h a t our f u n c t i o n w i l l
// t a k e a s i n g l e argument , w ith ou t s p e c i f y i n g th e typ e o f th e
// v a r i a b l e to be p a s s e d !
21.6. Iterators 161

d ou b le generalSum ( C o n t a i n e r & c o n t a i n e r ) {
//As b e f o r e , d e c l a r i n g a v a r i a b l e to s t o r e our sum and
// i n i t i a l i s i n g i t with a v a l u e 0
d ou b le sum ;
// d e f i n i n g an i t e r a t o r to p o i n t at th e f i r s t elem en t o f our
// i n s t a n c e , ” c o n t a i n e r ” o f our unknown c l a s s , ” C o n t a i n e r ” .
typename C o n t a i n e r : : i t e r a t o r i t = c o n t a i n e r . b e g i n ( ) ;
// Using our i t e r a t o r to l o o p th r ou gh a l l e l e m e n t s o f our
// unknown c o n t a i n e r
w h i l e ( i t != c o n t a i n e r . end ( ) ) {
// summing each i n d i v i d u a l elem en t .
// Note th e u s e o f th e d e r e f e r e n c e o p e r a t o r , ∗ , to e n s u r e
//we a r e summing v a l u e s o f th e ∗∗ s t o r e d e l e m e n t s t h e m s e l v e s ∗∗
sum += ∗ i t ;
//No d e r e f e r e n c e o p e r a t o r , ∗ , i . e . h e r e i t i s th e
// ∗∗ p o s i t i o n ∗∗ o f th e i t e r a t o r b e i n g in cr em en ted ,
// ∗∗NOT∗∗ th e v a l u e o f i t s c o n t e n t s !
i t ++;
}
// r e t u r n i n g th e sum o f th e unknown c o n t a i n e r to th e u s e r .
r e t u r n sum ;
}

The second implementation of our function requires only an extra three lines of code, yet can
be used for a wide variety of dissimilar containers – clearly, this is much simpler (and neater!)
than recreating the same code for all different container types.

Exercise 21.4.
Without running the below code, comment each line and predict what the relevant outputs will
be at each stage. Then, run the code to see if you were right!

#i n c l u d e <i o s t r e a m >
#i n c l u d e <v e c t o r >
i n t main ( ) {
s t d : : v e c t o r <i n t > v = { 0 , 1 , 2 , 3 , 4 , 5 } ;
s t d : : v e c t o r <i n t > : : i t e r a t o r i t ;
i t = v . begin ( ) ;
w h i l e ( i t != v . end ( ) ) {
s t d : : cou t << ∗ i t << ” ” << ' \ t ' ;
++i t ;
}

s t d : : cou t << s t d : : e n d l ;
i t = v . begin ( ) ;
w h i l e ( i t != v . end ( ) ) {
i t ++;
s t d : : cou t << ∗ i t << ” ” << ' \ t ' ;
++i t ;
}
21.7. Range-Based for loops 162

s t d : : cou t << s t d : : e n d l ;

i t = v . begin ( ) ;
w h i l e ( i t != v . end ( ) ) {
( ∗ i t )++;
s t d : : cou t << ∗ i t << ” ” << ' \ t ' ;
++i t ;
}
s t d : : cou t << s t d : : e n d l ;
}

Using iterators, add to the above a section of code which outputs the elements of the same vector
array in reverse order.

Re-write both the vector and general sum functions defined in section 21.6.3 to give the product
of all the numbers in a given container. Call both functions for i) an std::vector of your
choosing and ii) a similar std::array.

21.7 Range-Based for loops

In this section, we introduce range-based for loops, which provide a convenient alternative to
‘normal’ for loops, and a more elegant syntax than iterators when working with container-type
objects.

Say we have a simple std::vector, v, which stores some integer elements:

s t d : : v e c t o r <i n t > v = { 0 , 1 , 2 , 3 , 4 , 5 } ;

If we wanted to output all the elements of v to the console, we would normally write something
along the lines of:

f o r ( i n t i = 0 ; i < v . s i z e ( ) ; i ++) {
s t d : : cou t << v [ i ] << s t d : : e n d l ;
}

However, this notation requires you to call the v[i] operator repeatedly, which is costly, and
thus should be avoided. For improved efficiency, we can instead use iterators, as we have seen
in the previous chapter:

f o r ( v e c t o r <i n t > : : i t e r a t o r i t=v . b e g i n ( ) ; i t !=v . end ( ) ; i t ++)


{
s t d : : cou t << ∗ i t << s t d : : e n d l ;
21.7. Range-Based for loops 163

However, this is – to put it bluntly – rather ugly, which is why C++11 introduced the above-
mentioned range-based for loops. In C++11, we can perform the same operation using a dif-
ferent syntax, which may in fact be more familiar to those with expertise in other programming
languages:

for ( int i : v) {
s t d : : cou t << i << s t d : : e n d l ;
}

This is equivalent to the following:

v e c t o r <i n t > : : i t e r a t o r b e g i n = v . b e g i n ( ) ;
v e c t o r <i n t > : : i t e r a t o r end = end ( ) ;
f o r ( ; i t != end ; i t ++)
{
v e c t o r <i n t > i =∗ i t ;
s t d : : cou t << i << s t d : : e n d l ;
}

As we can see, the new syntax is much more concise than the usual, non-range-based form.
However, for those already familiar with using ‘normal’ C++ for loops, there are certain pitfalls
that we must avoid, and certain new tricks we must learn.

In the argument of the for loop, (int i) in essence tells the compiler to assign to the variable
‘i ’ the values corresponding to each of the elements of v in turn – i.e. in the above example,
i ‘becomes’ each of the values stored in v, is output, and then ‘becomes’ the next one and so
on. This is why in the methods section of the loop – ‘{}’ – instead of writing std::cout <<
v[i] << std::endl;, we write std::cout << i << std::endl;. In fact, if we accidentally
output v[i] instead of i, we can end up with some very confusing results (as demonstrated in
the exercises at the end of this section!).

It is additionally important to note that if we want to use range-based for loops not just to
‘look at’ data but to actually alter the values stored, we need to make our loop variable (i) a
reference. This is done simply by adding the usual ‘&’ symbol to our integer declaration. So
if, for example, we want to increment each of the values stored in our vector, we would write:

f o r ( i n t& i : v ) {
i ++;
}

Of course, range-based for loops don’t only work with vectors – we can also use them with many
other container types. For instance std::strings:
21.7. Range-Based for loops 164

s t d : : s t r i n g s = ” example ” ;
f o r ( ch ar i : s ) {
s t d : : cou t << ” [ ” << i << ” ] ” ;
}

where the above example would output:

[e][x][a][m][p][l][e]

There are many, many other ways to use range-based for loops for all kinds of different containers,
and the best way to learn more about these possibilities is to spend some time playing around
with them!

Exercise 21.5.

Without running the below code, try and predict its output at each point, and explain why you
would expect this output. Comment the code accordingly. Then, run the code to see if you were
correct!

#i n c l u d e <v e c t o r >
#i n c l u d e <i o s t r e a m >
i n t main ( ) {
s t d : : v e c t o r <i n t > v = { 0 , 1 , 2 , 3 , 4 , 5 } ;

for ( int i : v) {
s t d : : cou t << i << ' \ t ' ;
}
s t d : : cou t << s t d : : e n d l ;

for ( int i : v) {
i ++;
s t d : : cou t << i << ' \ t ' ;
}
s t d : : cou t << s t d : : e n d l ;

for ( int i : v) {
i ++;
}

for ( int i : v) {
s t d : : cou t << i << ' \ t ' ;
}
s t d : : cou t << s t d : : e n d l ;

for ( int i : v) {
s t d : : cou t << i << ' \ t ' ;
}
s t d : : cou t << s t d : : e n d l ;
21.7. Range-Based for loops 165

for ( int i : v) {
s t d : : cou t << v [ i ] << ' \ t ' ;
}
s t d : : cou t << s t d : : e n d l ;

return 0;
}


Chapter 22
Object Oriented Programming II: Creating New Classes

Object-oriented programming (OOP) is a programming style where objects - data structures


that consist of both data fields and methods - are used to design computer programs. In C++
this is done using classes.

22.1 A simple OOP problem

A class can be used to declare structures which require both data storage and functions acting
on that data. In the following example, a rectangular shape is defined. The shape of a rectangle
is defined by its width and height; this is the data contained in the class. Further, there are
many properties of a rectangle that can be evaluated from the data, for example the area or
circumference of the rectangle; these class-specific functions can be implemented as part of the
class.

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;

c l a s s Rectangle {
d ou b le width , h e i g h t ;
public :
R e c t a n g l e ( d ou b le w, d ou b le h ) { s e t V a l u e s (w, h ) ; }
v o i d s e t V a l u e s ( double , d ou b le ) ;
i n t getAr ea ( ) { r e t u r n ( width ∗ h e i g h t ) ; }
};

v o i d R e c t a n g l e : : s e t V a l u e s ( d ou b le w, d ou b le h ) {
i f (w>0 && h>0) {
width = w ;

– 166 –
22.1. A simple OOP problem 167

height = h ;
} else {
c e r r << ” E r r o r i n R e c t a n g l e : : s e t V a l u e s : ” <<
” h e i g h t and width need to be p o s i t i v e ” << e n d l ;
e x i t ( − 1);
}
}

i n t main ( ) {
R e c t a n g l e r ectA ( 3 , 4 ) , r ectB ( 5 , 6 ) ;
cou t << ” r ectA a r e a : ” << r ectA . getAr ea ( ) << e n d l ;
cou t << ” r ectB a r e a : ” << r ectB . getAr ea ( ) << e n d l ;
return 0;
}

• The Class-Definitions appear before the main() program, which is especially short.
Class definitions can be placed in separate files and this is normal the case for large projects.
This is discussed further in section 24.

• A class is declared outside by the keyword class followed by the class name, the body in
{}-parentheses, and a semicolon. It can be declared locally (i.e. inside a function), but is
usually declared globally. The body contains the declaration of the member variables and
member functions.

• A class like Rectangle is a data structure that can contain both member variables and
member functions. In this case, the member variables are the height and width of the
rectangle. The member functions are used to manipulate, read and write the member
variables. In this case, setValues is used to set the dimensions of the rectangle (it also
checks if the values make sense), getArea is used to evaluate its area.

• Members (variables and functions) are declared inside the class body. However, they can
be defined both inside and outside the body of the class. If defined outside, the scope
operator (class_name::member_name) is used to identify the function (see setValues).

• Encapsulation by access specifiers: By default members of a class are private, i.e.,


they cannot be called from outside the class (try using the variable rectA.width in the
function main). You can make members public, i.e. accessible from outside the class by
adding the line public:; all following members will then be accessible. Public members
of a class are called using the dot operator (object_name.member_name).

• A constructor and a destructor can be defined for each class, which specifies what to
do when an object of the class is created or destroyed. This is often used to set default
values; the constructor is declared similar to a member function, with the same name as
the class, but with no output type. A preceding tilde is used for the destructor. One can
create constructors that take input variables, as in this example. Then an object of a class
can be initialized with the () operator: Rectangle rectA(3,4);
22.2. Inheritance 168

22.2 Inheritance

Classes can also be inherited, which means that one can create a ‘child’ of a class which has all
the properties of the ‘parent’ class, plus a few extra properties. For example, we can add colour
to the definition of our rectangle:

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t r i n g >
u s i n g namespace s t d ;

c l a s s R e c t a n g l e { /∗ . . . ∗/ } ;

c l a s s ColouredRectangle : p u b lic Rectangle {


s t r i n g Colour ;
public :
C o l o u r e d R e c t a n g l e ( d ou b le w, d ou b le h ) : R e c t a n g l e (w, h ) {
Colour = ” w h ite ” ;
}
v o i d s e t C o l o u r ( s t r i n g c ) { Colour=c ; } ;
s t r i n g g e t C o l o u r ( ) { r e t u r n Colour ; } ;
};

i n t main ( ) {
C o l o u r e d R e c t a n g l e r ectA ( 3 , 4 ) , r ectB ( 5 , 6 ) ;
r ectB . s e t C o l o u r ( ” b l a c k ” ) ;
cou t << ” r ectB c o l o u r : ” << r ectB . g e t C o l o u r ( ) << e n d l ;
return 0;
}

• To inherit from an existing class, we use a colon : in the declaration of the derived class:

c l a s s d e r i v e d c l a s s n a m e : p u b l i c b a s e c l a s s n a m e { /∗ . . . ∗/ } ;

The class has now all the member variables and functions of the parent class. Additional
members are specified in the class body.

• We also use the colon if we want to inherit from the constructors or destructors of the
parent class. In this example, the constructor of ColouredRectangle calls the constructor
of Rectangle before initialising the Colour string.

22.3 Polymorphism

Inheritance is a relatively easy concept to understand. Polymorphism on the other hand is much
harder. Polymorphism is about an object’s ability to provide context when methods or operators
are called on the object.
22.3. Polymorphism 169

Definition of polymorphism: In object-oriented programming, polymorphism (from the


Greek meaning “having multiple forms”) is the characteristic of being able to assign a
different meaning to a particular symbol or “operator” in different contexts.

The simple example is two classes that inherit from a common parent and implement the same
virtual method.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <cmath>
#i n c l u d e <v e c t o r >
u s i n g namespace s t d ;

c l a s s Shape {
public :
v i r t u a l d ou b le getAr ea ( ) { } ;
};

c l a s s C i r c l e : p u b l i c Shape {
private :
d ou b le r a d i u s ;

public :
C i r c l e ( d ou b le r ) : r a d i u s ( r ) { } ;

d ou b le getAr ea ( ) {
r e t u r n M PI∗ r a d i u s ∗ r a d i u s ;
}
};

c l a s s R e c t a n g l e : p u b l i c Shape {
private :
d ou b le width , h e i g h t ;

public :
R e c t a n g l e ( d ou b le w, d ou b le h ) : width (w) , h e i g h t ( h ) { } ;

d ou b le getAr ea ( ) {
r e t u r n width ∗ h e i g h t ;
}
};

i n t main ( )
{
Circle c (10);
Rectangle r ( 1 0 , 5 ) ;

v e c t o r <Shape∗> L i s t O f S h a p e s ( 2 ) ;
L i s t O f S h a p e s [ 0 ] = &r ;
22.3. Polymorphism 170

L i s t O f S h a p e s [ 1 ] = &c ;

f o r ( i n t i =0; i <L i s t O f S h a p e s . s i z e ( ) ; i ++)


cou t << ” Area : ” << L i s t O f S h a p e s [ i ]−>getAr ea ( ) << e n d l ;

return 0;
}

In this example, we create two classes, one for rectangular and one for circular shapes. We
want to be able to calculate the area for both shapes. Therefore, we create a base class Shape
which does nothing but declare a function getArea(). Then we create the classes Circle and
Rectangle by inheriting from Shape. Thus they inherit the getArea() function.

One of the key features of derived classes is that a pointer to a derived class is type-compatible
with a pointer to its base class. This can be used to create pointers which can point to any
kind of shape and which allow access to the member variables and functions inherited from the
parent class. In order for a parent class pointer to use a inherited function definition, we have
to declare the parent member function as virtual.

Exercise 22.1.
For Experts: Think about what can be improved in the following code – for this you first will
have to understand ... Further reading/learning required. 

#i n c l u d e < s t d l i b . h>
#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m>
u s i n g namespace s t d ;
c l a s s CSample
{
public :
CSample ( ) ; // c o n s t r u c t o r
∼CSample ( ) ; // d e s t r u c t o r

i n t I n p u t ( c o n s t ch ar ∗ fname ) ;
d ou b le GetSum ( ) ;
d ou b le GetMax ( ) ;
int Size ;
private :
i n t Nmax ;
d ou b le ∗a ;
b o o l mem alloc ;
};

i n t CSample : : I n p u t ( c o n s t ch ar ∗ fname )
{
i f s t r e a m i n ( fname ) ;
i n >> Nmax ;
S i z e = Nmax ;
22.3. Polymorphism 171

//memory a l l o c a t i o n
a = new d ou b le [ Nmax ] ;

mem alloc=t r u e ;

f o r ( i n t i =0; i <Nmax ; i ++)


i n >> a [ i ] ;
in . clos e ( ) ;
return 1;
}

d ou b le CSample : : GetSum ( )
{
d ou b le sum ;
sum = 0 ;
f o r ( i n t i =0; i <Nmax ; i ++)
sum = sum + a [ i ] ;
r e t u r n sum ;
}

d ou b le CSample : : GetMax ( )
{
i f ( a==0) r e t u r n 0 ;
d ou b le m;
m = a[0];
f o r ( i n t i =1; i <Nmax ; i ++)
i f ( a [ i ] > m) m = a [ i ] ;
r e t u r n m;
}

CSample : : CSample ( )
{
mem alloc = f a l s e ;
a = 0;
Nmax = 0 ;
}

CSample : : ∼CSample ( )
{
// f r e e memory
i f ( mem alloc ) d e l e t e [ ] a ;
}

//= MAIN PROGRAM ==============================


// Uses th e c l a s s CSample
// to r ead i n data , p r i n t th e s i z e o f th e data−f i e l d ,
// compute th e sum of , and th e maximum .
i n t main ( )
{
22.4. C++ standard classes 172

CSample Test ;
Test . I n p u t ( ” data . dat ” ) ;
cou t << ” S i z e = ” << Test . S i z e << ”\n” ;
cou t << ”Sum = ” << Test . GetSum ( ) << ” \n” ;
cou t << ”Max = ” << Test . GetMax ( ) << ” \n” ;
cou t << e n d l ;
system ( ”PAUSE” ) ;
return 0;
}

Exercise 22.2.
Below you see a simple class definition to store name of contacts. Create an inherited class that
can also store the occupation of a person. 

c l a s s Contact {
//member v a r i a b l e s
string first name ;
s t r i n g last name ;
public :
//member f u n c t i o n s
v o i d s et n am e ( s t r i n g , s t r i n g ) ;
s t r i n g get name ( ) ;
};

s t r i n g Contact : : get name ( ) {


s t r i n g name ;
name += f i r s t n a m e ;
name += ” ” ;
name += l a s t n a m e ;
r e t u r n name ;
}

v o i d Contact : : s et n am e ( s t r i n g f i r s t , s t r i n g l a s t ) {
first name = f i r s t ;
last name = l a s t ;
}

22.4 C++ standard classes

All the C++ libraries contain objects and most of these are templated. We have been using
these for some time without exactly understanding the syntax.

The first example we meet was numeric_limits<int>::min(). So here clearly it is templated


with a type, in this example int, and we call the static member function min(). Note, :: calls
static member function, whose purpose we have not covered in the discussion above and will not
in this short course.
22.5. STL vector 173

A second example we have seen is

#i n c l u d e <s s tr eam>
#i n c l u d e <f s t r e a m >
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;

i n t main ( )
{
stringstream file name ;
s t r i n g s t r e a m problem name ( ” my problem ” ) ;
ofstream s c r i p t f i l e ;
f i l e n a m e << problem name . s t r ( ) <<” . d i s p ” ;
s c r i p t f i l e . open ( ( f i l e n a m e . s t r ( ) ) . c s t r ( ) ) ;
// . .
s c r i p t f i l e . close ( );
return 0;
}

In this example str() is a member function of stringstream that return a string. Then
c_str() is a member function of string that returns a const char*, i.e. a constant character
array.

Full listing of all standard C++ libraries can be found at http://www.cplusplus.com. Note,
many of the higher classes inherit from the more basic ones. For example both isstream and
ifstream inherit from istream, this explains why both type of streams have similar methods
defined and can be interchanged so easily.

22.5 STL vector

A very useful templated class in C++ is the STL vector. This is a container that can take any
type of data i.e. int, double or even a user-defined class. Below we briefly introduce this very
useful standard template library (STL) class.

#i n c l u d e <i o s t r e a m>
#i n c l u d e <v e c t o r >
u s i n g namespace s t d ;

i n t main ( ) {
int n = 0;
co ut << ” Enter how many s q u a r e numbers t o compute : ” << e n d l ;
c i n >> n ;

// Decla y an i n t e g e r a r r a y o f l e n g t h n
v e c t o r <i n t > my vec ( n ) ;

// A s s i g n t h e v a l u e i s q u a r e d t o ea ch element
f o r ( i n t i =0; i <n ; i ++)
22.5. STL vector 174

my vec [ i ]= i ∗ i ;

// Write out ea ch element ' s v a l u e t o t h e s c r e e n


f o r ( i n t i =0; i <n ; i ++)
co ut << my vec [ i ] << e n d l ;

return 0;
}

A major advantage of vector is that it supports dynamic size control, i.e. by calling
my_vec.resize(20) you can change the size of my_vec after creation; this is useful when the
size of a field is not known at compile-time.

In the above examples my_vec is a class which has both data (in this case integers) and functions
(e.g. resize or sum).

valarray is a very similar container class vector but can only store numerical data. This is
implemented in the header <valarray>.

Access to data stored, in both valarray and vector classes can be slower than pointer based
method described in §16.3.8, but the use of iterators (not covered by this course) can massively
improve access time for these classes.
Chapter 23
I/O (Input and Output)

The I/O in C++ is completely renewed as compard to C. This was mostly necessary because of
the complex format in C with non-constant number of variables.

The two most important objects are I/O-channels like istream and ostream. Both are declared
in the header iostream. In the previous chapters, the standard I/O channels ‘cin’ and ‘cout’
with the operators ‘<<’ or ‘>>’ were already used frequently. In the following alternatives and
extensions are explained.

In which sequence is I/O processed?

#i n c l u d e <i o s t r e a m >
// The programmer t y p e s t h i s
cou t << ” S a l a r y : ” << Person . mSalary ;

// . . . but th e c o m p i l e r r e a d s t h i s :
( cou t << ” S a l a r y : ” ) << Person . mSalary ;

In order to write the string Salary: to the screen, the operator << is called from the ostream
cout and returns another ostream with which the next << is called. This time, Person.mSalary
is the second argument. Analogously after an input with cin, another istream is returned so
that one can input again.

23.1 Elementary functions of iostreams

Instead of the form as used up to now, I/O can also be performed in the form of functions – for
compatibility. However, the function-form has much wider range of applications, see Tab. 23.1.

– 175 –
23.2. Formatting 176

ch ar c1= ' x ' ;


cou t << c1 << ' \n ' ; // Syntax used up to now
cou t . put ( c1 ) ; // E q u i v a l e n t form u s i n g f u n c t i o n s
cou t . put ( ' \n ' ) ;

ostream::put (char c); writes character c to ostream


Example: cout.put( c1 );
char c=’x’; For comparison ...
cout << c; also writes the char ’c’
istream::get (char c); reads character c from istream
Example: cin.get( c1 );
char c; For comparison ...
cin >> c; Reads character c, ignores SPACE, TAB, EOL

Table 23.1: Prototypes of some element-functions for I/O alternative to the use of cout und
cin.
There are many related element-functions like this that allow a much more controlled and well-
behaved input and output of data. (Further reading if needed).

23.2 Formatting

Typically it is necessary to change the format of the output, e.g., in order to obtain a better
readable table, or in order to prepare the output for the transfer to another software, or to write
the full precision on the screen, or ... see Tab. 23.2 for a summary.

Manipulator Description
int width=12;
cout << setw(width); sets the minimal number of digits for the following
output only.
int prec=5;
cout << setprecision(prec); Changes the number of digits behind the comma,
or the max. number of digits
char c='*';
cout << setfill(c); Defines a filling-symbol as, e.g., *.
boolapha Boolean values are written as textual version, i.e.,
true not 1 for a true value and false not 0 for a false
value.
noboolalpha Default. Has the opposite effect of boolaphla.

Table 23.2: Examples of formatting functions for the output

In order to call these functions, first use: #include<iomanip>. Note that there are modifications
that only act on the next output, and others that remain active permanently.

#i n c l u d e <iomanip>
23.3. Files 177

d ou b le x = 1 2 3 4 . 5 ;
cou t << x << ' \n ' ; // l e a d s to : 1 2 3 4 . 5
cou t << s e t f i l l ( ' ∗ ' ) << setw ( 1 0 ) << s e t p r e c i s i o n ( 5 ) ;
cou t << x << ' \n ' ; // l e a d s to : ∗ ∗ ∗ ∗ 1 2 3 4 . 5
cou t << x << ' \n ' ; // back to p r e v i o u s s e t t i n g : 1 2 3 4 . 5

Furthermore there exist switches (flags) for the formatted output that need no parameters, as
summarised in Tab.23.3:

Flag Group function


left adjustfield left-adjust
right adjustfield right-adjust
internal adjustfield +/- left
dec basefield decimal numbers
hex basefield hexadecimal numbers
oct basefield octal numbers
showbase shows the dec-basis of hex- and oct-numbers
showpos prints ’+’ before number if positive
uppercase E, X, A-F instead of: e, x, a-f
fixed floatfield Fixed-point notation
scientific floatfield scientific notation

Table 23.3: Flags for the formatted output of data

In order to activate flags one can use alternatively

cou t . s e t f ( i o s : : ' f l a g ' , i o s : : ' group ' )


cou t << s e t i o s f l a g s ( i o s : : ' f l a g ' , i o s : : ' group ' )

where the possibilities for 'flag' and 'group' are summarized above in Tab. 23.3, where the
second parameter is not always needed. In order to change the setting, or set it to default, for
a single flag or for groups of flags, one can use:

cou t . u n s e t f ( i o s : : ' f l a g ' )


cou t << r e s e t i o s f l a g s ( i o s : : ' flag ' )

cou t . u n s e t f ( i o s : : ' group ' )


cou t << r e s e t i o s f l a g s ( i o s : : ' group ' )

23.3 Files

For reading and writing on files, one can use the channels fstream and ofstream. These are
derived from the std-streams istream and ostream.
23.3. Files 178

# i n c l u d e <f s t r e a m >
...
d ou b le z = 1 . 2 3 4 ;
int m=5;
o f s t r e a m o u t s ( ” f i l e n a m e ” , i o s : : out ) ; // open th e f i l e with name
// ' f i l e n a m e ' f o r w r i t i n g
// i o s : : out can be s k i p p e d
o u t s << x << ' \n ' ; // th e u s e o f th e s e l f −d e f i n e d output −stream
o u t s << j << ' \n ' ; // ' o u t s ' i s a n a l o g o u s to th e u s e o f ' cou t '
outs . c l o s e ( ) ; // c l o s e th e out−f s t r e a m ' o u t s '

ifstream ins ( ” filename ” , ios : : in ) ; // open th e f i l e with name


// ' f i l e n a m e ' to r ead from
// i o s : : i n can be s k i p p e d
i n s >> z ; // th e u s e o f th e s e l f −d e f i n e d in p u t−stream
i n s >> m; // ' i n s ' i s a n a l o g o u s to th e u s e o f ' c i n '
ins . close ( ) ; // c l o s e th e in −f s t r e a m ' i n s '

At least now, when working with files, we need information whether we have reached the end
of the file (EOF) or if the opening of the file was successful. For this, the so-called status-
informations can be used, which return – dependent on the status of a file – either true or
false:

i n s . good ( ) // tr u e , i f no e r r o r o c c u r e d i n stream ' i n s '


ins . eof () // tr u e , i f th e end o f f i l e / stream i s r e a c h e d
i n s . bad ( ) // tr u e , i f an hardware e r r o r o c c u r e d
ins . f a i l () // tr u e , i f a l o g i c a l e r r o r or a
// hardware e r r o r o c c u r e d
i n s . c l e a r ( ) // s e t i n s . good ( ) to t r u e
ins . clear ( ios : : f a i l b i t | ins . rdstate () )
// s e t f a i l ( ) manually to t r u e

Example: How to read from a file to its end?

The following examples show which problems can occur doing this.

int n;

while ( ! cin . eof ()){


c i n >> n ;
// . . . . t h i s r e a d s too f a r
}

w h i l e ( ( c i n >> n ) . good ){
// . . . t h i s r e a d s not f a r enough
}

w h i l e ( c i n >> n ){
23.3. Files 179

// . . . t h i s i s th e way i t works
}
Chapter 24
Organisation implementation and header-files

Big programs and program-packages should not be kept in a single file since this can lead to
long compilation times and non-clear dealing with and navigation in the file. Furthermore it
causes big trouble if more persons work on (a single file) at the same time.

Therefore, one typically splits programs into several files (projects), that can be compiled in-
dependently from each other. There are compilable (Implementation-) C++-files with the ex-
tension .cc or .cpp. Files that only contain declarations are called header-files and are used
to make functions and data from one file known to another. These have the extension .h. In
general (except for main.cc) an implementation-file comes together with a header-file.

header-files should contain:

1. so-called include-guards, that hinder the multiple inclusion of header-files (required by the
standard)

#i f n d e f HEADER H
#d e f i n e HEADER H
// d e c l a r a t i o n s
#e n d i f

2. Declarations of functions that are used amongst several modules. For declarations of local
functions, another header-file can be used.

3. Definition of inline functions

4. Declaration of classes and their elementfunctionen

5. extern declarations of global variables, and declaration of static varbiables

6. Declaration and definition of template-functions and -classes

– 180 –
181

implementation-files should contain:

1. Implementation of elementfunctions of not-template-classes

2. Implementation of regular functions

3. Declaration von file-scope, class-scope and global static variables

Exercise 24.1.
For example, the Sample class in exercise 9.1 is long, and we want our code to be more struc-
tured. Thus, we copy the class declaration (lines 5-19 of the code in exercise 9.1) into a
header file Sample.h, and copy the class member declaration (line 21-69 of the code in ex-
ercise 9.1) into a implementation file Sample.cpp, where we have to add some include directives
at the beginning of the file. We tell the compiler where to find the class declaration by adding
#include "Sample.h" to teh implementation files. This gives our code structure. The whole
programm can now be compiled with the command g++ main.cpp Sample.cpp. 

Sample.h:

#i f n d e f Sample H
#d e f i n e Sample H
c l a s s CSample
{
public :
CSample ( ) ; // c o n s t r u c t o r
∼CSample ( ) ; // d e s t r u c t o r

i n t I n p u t ( c o n s t ch ar ∗ fname ) ;
d ou b le GetSum ( ) ;
d ou b le GetMax ( ) ;
int Size ;
private :
i n t Nmax ;
d ou b le ∗a ;
b o o l mem alloc ;
};
#e n d i f

Sample.cpp

#i n c l u d e < s t d l i b . h>
#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m>
#i n c l u d e ” Sample . h”
u s i n g namespace s t d ;

// . . . ( copy l i n e 21−69 o f th e code i n e x e r c i s e 9 . 1 h e r e )


24.1. Compiling and linking 182

main.cpp

#i n c l u d e < s t d l i b . h>
#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m>
#i n c l u d e ” Sample . h”
u s i n g namespace s t d ;

// Uses th e c l a s s CSample
// to r ead i n data , p r i n t th e s i z e o f th e data−f i e l d ,
// compute th e sum of , and th e maximum .
i n t main ( )
{
CSample Test ;
Test . I n p u t ( ” data . dat ” ) ;
cou t << ” S i z e = ” << Test . S i z e << ”\n” ;
cou t << ”Sum = ” << Test . GetSum ( ) << ” \n” ;
cou t << ”Max = ” << Test . GetMax ( ) << ” \n” ;
cou t << e n d l ;
system ( ”PAUSE” ) ;
return 0;
}

24.1 Compiling and linking

Whenever we use the g++ compiler we actually do two steps: compiling and linking. Let us con-
sider the above example. One can compile the code using the -c flag e.g. g++ -c main.cpp and
g++ -c Sample.cpp. This will create object files called main.o and Sample.o. These separate
objects are then linked into an executable by calling g++ main.o Sample.o -o main.exe.
Chapter 25
Functional Programming

Functional programming is very useful - being able to pass a function to another function is
often highly useful while sorting items, for instance. Functional programming allows us to sort
objects using more complex criteria than simply ‘bigger than’ or ‘smaller than’.

This concept of using functions as variables forms the basis of functional programming. In C++
there are multiple ways to do this.

25.1 Function Pointers

Consider a (very simple) function which simply acts to return an integer variable:

i n t giveMeFive ( ) {
return 5;
}

In the above, ‘giveMeFive’ is the name of the function, and ‘giveMeFive’ can be considered as
a constant pointer to the code containing the function’s methods. In other words, the pointer
‘giveMeFive’ points to the memory address where the code corresponding to the
function starts.

So, we can consider our call to the function ‘giveMeFive’ as an instruction to our compiler to
‘jump’ to the memory address corresponding to the function!

To illustrate the equivalence between functions and pointers, try running the following example:

// f o r cin , cou t e t c .

– 183 –
25.1. Function Pointers 184

#i n c l u d e <i o s t r e a m >
// d e c l a r i n g and d e f i n i n g th e f u n c t i o n
i n t giveMeFive ( ) {
return 5;
}

i n t main ( ) {
// C a l l i n g th e f u n c t i o n and o u t p u t t i n g th e r e t u r n v a l u e
s t d : : cou t << giveMeFive ( ) << s t d : : e n d l ;
//A common c o d i n g e r r o r !
s t d : : cou t << giveMeFive << s t d : : e n d l ;
}

Depending on your compiler, for the 2nd cout, your code will likely either return the integer ‘1’,
or a hexadecimal value. This value printed out is the address at which your function code
is stored. This is also a very good illustration of how a very simple error (missing the ‘()’ from
your function) could potentially cause some very serious bugs in your code!

So, if the ‘normal’ declaration above gives us a constant pointer to a function, can we also declare
a non-constant pointer to a function? The answer, of course, is yes, and these function
pointers can prove highly useful.

Standard pointers, as we have already learned, can be declared fairly straightforwardly. For
instance if we want to declare a pointer to an integer, we simply write:

int ∗ intPointer ;

Or, to declare a pointer to a double, we write:

d ou b le ∗ d b l P o i n t e r ;

However, since functions are more complicated than simple variables, however, the declaration
of a function pointer is also more complicated. Specifically, if we want to declare a pointer to
be used with functions, we need to specify both the return type and argument type(s) of
the kind of functions we want to be able to ‘point to’.

For example, if we want to point to functions such as that declared above, we need to specify a
pointer to a function which takes no arguments and returns an integer. This can be done as
follows:

i n t (∗ functionPointer ) ( ) ;

Similarly, if we wanted to declare a pointer to a function with no return type but which takes
an integer argument we would instead write:
25.1. Function Pointers 185

void (∗ fu n ction Poin ter ) ( i n t ) ;

As you have probably already worked out from the above example, function pointers are de-
clared as the return type of the functions they point to, while the contents of the 2nd set
of round brackets pertains to the arguments of the functions to be ‘pointed to’ (Note: if the
pointed-to functions take no arguments, the brackets are still included, but left empty, as above).

The name of the function pointer (here, we have simply named our pointers ‘functionPointer’)
must be contained in brackets to ensure that the function pointer is read correctly, and not
interpreted as a forward declaration of a function of the same name.

Below is an example of a function pointer in action:

// f o r cin , cou t e t c .
#i n c l u d e <i o s t r e a m >
// d e c l a r i n g and d e f i n i n g a f u n c t i o n . . .
i n t giveMeFive ( ) {
return 5;
}
// . . . and a 2nd , s i m i l a r f u n c t i o n
// with th e same argument and r e t u r n t y p e s
i n t giveMeTen ( ) {
return 10;
}
i n t main ( ) {
// d e c l a r i n g a p o i n t e r , and s e t t i n g i t to ' p o i n t at '
// our ” giveMeFive ” f u n c t i o n .
// Note t h a t we do not i n c l u d e th e ' ( ) ' h er e , as we
// a c t u a l l y want th e memory a d d r e s s !
i n t ( ∗ f u n c t i o n P o i n t e r ) ( ) = giveMeFive ;
// C a l l i n g ” giveMeFive ” u s i n g th e f u n c t i o n p o i n t e r !
s t d : : cou t << ( ∗ f u n c t i o n P o i n t e r ) ( ) << s t d : : e n d l ;
// P o i n t i n g i n s t e a d at ” giveMeTen ” . . .
f u n c t i o n P o i n t e r = giveMeTen ;
//And c a l l i n g t h a t f u n c t i o n u s i n g th e same p o i n t e r !
s t d : : cou t << ( ∗ f u n c t i o n P o i n t e r ) ( ) << s t d : : e n d l ;
// Note t h a t we can a l s o u s e our p o i n t e r l i k e t h i s :
s t d : : cou t << f u n c t i o n P o i n t e r ( ) << s t d : : e n d l ;
}

Note that we can use function pointers to call our functions in two ways. The first, (*functionPointer)()
(e.g. lines 17, 23), is an explicit dereference while the second, functionPointer() (e.g. line 25),
is an implicit dereference.

Both methods carry advantages and disadvantages – calling via an implicit dereference more
closely resembles a ‘normal’ function call, but may not work with some older compilers. The
former method meanwhile, despite looking more messy, will always work.
25.1. Function Pointers 186

25.1.1 std::functions

In C++11, we have access to std::functions, which can be used similarly to function pointers,
but use a different syntax. However, these std::functions are considerably more versatile than
function pointers, in that they can work with any type of callable object including both functions
and, perhaps most importantly, lambda expressions – which we will discuss in the next section.

The downside of std::functions is that they are relatively slow as compared to function
pointers. However, as std::functions are relatively ‘new’ by C++ standards, it is likely that
they will become faster in the future as their implementation is refined.

An std::function is declared as follows:

s t d : : f u n c t i o n <r e t u r n t y p e ( ar gu m en t typ e)> name ;

So, if we want to use an std::function with a function that takes an integer as an argument and
returns an integer, we would write:

s t d : : f u n c t i o n <i n t ( i n t )> f n ;

which is equivalent to the following function pointer:

i n t (∗ fn ) ( i n t ) ;

std::functions can be ‘assigned’ a function – or other object(!) – as follows:

// f o r cin , cou t e t c .
#i n c l u d e <i o s t r e a m >
// f o r s t d : : f u n c t i o n
#i n c l u d e <f u n c t i o n a l >
// d e c l a r i n g and d e f i n i n g a f u n c t i o n . . .
i n t giveMeFive ( ) {
return 5;
}
i n t main ( ) {
// a s s i g n i n g ' giveMeFive ' to th e f u n c t i o n p o i n t e r fn ,
// which t a k e s no arguments , but r e t u r n s an i n t
s t d : : f u n c t i o n <i n t ()> f n = giveMeFive ;
// c a l l i n g ' giveMeFive ' with our s t d : : f u n c t i o n
// and o u t p u t t i n g th e r e s u l t
s t d : : cou t << f n ( ) << s t d : : e n d l ;
}

...which, again, should seem very familiar from our introduction to function pointers! Note that,
since giveMeFive takes no arguments, the ‘()’ in the std::function declaration is left empty.
25.1. Function Pointers 187

Note also that to use std::functions, we need to use the header:

#i n c l u d e <f u n c t i o n a l >
25.1. Function Pointers 188

Exercise 25.1.
For the code below:

1. Comment the code to explain what is happening at each step.

2. Determine whether each assignment of a function pointer would successfully compile.

3. Determine what will be output to the console for each ‘std::cout’.

#i n c l u d e <i o s t r e a m >
i n t giveMeFive ( ) {
return 5;
}
i n t giveMeTen ( ) {
return 10;
}
i n t timesTwo ( i n t x ) {
return (x ∗ 2);
}
i n t plusTwo ( i n t x ) {
return (x + 2);
}
i n t main ( ) {

i n t ( ∗ f u n c t i o n P o i n t e r 1 ) ( ) = giveMeFive ;
s t d : : cou t << ( ∗ f u n c t i o n P o i n t e r 1 ) ( ) << s t d : : e n d l ;

f u n c t i o n P o i n t e r 1 = giveMeTen ;
s t d : : cou t << ( ∗ f u n c t i o n P o i n t e r 1 ) ( ) << s t d : : e n d l ;
s t d : : cou t << f u n c t i o n P o i n t e r 1 << s t d : : e n d l ;

int ( ∗ f u n c t i o n P o i n t e r 2 ) ( i n t ) = timesTwo ;
std : : cou t << f u n c t i o n P o i n t e r 2 ( 2 ) << s t d : : e n d l ;
std : : cou t << ( ∗ f u n c t i o n P o i n t e r 2 ) ( 2 ) << s t d : : e n d l ;
std : : cou t << f u n c t i o n P o i n t e r 2 ( ( ∗ f u n c t i o n P o i n t e r 2 ) ( 2 ) ) << s t d : : e n d l ;

f u n c t i o n P o i n t e r 2 = plusTwo ;
s t d : : cou t << f u n c t i o n P o i n t e r 2 ( 2 ) << s t d : : e n d l ;
s t d : : cou t << f u n c t i o n P o i n t e r 2 ( ( ∗ f u n c t i o n P o i n t e r 2 ) ( 2 ) ) << s t d : : e n d l ;

f u n c t i o n P o i n t e r 1 = timesTwo ;
s t d : : cou t << f u n c t i o n P o i n t e r 1 ( 2 ) << s t d : : e n d l ;
s t d : : cou t << f u n c t i o n P o i n t e r 2 ( 2 ) << s t d : : e n d l ;

Re-write the above example using exclusively std::functions.


25.2. Lambda Functions 189

25.2 Lambda Functions

25.2.1 An Introduction to Lambda Functions

Before discussing lambda functions in detail, it is first very useful to understand inline functions
and their uses.

As we have covered previously, calling a ‘normal’ function requires the running program to ‘jump’
to the memory address corresponding to the function called, execute the relevant code, and then
‘jump’ back to the main function. Clearly, this is a somewhat time-inefficient process. When
using an inline function, meanwhile, when the code is compiled, the function call is replaced
with the function code itself. As such, when the code is actually run, there is no need to jump
between different positions in the computer’s memory when using this function. Thus, inline
functions are often used as an enhancement feature to improve the execution time of a program.

Note, however, that using inline functions will add to the size of the exe files produced, making
its widespread use unsuitable for embedded systems, for instance, where limited memory is an
issue.

Any function can be ‘made inline’ simply by using the inline keyword; for example:

i n l i n e i n t plusTwo ( i n t x ) {
return (x + 2);
}

In fact, even if a function is not explicitly declared inline, the compiler may – in certain circum-
stances – decided to make a non-inline function inline if it determines that this would make the
code more efficient.

Lambda functions are a particularly useful type of inline function. The generic definition of a
lambda function is as follows:

typ e n a m e o f f u n c t i o n [ c a p t u r e s p e c i f i c a t i o n ] ( arguments ){
methods
}

So, a very simple lambda function might look something like this:

auto s a y H e l l o = [ ] ( ) { s t d : : cou t << ” H e l l o World” << s t d : : e n d l ; } ;

Note the use of the auto keyword to automatically determine the type of the lambda function.

The capture specification, ‘[]’, at the start of the above code snippet acts as an identifier
that lets the compiler know that we are declaring a lambda function. Our function, ‘sayHello’,
requires no arguments, so the round brackets, ‘()’, which would normally hold the arguments
25.2. Lambda Functions 190

of a lambda function, are left empty. A final interesting thing to note about lambda functions
is that we do not need to specify a return type – the compiler can work that out for us!

Calling a lambda function is more-or-less as simple as calling a normal function. If we want to


call the above lambda, we simply write:

sayHello ( ) ;

in our main function, and the lambda function will be called, in our case simply outputting to
screen the now familiar “Hello World” message.

Of course, this is a very trivial example, and does not require the use of lambda functions. In
the next section, we will see the true power of lambda functions.

25.2.2 Lambdas in Action – Making a DIY CTRL+F

Lambda functions are – to put it lightly – not a trivial thing to understand and, moreover, they
perform a lot of different functions. This being the case, the best way to teach lambda functions
is not to talk about them, but to show them working. In this section, we will teach you some of
the more complex uses of lambda functions through an extended example.

The code below implements lambda functions in a code which acts to look for, and return, strings
containing a certain character or sequence of characters. Such a code might, for instance, form
the basis of an operating system’s file search mechanism, and it is in this context that we present
the code. The code also draws together many of the other more complex concepts we have come
across during the course – for example templates, classes and iterators – and, as such, should
also help us solidify our knowledge of these.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <v e c t o r >
#i n c l u d e <s t r i n g >
// d e f i n i n g a c l a s s c a l l e d ” f i l e F o l d e r ”
class fileFolder {
private :
//The ( p r i v a t e ) f i l e s s t o r e d i n our f i l e F o l d e r .
// S i n c e t h i s i s j u s t a s i m p l e example , th e f i l e s a r e ” hardcoded ”
// i n t o th e c l a s s , but c o u l d e a s i l y be made c h a n g e a b l e
// by i n c l u d i n g a ” s e t ” f u n c t i o n i n our c l a s s .
s t d : : v e c t o r <s t d : : s t r i n g > f i l e s = { ” t e x t F i l e . t x t ” , ” code . cpp” ,
” p r e s e n t a t i o n . pdf” , ” researchPaper . pd
” p r a c t i c e . cpp ” , ” n o t e s . t x t ” , ” book . p d
”document . t x t ” , ” moreNotes . t x t ” } ;
public :
// c r e a t i n g a t e m p l a t e f u n c t i o n with th e p l a c e h o l d e r name ” Fu n ction ”
// to remind us th at , f o r th e c u r r e n t problem , th e typ e w i l l alw ays
// be some form o f f u n c t i o n
t e m p l a t e <typename Function>
25.2. Lambda Functions 191

// d e c l a r i n g a tem p lated f u n c t i o n with a r e t u r n typ e t h a t i s


// a v e c t o r o f s t d : : s t r i n g s .
//The tem p lated f u n c t i o n i t s e l f w i l l r ead i n a f u n c t i o n ” s e a r c h F u n c t i o n ” .
s t d : : v e c t o r <s t d : : s t r i n g > f i n d F i l e ( Fu n ction s e a r c h F u n c t i o n ) {
// d e c l a r i n g an empty v e c t o r named ” s e a r c h R e s u l t s ” t h a t w i l l , as
// th e name s u g g e s t s , s t o r e our e v e n t u a l s e a r c h r e s u l t s !
s t d : : v e c t o r <s t d : : s t r i n g > s e a r c h R e s u l t s ;

f o r ( auto i t r = f i l e s . b e g i n ( ) , end = f i l e s . end ( ) ; i t r != end ; ++i t r )


// Checks i f our ( c u r r e n t l y unknown) s e a r c h f u n c t i o n r e t u r n s ' t r u e
// f o r th e elem en t o f th e ” f i l e s ” v e c t o r c u r r e n t l y b e i n g p o i n t e d t
i f ( searchFunction ( ∗ i t r )) {
// I f our ( unknown) s e a r c h f u n c t i o n r e t u r n s ' t r u e ' , i . e . i f
//we have found a match , i n s e r t s th e s t d : : s t r i n g c o r r e s p o n d i n
// to th e c u r r e n t elem en t i n t o our ” s e a r c h R e s u l t s ” v e c t o r a r r a
s e a r c h R e s u l t s . p u s h b ack ( ∗ i t r ) ;
}
}
// r e t u r n s a l l s u c c e s s f u l matches !
return searchResults ;
}
};

i n t main ( ) {

// D e c l a r i n g an i n s t a n c e o f th e ” f i l e F o l d e r ” c l a s s .
f i l e F o l d e r myFolder ;
// d e c l a r i n g a v e c t o r o f s t d : : s t r i n g s to s t o r e our s e a r c h r e s u l t s
s t d : : v e c t o r <s t d : : s t r i n g > myResults ;
// c a l l i n g th e ” f i n d F i l e ” f u n c t i o n from our i n s t a n c e o f th e
// ” f i l e F o l d e r ” c l a s s and p a s s i n g i s a ∗∗ lambda f u n c t i o n ∗∗ as an
// argument .
myResults = myFolder . f i n d F i l e (
//Our lambda f u n c t i o n l o o k s f o r th e s e q u e n c e o f c h a r a c t e r s ” . t x t ”
// i n any s t d : : s t r i n g s p a s s e d to i t −− i n t h i s c a s e th e c o n t e n t s
// o f ” myFolder ” ' s ” f i l e s ” v e c t o r .
// I f th e r e l e v a n t s t r i n g i s ( . t x t ) i s found , th e lambda w i l l
// r e t u r n ” t r u e ” and ” f i n d F i l e ” w i l l add th e r e l e v a n t s t d : : s t r i n g
// to th e ” s e a r c h R e s u l t s ” v e c t o r .
[ ] ( c o n s t s t d : : s t r i n g& f i l e N a m e ) {
r e t u r n f i l e N a m e . f i n d ( ” . t x t ” ) != s t d : : s t r i n g : : npos ;
}
);
// o u t p u t s our s e a r c h r e s u l t s to th e c o n s o l e !
f o r ( i n t i = 0 ; i < myResults . s i z e ( ) ; i ++) {
s t d : : cou t << myResults [ i ] << s t d : : e n d l ;
}
return 0;
}
25.2. Lambda Functions 192

Despite being heavily commented, it is still worth explaining the above code step-by-step to
provide both a clearer overview of the code’s function, as well as a few extra details, tricks and
tips.

We start off by creating a class ‘fileFolder’. Any instance of this class will possess:

1. A vector of strings (‘files’) containing a series of hypothetical file names.


2. A templated function (‘findFile’) which takes as an argument some unknown function
(‘searchFunction’). ‘findFile’ uses iterators to look through all elements contained in the
‘files’ vector array, passing each element to the unknown function. If this function returns
‘true’ for a given element, it is added to the ‘searchResults’ list. When the ‘findFile’ reaches
the end of the ‘files’ vector, the ‘searchResults’ vector is returned.

So, our ‘fileFolder’ class contains everything we need to perform a ‘CTRL+F’-style search
through our stored ‘files’ – except for a function which actually establishes whether a given
std::string from the ‘files’ vector matches our search criteria! This is where our lambda function
comes in.

In our main() function, we create an instance of our ‘fileFolder’ class (‘myFolder’) and pass a
lambda function to the ‘findFile’ member function, where it takes on the rôle of ‘searchFunction’.
Our lambda function:

[ ] ( c o n s t s t d : : s t r i n g& f i l e N a m e ) {
r e t u r n f i l e N a m e . f i n d ( ” . t x t ” ) != s t d : : s t r i n g : : npos ;
}

simply takes as an argument a string (‘fileName’) and uses the std::string’s inbuilt ‘find()’
operation to search for the sequence of characters ‘.txt’. The function returns ‘true’ if the
character sequence is successfully found (or, more specifically to the syntax used, if the sequence
is not not found!)1 . The elements of the ‘files’ vector for which our lambda function returns
‘true’ will then be added to the vector which stores our successful search results.

Note that we do not have to bother explicitly defining our lambda as a bool – the return type
of a lambda is deduced from return statements (lambdas effectively have a built-in ’auto’ !).
Nonetheless, if desired (or if our lambda contains multiple statements, which may confuse our
compiler), it is also possible to explicitly specify the type of a lambda. This is done simply by
adding ‘-> Type’ after the arguments brackets, (), but before the methods, {}. So, in our above
example, if we wanted (for peace of mind, perhaps) to explicitly declare the return type of our
lambda as a bool, we would simply need to write:

[ ] ( c o n s t s t d : : s t r i n g& f i l e N a m e ) −> b o o l { . . . }

Try running the code from the start of the section again, but this time replace the lambda
function with the above; you will notice that, as expected, it makes absolutely no difference!
1
The ‘find()’ function returns the string ‘npos’ if no matches are found in the string being searched, i.e.
fileName.find( ".txt" ) != std::string::npos will return true if a match is found.
25.2. Lambda Functions 193

Although the above example demonstrates one strength of lambdas – that they can be easily
passed as functions to other functions – the code could (almost) as easily be written without
using a lambda function. To really illustrate the beauty of lambdas, we need to show the capture
specifier in action.

Below, we show a slightly modified version of the main() function from our previous example:

i n t main ( ) {
// d e c l a r i n g and r e a d i n g i n a s t d : : s t r i n g ` searchTerm ' , a l l o w i n g
// th e u s e r to s p e c i f y th e s e q u e n c e to be s e a r c h e d f o r .
s t d : : s t r i n g searchTerm ;
s t d : : cou t << ” Find : ” ;
s t d : : c i n >> searchTerm ;
f i l e F o l d e r myFolder ;
s t d : : v e c t o r <s t d : : s t r i n g > myResults ;
myResults = myFolder . f i n d F i l e (
// M o d i f i e d lambda f u n c t i o n now ` c a p t u r e s ' th e u s e r i n p u t !
[ & ] ( c o n s t s t d : : s t r i n g& f i l e N a m e ){
r e t u r n f i l e N a m e . f i n d ( searchTerm ) != s t d : : s t r i n g : : npos ;
}
);
f o r ( i n t i = 0 ; i < myResults . s i z e ( ) ; i ++) {
s t d : : cou t << myResults [ i ] << s t d : : e n d l ;
}
return 0;
}

In the above, we adapt our program so that instead of using a ‘search term’ that is hard-coded,
we instead allow the user to choose what to search for. Let’s take a closer look at our ‘revised’
lambda function:

[ & ] ( c o n s t s t d : : s t r i n g& f i l e N a m e ){
r e t u r n f i l e N a m e . f i n d ( searchTerm ) != s t d : : s t r i n g : : npos ;
}

Unlike the original version, we now have an ‘& ’ symbol in our capture specifier. This tells our
compiler that we want our lambda function to have variable capture. By including this capture
specifier, we can use the ‘searchTerm’ variable inside our lambda even though it is not declared
within the function!

Note that using ‘&’ captures all variables and captures them by reference (variables can also
be captured by value by replacing ‘&’ with ‘=’). It is additionally useful to know that lambdas
can also capture a specific variable. For instance, instead of using ‘& ’ in our example, we could
instead have written:

[& searchTerm ] ( c o n s t s t d : : s t r i n g& f i l e N a m e ){


r e t u r n f i l e N a m e . f i n d ( searchTerm ) != s t d : : s t r i n g : : npos ;
25.2. Lambda Functions 194

This more specific capture specifier may be valuable, for instance, in situations where a large
number of variables would be captured using the more general specifiers (‘&’ or ‘=’), potentially
slowing down the resultant code. It is also possible to capture multiple variables using a comma-
separated list – just like in the arguments of normal functions.

In order to provide a complete background to lambda functions, we need to introduce one


final capture specifier – ‘this’. When inside a C++ object, the ‘this’ keyword corresponds
to a pointer which stores the address of the current object. In other words, a ‘this’ inside an
instance of a class (for example) provides a pointer to the instance itself.

As usual, these things are much more easily explained using an example:

#i n c l u d e <i o s t r e a m >
// d e f i n i n g a c l a s s ' U s e l e s s C l a s s '
class UselessClass {
public :
// d e f i n i n g a p u b l i c member v a r i a b l e , ' v a r i a b l e ' ,
// o f th e b o o l e a n typ e
bool v a r i a b l e = true ;
// d e f i n i n g a p u b l i c member f u n c t i o n , ' u s e l e s s F u n c t i o n '
void u selessFu n ction ( bool v a r i a b l e ) {
// o u t p u t s th e b o o l ' v a r i a b l e ' p a s s e d to
// th e f u n c t i o n
s t d : : cou t << v a r i a b l e << s t d : : e n d l ;
// o u t p u t s th e b o o l ' v a r i a b l e ' which
// ∗∗ b e l o n g s to ” t h i s ” c l a s s ∗∗
s t d : : cou t << t h i s −>v a r i a b l e << s t d : : e n d l ;
}
};
i n t main ( ) {
// d e f i n i n g an i n s t a n c e o f our U s e l e s s C l a s s
// and c a l l i n g i t , s u i t a b l y , u s e l e s s I n s t a n c e
UselessClass uselessInstance ;
// c a l l i n g th e u s e l e s s F u n c t i o n f u n c t i o n
// f o r th e c u r r e n t i n s t a n c e o f U s e l e s s C l a s s
// and p a s s i n g i t a ' f a l s e ' b o o l e a n .
uselessInstance . uselessFunction ( f a l s e ) ;
return 0;
}

Of course, as is often the case with these simple examples, the above code is highly unlikely to
be practically useful, but nonetheless illustrates what the ‘this’ pointer does! The code, when
compiled and run, will output:

0 (false)
25.2. Lambda Functions 195

1 (true)

But why?

The first method of our ‘uselessFunction’ does what most of us would likely expect for a
normal function of the form:

void ( bool x ) {
s t d : : cou t << x ;
}

In the second method, however, the ‘this’ keyword comes in to play. As we have just learned,
‘this’ provides a pointer to an object, in this case an instance (uselessInstance) of our class
(UselessClass). As such, when we call ‘this->variable’, we are specifically instructing our
compiler to give us the version of variable which belongs to uselessInstance – i.e. the member
variable of UselessClass – not the one read in from outside!

From this example, we can now see that the ‘this’ pointer gives us access to all the member
variables and functions associated with an object, and hence how it may be useful for a lambda
function to be able to capture the ‘this’ pointer. Below, we give an example demonstrating the
same point, but this time actually using lambda functions and their capture specifiers:

#i n c l u d e <i o s t r e a m >
class UselessClass {
public :
bool v a r i a b l e = true ;
void thisFunc ( ) {
// lambda f u n c t i o n u s i n g ' t h i s ' as a c a p t u r e s p e c i f i e r
[ this ](){
s t d : : cou t << v a r i a b l e << s t d : : e n d l ;
} ();
// n ote th e i n c l u s i o n o f a s econ d ' ( ) ' at th e end o f th e
// lambda − t h i s means t h a t th e f u n c t i o n w i l l a c t u a l l y
// be c a l l e d when ' t h i s F u n c ' i s c a l l e d .
}
v o i d thatFunc ( b o o l v a r i a b l e ) {
// an i d e n t i c a l lambda f u n c t i o n ∗∗ e x c e p t ∗∗
// u s i n g th e '= ' c a p t u r e s p e c i f i e r
[=](){
s t d : : cou t << v a r i a b l e << s t d : : e n d l ;
} ();
}
};
i n t main ( ) {
UselessClass uselessInstance ;
u s e l e s s I n s t a n c e . thisFunc ( ) ;
u s e l e s s I n s t a n c e . thatFunc ( f a l s e ) ;
return 0;
}
25.2. Lambda Functions 196

Just like the previous example, the above code will output:

0 (false)

1 (true)

i.e. the function ‘thisFunc’ (where our lambda uses the ‘this’ capture specifier) will return
true, while ‘thatFunc’ (which takes the ‘=’ access specifier) will return false. This also shows
us a valuable piece of information about the ‘=’ (and similarly &) capture specifiers – if two
versions of a variable with the same name exist, they will capture the variable in the nearest
scope (we put this concept to the test in the exercises at the end of the section!).

Make an example showing that = will look within the closest scope – i.e. show an example using
”variable” or something else and show that it then looks to the rest of the class and captures
the first thing it seems called variable!

25.2.3 Summary of Capture Specifiers

Since the last section was rather weighty, we include here a more concise summary of the various
different capture specifiers used with lambda functions.

Capture Specifier Explanation


&var Capture a single variable, ‘var’, by reference.
var Capture a single variable by value (i.e. make a ‘copy’).
var1, var2, var3... Capture multiple specified variables.
& Capture all variables by reference.
= Capture all variables by value.
[empty] Capture nothing.
this Capture the ‘this’ pointer (when in a class).
25.2. Lambda Functions 197

Exercise 25.2.
Spot the mistake: the code below, which you have already seen in the preceding chapter, contains
a deliberate mistake, the kind of typographical mistake one can easily make when coding! What
would the output of this code be, and why?

#i n c l u d e <i o s t r e a m >
class UselessClass {
public :
bool v a r i a b l e = true ;
void thisFunc ( ) {
[ this ](){
s t d : : cou t << v a r i a b l e << s t d : : e n d l ;
} ();
}
v o i d thatFunc ( b o o l v a r i a b l e ) {
[=](){
s t d : : cou t << v a r i a b l e << s t d : : e n d l ;
} ();
}
};
i n t main ( ) {
UselessClass uselessInstance ;
u s e l e s s I n s t a n c e . thisFunc ( ) ;
u s e l e s s I n s t a n c e . thatFunc ( f a l s e ) ;
return 0;
}

As you have probably already worked out, one of the (many) values of lambdas is that they do
not need to be declared and named like ‘normal’ functions. The simple code below uses the very
useful for each2 function to print a tab-separated list of all the elements in a vector. However,
this code can be re-written much more concisely and efficiently using a lambda function. In
fact, lines 6, 7, 8 and 15 can all be combined into a single line of code! Give it a go!

#i n c l u d e <i o s t r e a m >
// f o r s t d : : f o r e a c h
#i n c l u d e <a l g o r i t h m >
#i n c l u d e <v e c t o r >
// D e f i n i n g a f u n c t i o n to p r i n t tab−s e p a r a t e d l i s t s
void tabSepPrint ( i n t i ) {
s t d : : cou t << i << ' \ t ' ;
}
i n t main ( ) {
// d e c l a r i n g an a r b i t r a r y v e c t o r to p r i n t
s t d : : v e c t o r <i n t > v = { 1 , 2 , 3 , 4 , 5 } ;
// u s i n g th e f o r e a c h f u n c t i o n to p a s s a l l e l e m e n t s
2
The for each function is an easy way to apply a function to multiple elements of a given container. It takes
three arguments: the first and last elements to which we want to apply the function, and the function we want
to apply. Each of the elements between the chosen start- and end-point are then passed as the argument of the
function provided.
25.2. Lambda Functions 198

// o f v ( i . e . s t a r t i n g at v . b e g i n ( ) and en d in g
// at v . end ( ) ) i n tu r n to th e ” t a b S e p P r i n t ” f u n c t i o n
f o r e a c h ( v . b e g i n ( ) , v . end ( ) , t a b S e p P r i n t ) ;
return 0;
}

Some practice with ‘this’: In this exercise, we are going to use the ‘this’ keyword to create
the template for a ‘Top Trumps’-like game. The game should be able to compare the attributes
of different objects of the same class and decide which one ‘wins’. Some example code is given
below to get you started, but you do not have to follow the same structure; this example uses
cars, but you can try with anything you want, and add as many features to the game as you like!

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t r i n g >
c l a s s Car {
public :
// d e f i n i n g some v a r i a b l e s to r e p r e s e n t c h a r a c t e r i s t i c s
// t h a t may be im p or tan t i n a c a r !
d ou b le topSpeed ;
d ou b le bhp ;
d ou b le zeroToSixtyTime ;
// J u s t some i d e a s −
// you c o u l d add as many more as you l i k e !
//The name f o r each i n s t a n c e − i . e . your model o f c a r !
s t d : : s t r i n g model ;
// c r e a t i n g a c o n s t r u c t o r which a l l o w s us to
// e a s i l y and q u i c k l y e n t e r th e d e t a i l s o f our c a r s !
Car ( d ou b le speed , d ou b le acc , s t d : : s t r i n g name ) {
topSpeed = s p eed ;
zeroToSixtyTime = a c c e l e r a t i o n ;
model = name ;
}
// This f u n c t i o n s h o u l d d e t e r m i n e which c a r has
// th e h i g h e r top s p eed and d e c l a r e an a p p r o p r i a t e
// ” winner ” .
v o i d i s F a s t e r ( Car c a r ) {
// [YOUR CODE HERE ! ]
}
// . . .
// . . .
};

i n t main ( ) {
// C r e a t i n g some ”Car”−typ e o b j e c t s .
Car p o r s c h e ( 3 5 1 . 0 , 2 . 2 , ” P or s ch e 918 ” ) ;
Car b u g a t t i ( 4 0 8 . 8 4 , 2 . 5 , ” B u g a t t i Veyron” ) ;
// c a l l i n g th e ” i s F a s t e r ” f u n c t i o n
b u gatti . i s F a s t e r ( porsche ) ;
// i f your f u n c t i o n i s defined correctly ,
25.2. Lambda Functions 199

// both c o m b i n a t i o n s s h o u l d
// g i v e th e same r e s u l t !
porsche . i s F a s t e r ( b u gatti ) ;
return 0;
}


Chapter 26
Literature and longer exercises

26.1 Further reading

The many new terms used in the last pages indicates that C++ has much more possibilities,
rules and options to be explored. Classes, templates, over-loading, scopes, etc. can not be
discussed in this short course. However, here is a list of further literature:

1. Wikipedia ...

2. Brian W. Kernighan and Dennis M. Ritchie, The C-Programming Language, 2nd edition,
Prentice Hall, 1988.

3. B. Stroustrup, The C++ Programming Language, 3rd edition, Addison Wesley, 1997.

4. Steve Ouallinie, Practical C++ Programming, O’Reilly, 1995.

5. C. S. Horstmann, Mastering C++, John Wiley & Sons, New York, 1996.

6. S. B. Lippman, C++ Einführung und Leitfaden, 3. Auflage, Addison-Wesley, Bonn, 1998.

– 200 –
26.2. Longer exercises C++ 201

26.2 Longer exercises C++

Exercise 1

Describe with a few words what the following program is doing. Do not copy this file into your
computer - solve this by reading it and write a few sentences (in 15 minutes). Then plot a
flow-chart or flow-diagram.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m >
#i n c l u d e <cmath>
u s i n g namespace s t d ;

i n t main ( i n t ar gc , ch ar ∗ ar gv [ ] )
{
// D e f i n e f i e l d x ( t ) with l e n g t h 1000
d ou b le x [ 1 0 0 0 ] , t ; // ou tp u t v a r i a b l e s
// i n i t i a l c o n d i t i o n s
d ou b le A, d e l t a ; // A=amplitude , d e l t a=phase−a n g l e
d ou b le mass , ks p r n g ; // mass=mass , ks p r n g=s p r i n g−c o n s t a n t
d ou b le t max , dt ; // t max=max−time , dt=time−i n t e r v a l l
// Request i n p u t o f th e p a r a m e t e r s
cou t << ” am p litu d e ” ; c i n >> A;
cou t << ” phase−a n g l e ” ; c i n >> d e l t a ;
cou t << ” mass ” ; c i n >> mass ;
cou t << ” s p r i n g−c o n s t . ” ; c i n >> ks p r n g ;
cou t << ”max−time ” ; c i n >> t max ;
cou t << ” time−i n t e r v a l ” ; c i n >> dt ;
d ou b le omega=s q r t ( ks p r n g / mass ) ;
// Loop from t=0 to t=t max
t =0.0;
f o r ( i n t i =0; i<=t max / dt ; i++ )
{
x [ i ]=A∗ s i n ( omega ∗ t+d e l t a ) ; // Compute f u n c t i o n
t=t+dt ; // Step to n ext time
}

o f s t r e a m o u t f i l e ( ” p l o t . data ” ) ; // Output to f i l e
t =0.0;
f o r ( i n t i =0; i<=t max / dt ; i++ )
{
o u t f i l e << t << ” ” << x [ i ] << ” \n” ;
t=t+dt ;
}
}
26.2. Longer exercises C++ 202

Exercise 2

Writing the first program.


Extend the minimal, basic C++ program by the command lines int inum=0; cin >> inum;
where the second requests input of an integer number from the keyboard.

Write a C++ program that prints the binary representation of the integer number inum to the
screen. You can check if the program works by, e.g., using the number 496 from the lecture-
example.

Exercise 3

What is the greatest value of n that can be used in the sum

12 + 22 + 32 + . . . + n2

and gives a total value of the sum less than 100?


(a) Write a short C++ program that answers this question – like in the Matlab exercise ??
Then answer the question also for an exponent of 10 and a total value of the sum of
(b) less than 106 and
(c) less than 1012 (Advanced).
(d) If doing both parts compare the run-time between you C++ and MATLAB implementation.

Exercise 4

Declare an array with 10 001 entries. Compute the solution vector f (xi ), with xi = 0, . . . , 10 000
(as fast as possible!)

xi
f (xi ) =
sin(xi ) + 2

In the same program, form the alternating sum

Sn = f (x0 ) + f (x1 ) − f (x2 ) + f (x3 ) − . . .

up to the last term and print the result to the screen. Finally, compare the result with the result
obtained in the Matlab section ??.
26.2. Longer exercises C++ 203

Exercise 5

In the following program (part of which we have discussed today) there are hidden 10 syntax
and typo-errors. See how many you can find in 5-10 minutes.

#i n c l u d e <ios team >


#i n c l u d e <cmath>
#i n c l u d e <c s t d l i b >
u s i n g namespce s t d ;

i n t main ( i n t ar gc , ch ar ∗ ar gv [ ] )
{
int i ;
i n t n=5;
i n t ∗p ;
int a [ 1 0 ] ;

f o r ( i =0; i <=10; i++ }


a [ i ]=10;
p [ i ]=10;

cou t << a << ” \n” ;


cou t << ∗a << ” \n” ;
cou t << ∗ ( a ) << ” \n” ;
cou t << a [ 1 ] << ” \n”
cou t << ∗ ( a+2) << ” \n” ;
cou t << s i z e o f ( i n t ) << ” ” << s i z e o f f ( i n t ∗ ) << ” \n” ;
cou t << s i z e o f ( d ou b le ) << ” ” << s i z e o f f ( d ou b le ∗ ) << ”\n” ;
cou t << ” n : ” << n << ” ” << &n << ” \n” ;
i=n+1;
cou t << ” i : ” << i << ” ” << &i << ” \n” ;
p=&n ;
cou t << ” p : ” << p << ” ” << ∗p << ” \n” ;
∗p+=2
cou t << ” p : ” << p << ” ” << ∗p << ” \n” ;
p++;
cou t << ” p : ” << p << ” ” << &p << ” \n” ;

return 0;
}
26.2. Longer exercises C++ 204

Exercise 6

This is an example of pointers:

(a) Use the following program segment and play around using the pointers.

#i n c l u d e <c s t d l i b >
#i n c l u d e <i o s t r e a m >
#i n c l u d e <cmath>
u s i n g namespace s t d ;

i n t main ( i n t ar gc , ch ar ∗ ar gv [])
{
ch ar c= ' x ' ;
int a [ 2 0 ] ;
i n t ∗p = a ; // ok , a i s name o f th e f i e l d and can
// be used as a d d r e s s to th e f i e l d
// i n t ∗p = &(a [ 0 ] ) ; // . . . e q u i v a l e n t ( e r r o r −>r e d e c l a r a t i o n )

p [ 5 ] = 4; // a c c e s s to a th r ou gh p o i n t e r a r i t h m e t i c ,
// a [ 5 ] i s s e t to th e v a l u e o f 4
a [ 5 ] = 4; // . . . equivalent
//
int b [ 2 0 ] [ 3 0 ] ; // b i s now an a r r a y o f 20 a r r a y s o f
// 30 e l e m e n t s o f typ e i n t
// i n t ∗p = b ; e r r o r ! wrong type , s i n c e
// b i s o f typ e p o i n t e r to 30 i n t h e r e
int ∗r = b [ 0 ] ; // ok , r p o i n t s to th e f i r s t i n t
// i n th e f i r s t ( o f 20) a r r a y ( s ) o f 30 i n t s
i n t (∗ q ) [ 3 0 ] = b ; // ok , q p o i n t s to th e f i r s t s e t o f 30 i n t ' s ,
// q and b can now be used synonymous
q [ 1 2 ] [ 1 5 ] = 26; // ok , s e t elem en t ( 1 3 , 1 6 ) to th e v a l u e 26
( ∗ ( q + 1 2 ) ) [ 1 5 ] = 2 6 ; // . . . equivalent
∗ ( ∗ ( q+12)+15) = 2 6 ; // . . . equivalent
b [ 1 2 ] [ 1 5 ] = 26; // . . . equivalent

cou t . put ( c ) ;
int ∗ p i = new i n t ;
// Person ∗ p p = new Person (”B . S t r o u s t r u p ” , 4 5 ) ;
int n = 40;
int ∗ p a i = new i n t [ n ] ;
// . . .
delete p i;
// delete p p;
delete [ ] pa i ;
//
//
pa i [0]=5;
pa i [1]=4;
26.2. Longer exercises C++ 205

f o r ( i n t i =0; i <10; i ++) cou t << p a i [ i ] << ' ' ;

return 0;
}

Serious programming exercise:

Define an int field (vector) that contains the numbers:


{ 1, 0, -10, 12, -2, 5, 5, 1, -4, -2, -4, -8, 3, 25, 51, -4, -5 }

Then sort the entries of this linear field/vector.

(b) Read the field from a file.


(c) Use a linked-list to store the field.
(d) Implement a linked list (with pointers) to store the field.
(e) Use this linked list (with pointers) to sort the field.
(f) Write the sorted list to an output file, but remove double entries from the list. What is the
length of the field before and after this sorting/remove operation?
(g) (Advanced) Implement a (heap) tree structure to sort the field such that the largest entry
is always on top of the tree.

Exercise 7

Write a root-finding function in C++ and apply to general fifth order equation of your choice.
(Advanced)

You might also like