Programming Arcana by Andrew Cain
Programming Arcana by Andrew Cain
Programming Arcana by Andrew Cain
elcome neophyte! So you seek to master the arts of Magic. Well, you
have come to the right place. Here we will give you the opportunity to
explore magic, to understand its working and use. Before we start I
have one piece of advice for you, practice, for it is only through practice that
you can hope to learn these secret arts.
Welcome to the Programming Arcana1 , a book about learning to program. This book contains
a number of chapters that take you from knowing nothing, or little, about programming to a
position where the mysteries are revealed. By the end of the material you will be able to create
your own programs and you will be ready to start learning other programming languages and
approaches to software development.
This book is divided into a number of chapters, each of which introduces you to a programming
task and the arcane knowledge that must be attained to understand how the task is accom-
plished. As with any arcane knowledge there are special terms that are used by those who
know its secrets. In each chapter you will be introduced to the terms you need to understand
in order to perform the current task. This will provide you with the tools you need to describe
programs to other software developers, and will help you understand how the structures within
your programs work to achieve their goals.
Before we start getting into details let us have a look at how you can use this book to help you
become a master of the arcane arts of programming.
Book Overview
This book is designed for people who want to gain an in depth knowledge of software devel-
opment. It assumes that you are familiar with computers and how to use them, but does not
require you to have any prior programming experience. You should feel comfortable using a
computer, and be prepared to start looking at how it works in more detail.
There are a number of different ways in which texts can present their material. In this book, the
content is presented using a concept first approach. This approach places the programming
concepts as the central focus, with details of syntax being secondary. The logic behind this
is that you can learn new syntax if you understand the concepts, whereas it will be difficult
to be productive if you understand the syntax but do not understand the concepts behind
this syntax. To this end, this book gives you the choice to study either the C++ or Pascal
programming language. Both languages are very capable, and offer different advantages and
challenges.
The chapters of this book build upon each other. Each chapter covers a new group of concepts,
that will expand your programming capabilities and enable you to create larger and more
capable programs. The layout of each chapter is the same, with the concepts having the main
focus. Each chapter is laid out in the following order:
1. Concepts: The first part of the chapter introduces the concepts that will be covered. This
is done in a language neutral manner, with the focus being on how to think about the tools
being presented. This will introduce each concept with an illustration, and accompany
this with explanatory text.
1 Arcana is defined as secrets or mysteries, Wiktionary defines it as “specialized knowledge that is mysterious to
the uninitiated.”. This fits well with the idea of programming, and we think it is a cool word to describe the magic of
programming!
1
2. Using the Concepts: The next section shows how these concepts can be used to achieve
a task. This task will try to cover all the concepts presented in a practical manner. This
is done in a language neutral way, and talks about how to use the concepts to achieve a
goal.
3. Languages: The next two sections present the syntax you need to use these concepts in
C++ and Pascal. You should use this as a reference, and can read this alongside reading
about how to use the concepts.
4. Understanding: Following the language specific details, the next section explains in de-
tail how the concepts work within the computer. Use this to get an understanding of
how the concepts work in more detail. This section will show you illustrations of what is
happening within the computer when your code is running.
5. Examples: Each chapter will have at least one example showing you how these concepts
can be used. This will include the code, and some explanatory text to discuss what is
being presented.
6. Exercises: The exercises allow you to put into practice what you have read about. You
cannot learn to program without practice. These exercises are a good start, but you
should try to come up with your own project so that you can test out these new concepts
on something you are interested in working on.r
Which Language?
A programming language defines a set of rules that determine how you write the code for
your programs. Each language defines its own rules, and so there is always the temptation to
focus heavily on these details and place the overriding concepts in second place. We believe
that when you are starting to learn to program, a good understanding of the programming
concepts is far more important than the details of the programming language you are using.
This book is not an in depth study of either the C++ or Pascal language, it is a book about
learning to program.
To really learn these concepts well you will need to practice putting them to use. This will
require you to use a programming language. Each chapter will provide you with enough infor-
mation to put the concepts to use in either the C++ or Pascal language. So the main question
you need to answer now is which language will you use?
Both C++ and Pascal are very capable languages. Pascal was designed as a teaching language,
which means that it does make it a little easier to see how the concepts being covered apply
to your code. C++, on the other hand, is a commercial language designed for professionals to
build programs. This is both an advantage and disadvantage for C++. The advantage is that
the language is widely used in industry, but the disadvantage is that it lacks the clarity that is
offered by Pascal. Remember that this is only your first programming language. A professional
software developer will know many different languages, and by the end of this material you
will be equipped to learn many new languages.
C++
C++ is a very flexible language that is widely used in industry, though its syntax is more
♢
of a challenge to learn.
Pascal
Pascal is a powerful languages that was designed to teach programming. It is used in
♡
industry, but not to the same extent as C++.
2
Formatting
This book has a number of visual formatting guides. These are designed to help you navigate
through the material easily.
Pseudocode
Text formatted in this way relates to an algorithm description. This will describe the steps
that need to be performed in a way that is language neutral and can be applied to C++, ♣
Pascal, and possibly other languages.
C++
Text formatted in this way relates to the C++ programming language. If you are going to
use C++ you need to pay attention to the text in these boxes, otherwise you can skip over ♢
them.
Pascal
Text formatted in this way relates to the Pascal programming language. If you are going
to use Pascal you need to pay attention to the text in these boxes, otherwise you can skip ♡
over them.
Note
Text formatted in this way covers notes related to the current concept or illustration. This
♠
book makes extensive use of notes to capture important points, so do not skip over these.
The language sections of each chapter also add markers to each page to clearly mark where
they start, and where they end. If this is your first programming experience you should stick
with one of these languages, so you can skip the pages that are marked as being for the other
language.
Programming has a lot of its own jargon. As you learn to develop software it is also important
that you start to learn this special language that software developers use to discuss their pro-
grams. You will find that this terminology is used in many places. It is used in programming
texts, in discussions between developers, in discussion boards, blogs, anywhere that devel-
opers are discussing software development. Having a clear understanding of this terminology
will help you make the most of these resources.
The concepts in this book are closely linked to this programming terminology. To help you
understand each concept, we have classified them using one of the following categories:
• Artefact: An artefact is something that you can create in your code.
• Action: Actions are things that you can command the computer to do.
• Term: These are general terms, used to describe some aspect.
When you are reading about the different concepts in this book you can use these classifica-
tions to help you think about how you may use the knowledge you are gaining.
Artefacts: Artefacts are things that you create in your code. Programming is a very abstract
activity, you spend most of your time working with concepts and ideas. You write text, code,
that will create things within the computer when your code is run.
3
When you are learning about a new kind of artefact come up with ways of visualising it. It
is a thing that you are creating with your code. Try to picture the artefact within your code.
These artefacts are the basic building blocks that you have to work with. You need to be very
familiar with them, how they work, and what you can do with them.
Actions: Actions get the computer to perform a task. Your actions will be coded within the
artefacts that you create, and will define how artefacts behave when they are used. The
actions themselves are commands that you issue to the computer. They are executed one at a
time, and each kind of action gets the computer to carry out certain tasks.
When you are learning a new kind of action you need to see what this action does. To start
with you should play with it, test it out, and see if you can understand what it is getting the
computer to do. As you progress you need to start thinking about how you can sequence
these actions so that the computer performs the tasks you want it to. There are only a very
few kinds of actions, so it is by combining them that you can get the computer to do what you
want.
Terms: The remaining terms are words that developers use to explain concepts. These are
not things that you create, or actions that you request. These are just words that you need to
know.
When you are learning a new term you need to try to commit it to memory. Memorise the
terms, try to use them in sentences, explain them to others. All of these tasks will help you
understand, and remember these terms.
Advice
If you want, or need, to learn to program then you can not do this just by reading a book,
even one as magical as this. Learning to program requires practice. This book is designed
to give you the concepts you need in order to understand how to go about creating your first
programs. To really understand these concepts you need to apply them to the creation of your
own programs.
When you are getting started, programming can appear quite daunting and the tools you use
can be unforgiving. Work through these initial challenges, and with practice you will be able
to overcome them. Once you have some success there is nothing better than seeing a program
you created running on a computer. You have brought the machine to life, getting it to perform
a task the way you want it performed. Once you get a program working it can become easy
to get hooked and working on new features and functions becomes a real joy. The greater the
challenge the program offers, the greater your sense of achievement when you see the working
product in operation.
Other people are the best resources to help you get over these initial challenges. Fellow stu-
dents studying this material can provide you with support, and a chance to discuss the chal-
lenges you are facing. Teaching staff are also a good resource when you are really stuck. If
you do not have access to anyone who can help, use discussion boards and websites. Getting
the right help will make a large difference to your learning experience.
Remember that you will need to study this material. That is not just reading it, but thinking
and reflecting on what you have read. Try to think about each of the concepts, and how they
relate to the other material that has been presented to you. Try to design and build your own
programs with the material you are learning. If you do think deeply and apply the concepts to
programs you create, you will eventually get the light bulb moment when things become clear
and programming can become truly joyful.
4
Building Programs
1
agic requires both knowledge and tools. Our first lesson will uncover
the tools of the Magi. Tools that you will need to use to practice
magic. Here, take this ancient wand this orb and caldron. Ea of
these tools is essential to the working of even the most basic magic. Now lets
see if you can wield that wand. Take it in your hand like this, and . . .
Software development requires both knowledge and tools. This first chapter will introduce you
to the tools used by software developers. Tools that you will need to use to practice creating
programs.
When you have understood the material in this chapter you will be able to make basic use of a
Text Editor, the Terminal, and command line tools to create programs from source code.
Contents
1.1 Concepts Related to Building Programs . . . . . . . . . . . . . . . . . . . . . . 6
1.1.1 Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.2 Machine Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1.3 Assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1.4 Source Code and the Compiler . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.1.5 Terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.1.6 The First Program: Hello World . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.1.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.2 Using these concepts: Compiling a Program . . . . . . . . . . . . . . . . . . . 22
1.2.1 The SplashKit Manager: skm . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.2.2 Making the Hello World Program . . . . . . . . . . . . . . . . . . . . . . . . 22
1.3 Installing a Text Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.4 Using the C++ Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.4.1 Hello World in C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5 Using the Pascal Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5.1 Hello World in Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.6 Understanding Program Compilation . . . . . . . . . . . . . . . . . . . . . . . . 29
1.6.1 Levels of Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.6.2 Computers and Intelligent Behaviour . . . . . . . . . . . . . . . . . . . . . 30
1.7 Exercises on Building Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.7.1 Concept Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.7.2 Code Writing Questions: Applying what you have learnt . . . . . . . . . . . 31
1.7.3 Extension Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5
CHAPTER 1. BUILDING PROGRAMS
In this chapter you will learn about the basic tools you need to use to create your own pro-
grams. You will see an example program, and then use these tools to convert that code into an
executable program. You will then be able to run the program you created, and see it perform
the tasks you coded.
This chapter provides a background on what programs are, and the general processes of how
they are created. This will introduce you to the tools you will be using, and fill in some details
of what they are doing and how to use them. The topics covered include the following:
• Programs: This section introduces you to the idea of what a program is, and what it
contains. You will need to be familiar with programs and what they are, as you will need
to be able to create your own.
• Machine Code: Talks about the kinds of instructions the computer understands, and
why it is not very productive to work at this level. You need to understand that this exists
behind the scenes, but do not need to be overly familiar with it.
• Assembly: The next level of language is called Assembly. It is very close to machine code,
but much easier to understand and use. However, this is still too low a level to be very
productive. Just like machine code, you only need to know this exists
• Source Code and the Compiler: This is the level we are going to be working with in this
book. This code is much easier to work with than assembly, and allows you to create
your own programs reasonably quickly once you have learnt the basics. These are the
tools you are going to be working with throughout this text.
• Terminal: This is a command line environment that lets you issue text commands to the
user. You will use this to create and run your programs.
• The First Program: Hello World: A classic program used to check that you have everything
working correctly. This section shows you the code that you can use this to check that
you have all the tools setup correctly, and to check their usage.
• Making the Hello World Program: This final section will show you how to use these tools
to compile and run your own Hello World program. Figure 1.1 shows the Hello World
program running from the Terminal.
6
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
1.1.1 Programs
If you are going to learn to develop software you will need to become intimately aware of what
a program is. After all, as a developer you will be creating your own programs.
A program is a file that contains instructions that get the computer to perform a task. Pro-
grams are lists of commands1 telling the computer what to do, and the order in which to do
it. Each instruction is very simple, but they can be executed very quickly, allowing computers
to perform quite remarkable feats.
Figure 1.2: A program contains instructions that command the computer to perform a task
Note
• You can run programs, which gets the computer to follow the instructions found
within the program’s file.
• To run, the program’s instructions must first be loaded into memory.
• Once in memory, the computer starts running the instructions one after the other.
• When the last instruction is completed the program ends. ♠
• There are several different ways to run a program:
– You can double-click the program in a file browser.
– On tablets and app-phones you can tap the program’s icon.
– Advanced uses can enter text commands in the Terminal to start programs.
1 C++ and Pascal are both imperative programming languages. In the imperative paradigm a program is seen as a
7
CHAPTER 1. BUILDING PROGRAMS
When you run a program, regardless of how it is started, the Operating System loads it from
disk into memory and then starts it running. It is important that the file you try to run is a
program. These are special files that contain instructions the computer can understand.
Hello World
----------------------------
Program: Hello World
----------------------------
Steps:
The computer reads 1: Output 'Hello World!' to the Terminal
the program off
the disk,
Figure 1.3: Programs are loaded from disk into memory, then run
Note
• Your Operating System is a piece of software that is responsible for managing your
computer’s hardware.
• One of the Operating System’s responsible is to start programs.
♠
• The Terminal can be used to start programs.
• Programs can also output to the Terminal.
• A Program must contain instructions that the computer can understand.
8
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
00101011
Commands
........
Multiply signed
numbers
01101001
........
Test a condition, and just to
another instruction if 0
01110100
Note
• The CPU, Central Processing Unit, is the workhorse of the computer. It executes the
program’s instructions.
• The instructions a CPU uses is called its Instruction Set, and different CPUs have
♠
different instruction sets.
• Some common instruction sets: ARM (used in most mobiles and tablets), x86-64
(used in desktops and laptops).
9
CHAPTER 1. BUILDING PROGRAMS
Listing 1.1 shows a chunk of the machine code for a small program. These 1s and 0s are the
codes used to instruct the computer when this program is executed. Programs can be written
directly in machine code, but this is a time consuming task. This is further complicated by
the fact that machine code is unique to each kind of CPU. This means that programming at
this level is entirely dependent on the kind of processor that you are targeting.
Listing 1.1: 128 bits from the 106,752 bits of Machine Code from a small program.
No one wants to have to work at this level of details, and fortunately you do not need to. Soft-
ware developers have created tools to help them create programs without having to think about
these low level details. These tools make it possible to work at a higher level of abstraction.
They take the code you write, and do the hard work of converting that to the machine code of
the computer you want to run it on.
Note
• You can look at the machine code of any program on your computer. You just need
the right tools.
• If you open the program’s executable file in a text editor it will look very strange, and
not at all like a large list of binary values. This is because the text editor displays ♠
one character for every byte (or two bytes depending on the file) from the file.
• A Hex Editor is a program that is useful for examining binary data. It shows you
one character for every four bits in the file.
Figure 1.5: A HexEditor allows you to view the machine code of any program
10
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
1.1.3 Assembly
The next level of abstraction up from machine code is called Assembly, or Assembler Code.
Here the numeric machine code instructions are given symbolic names that are, to some
degree, more understandable for humans. The code may be given the symbolic
name , for example.
Programs written in this language cannot be executed directly by the computer, it isn’t machine
code. Assembler code is converted to machine code by a program called an Assembler. This
program reads the instructions from the assembler code and outputs machine code. So, for
example, anywhere it encounters in the code it can output .
.cstring Assembly
LC0:
.ascii "Hello\0"
Code
.text
.globl _main Symbolic names for the
machine code instructions
_main:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
call ___i686.get_pc_thunk.bx Assembler converts
"L000001$pb": Assembly Code to
leal LC0-"L000001$pb"(%ebx), %eax Machine Code
movl %eax, (%esp)
call L_printf$stub
addl $20, %esp
popl %ebx
popl %ebp
ret
Assembler
Only the machine code
can be executed by the
computer
Note
• As with Machine Code, Assembly is liked to individual CPUs.
• Assembly is very close to Machine Code, its machine code with symbolic names for ♠
the instructions.
11
CHAPTER 1. BUILDING PROGRAMS
Programming in Assembly
The code in Listing 1.2 shows an example of some assembler code. This is the assembler code
that was used to generate the machine code from Listing 1.1. The machine code was 13,344
bytes in size, where the same program in assembler code is only 658 bytes. The assembler
reads these 658 bytes, combines it with instructions from program libraries, and outputs
machine code.
$
4
7
7
$
77777
$ $
$ $ $
$77
$
$
Listing 1.2: Assembler Sample
From a programmer’s perspective, assembler code is much easier to work with than machine
code, though there are still issues with the use of assembler code. Firstly Assembly is bound to
the instruction set of the CPU that you are targeting, meaning that if you want to support other
kinds of CPU you will need to rewrite the program. The other main issue with assembler code
is that while it is more understandable, you are still working with the primitive instructions of
the CPU. Working at this level takes considerable effort to write even simple programs.
Assembly languages were first developed in the 1950s, and were known as a Second Genera-
tion2 programming languages. This step forward did make programming easier, but the tools
have advanced since then and now we can work at an even higher level of abstraction.
12
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
The next step in programming language evolution moved from machine level instructions to
something more human readable. These languages, known as Third Generation Languages,
use move advanced programs than assemblers to convert their instructions into machine code.
Programs written in these languages have their code converted to machine code by a com-
piler.
A Compiler is a program that converts Source Code into machine code that is saved into
an executable file called a Program. The program can then be executed independent of the
compiler and the source code.
Internally, a compiler will perform a number of steps, as shown in Figure 1.7.
1. Preprocessing: The code is read from your source code files. This may involve some
processing of the text itself, which includes things like ignoring any comments in the
code.
2. Compiling: The code is then converted into assembly instructions, and an assembly
program is output.
3. Assembling: The assembly version of the program is converted into machine code, and
stored in object files.
4. Linking: In the final step the compiler uses a Linker to join together the machine code
from your program, with other machine code you have used from the programming li-
braries. This then outputs an executable program.
Source Code
More "Human" readable
int main() commands The Compiler uses a Linker
{ to combine your
write_line("Hello World"); code with library code
return 0; and create the final
} machine code file...
Compiler
Linker
.... 1110 0101 1111
0100 0001 0101 1000
Compiler converts your code 0110 0111 0111 0010
to Assembly, and then 0000 0000 0111 ....
uses an Assembler to Your Code as Machine Code
convert this to machine code
Assembler
Your code can now be run
on the computer...
13
CHAPTER 1. BUILDING PROGRAMS
Listing 1.3 and Listing 1.4 show two examples of source code. This code describes a small
program that can be used to output a message to the Terminal.
/
+ #
7
/ /$
' / '
Listing 1.4: Example Pascal code
Listing 1.3: Example C++ code
The code shown in Listing 1.3 shows the code for the C++ program that was used to generate
the assembler code, and machine code shown in the previous code listings. This code must
be converted by the C++ compiler into machine code before it can be run. It is interesting to
note the size of the C++ file: it is only 50 bytes! The compiler converts this 50 bytes into the
13,344 bytes of machine code.
Listing 1.4 shows the same program written in the Pascal programming language. Like its
equivalent C++ code, this must be compiled to create a program you can run.
Programs written in a third generation programming language are much easier to understand
than their assembler or machine code counterparts. It is also possible that this code can be
compiled to run on different types of CPU, making it more portable. Most modern programming
languages are third generation programming languages.
The code that a programmer writes in these languages is called Source Code. Typically source
code is saved into a text file with a file extension that helps identify the language it is written in.
For example, programs written in the C++ language are saved into files with a file extension
whereas Pascal programs are saved into files with a extension.
Note
• There are may different Third Generation Languages, including both C++ and Pascal.
• Each language has its own compiler that understands that language’s code.
♠
• The C++ compiler we will use is clang++ (or g++ - the GNU C++ Compiler).
• The Pascal compiler we will use is called fpc - this stands for Free Pascal Compiler.
14
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
1.1.5 Terminal
Once you have written some source code, you need to be able to compile it. This means, you
need to run the compiler, and give it your source code files to compile. The best way to do this
when you really want to learn about programming, is to run the compiler directly yourself. To
do this you needed to use a Terminal program.
The Terminal is a program that gives you command line access to the computer. With command
line access you can enter text commands to start programs. These programs can output details
back to the Terminal for you to read, and interactive programs can also read input from you
via this same Terminal.
Terminal
Bash
Figure 1.8: The Terminal program gives you command line access to your computer
Note
• On Ubuntu Linux you can find the Terminal in the Accessories folder within Appli-
cations. See Figure 2.14.
• On MacOS you can find the Terminal in the Utilities folder within Applications. See
Figure 2.15.
♠
• On Windows you will need to download and install MSys2. The MSys2 Shell is the
equivalent of Terminal on the other operating systems. The details for how to install
this are in the SplashKit installation guides.
• The Terminal is also be called the console or command prompt.
15
CHAPTER 1. BUILDING PROGRAMS
The Shell
The Terminal program itself just provides a text environment, allowing text input and output.
Within this environment a Shell program is run to interpret your commands. This is an
interactive program that will display a prompt to you, at which you enter your commands.
There are a number of different Shell programs, each of which has its own set of instructions.
The Shell we are going to use in this book is called Bash. This shell program is available on
Linux, Mac OS, and Windows. As a Unix shell it is native for Linux and Mac OS, and with
Windows you can install MSys2 to use these commands.
A shell program is very simple. It provides a text prompt at which you can enter commands.
The Shell then reads the text you entered, and performs an action based on the text you
entered. You can use the Shell to perform operations like copying and deleting files, and
starting programs.
Note
• The name ‘Shell’ came from idea that this was the outermost shell of the computer,
the interface between the user and the computer’s internals.
• Bash stands for ‘Bourne-again shell’, as Bash is a replacement for the Bourne shell. ♠
• It will take some time to get used to using Bash, but the more you learn about it the
more useful it will become.
16
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
Using Bash
To get started using Terminal you will need to know some Bash commands, see Table 1.2.
To get started with Bash, you need to understand a little bit about the file system. Each
operating system needs a way of storing its files, and there are going to be lots of files stored
on a computer. This means that it would be cumbersome to try and keep these all in one
place. Instead, the Operating System places files in directories (also known as Folders). A
directory can contain files, and other directories.
When you are working in Bash, you will have a working directory. This is the directory
where Bash will start searching for the files you are interacting with. To start working with
the compiler you will need to be able to use the change directory command to move to the
directory that contains your source code files.
With the Change Directory command you tell Bash which directory you want to move into,
with the different parts of this path being separated by forward slashes (/). Example com-
mands to move to your Documents directory are shown in Table 1.3, with screenshots for
Linux in Figure 1.10, Mac OS in Figure 1.11, and Windows in Figure 1.12.
Table 1.3: CD command to move into your documents directory on various Operating Systems. In these
examples
should be replaced by your user name. The examples in Figure 1.10, Figure 1.11, and
Figure 1.12 are for the user
.
Note
• You can find many resources on using Bash on the web, a simple overview of the
basic commands can be found at
7
77 .
♠
• After you run the command, you can check which directory you are in using the
pwd command. To do this just type and press enter.
• Once you get used to the command you can start exploring the other commands.
17
CHAPTER 1. BUILDING PROGRAMS
18
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
19
CHAPTER 1. BUILDING PROGRAMS
There is one very special program that all developers create. This is the first program a software
developer creates when they start using a new language, or technology. It is the famous Hello
World!
This is a very simple program, it runs and outputs the text ‘Hello World’ to the Terminal. So,
why is this the first program? It makes sure that everything is set up correctly. If ‘Hello World’
does not work, then there is something wrong with your setup you need to check.
Listings 1.5 and 1.6 show the code for the ‘Hello World’ program written with the C++ and
Pascal programming languages. Both programs result in the same output when run: they
write the text ‘Hello World!’ to the Terminal. They both use the same basic programming
structures, and they both go about performing the task in the same way. At this stage, however,
they are both just fancy text. What we need to do is use a special tool to convert these into
programs, we need to compile them.
C++
7
/ ♢
Listing 1.5: Hello World code in C++.
Pascal
/
+ #
♡
/$
' / '
Listing 1.6: Hello World code in Pascal.
Note
• This source code needs to be written into a text file.
• C++ source code usually has a .cpp file extension. For example, hello-world.cpp.
• Pascal source code usually has a .pas file extension. For example HelloWorld.pas.
♠
• It is a good idea to create a directory (folder) under which you will place your code.
Within this directory you can create other directories for individual projects, or for
the code related to the chapters in this book.
20
1.1. CONCEPTS RELATED TO BUILDING PROGRAMS
1.1.7 Summary
This chapter has introduced the concepts related to the tools you need to use to create pro-
grams. Computers can execute machine code, but this isn’t very friendly for people to read
or create. Assembly code provided the first layer of abstraction over machine code, giving
symbolic names to the machine code instructions. This was a little easier to work with, but
still required considerable work to create programs of even simple functionality. Most mod-
ern programs are written from third generation languages such as C++ and Pascal. With
these languages the develop writes source code that is converted by a compiler into machine
code.
Interprets your
commands using
a Shell like Bash Existing Artefact
Existing Artefact
Command line
access you can
Terminal Bash
use to run
the Compiler
Is a Program
Is a Program
Artefact
Instructions the
computer can use...
You write code
for your own
First generation
programs as
Program language
Source Code...
Contains
Third generation
Machine Code
language Term
Term
Source Code Term
Assembly
Assembler
Note
• The Terminal, Bash, Compiler, and Assembler are all existing programs that you
can use.
• Source Code, Assembly Code, and Machine Code are all terms for different ways ♠
that a program’s instructions can be represented. Though Machine Code is the only
form that can be executed directly by the machine.
21
CHAPTER 1. BUILDING PROGRAMS
Now that the concepts have been presented, let us have a look at how these can be used to
create a program. We will take the code from the Hello World, and use a compiler to turn this
code into a program that we can then execute. This process is the same for large and small
programs.
Before we get started, there is one additional tool that we can use to help make SplashKit
programs easier to work with: the SplashKit Manager (skm). ‘skm’ is a command line tool that
comes with SplashKit when you install it. It is designed to take your compiler instructions,
and add the extra options needed to link with the SplashKit library.
The best way to get started with a SplashKit program is to create a new folder (directory) in your
file system that will be used to store the code and other files related to that program.
C++
The following commands create a MyProject folder, setup a new C++ project, and then
compile it into a program.
%(
%( ♢
%(
Listing 1.7: Creating a C++ project with skm.
Pascal
The following commands create a MyProject folder, setup a new Pascal project, and then
compile it into a program.
%(
%( ♡
+
Listing 1.8: Creating a Pascal project with skm.
Listing 1.5 and Listing 1.6 show the source code for the Hello World program. To make this
into a program you need to:
1. Write the code into a text file.
2. Save the text file to disk.
3. Compile it.
Step 1 and 2 can be accomplished with any text editor, but the best ones to use highlight your
code. Each programming language has rules that determine how its code must be formatted.
This is known as the language’s syntax. You can get text editors that understand these rules,
and highlight your code as you type. This is called syntax highlighting. This highlighting
can help you identify any little mistakes you make.
22
1.2. USING THESE CONCEPTS: COMPILING A PROGRAM
Figure 1.14 shows the Hello World code in Visual Studio Code with C++, which has a consistent
look across all platforms. The figure also includes the command line instructions needed to
setup a new SplashKit C++ project, and compile it.
Figure 1.14: Editing and Compiling C++ code in Visual Studio Code
Figure 1.15 shows the Hello World code in Visual Studio Code, which has a consistent look
across all platforms. The figure also includes the command line instructions needed to setup
a new SplashKit Pascal project, and compile it.
Figure 1.15: Editing and Compiling Pascal code in Visual Studio Code
23
CHAPTER 1. BUILDING PROGRAMS
Once you have saved the code to file it is time to compile your program. For this you are going
to need to open a Terminal, and change into the directory where you saved the source code
file. Once you are in this directory it is time to run the compiler.
When you run the compiler you need to give it two kinds of information: options, and the name
of the file to compile. The compiler will read the code in the file you give it, and convert this to
machine code as shown in Section 1.1.4 Source Code and the Compiler. The exact command
you use depends on the compiler you are using.
C++
In C++ the compiler we will be using is called clang++ (or g++ the GNU C++ Compiler).
The command you need to run in the Terminal is shown in Listing 1.9. The -o name option
tells the compiler the name of the program file to create. In our example this will compile
the code in hello-world.cpp and save the machine code into a program called HelloWorld. ♢
/
Listing 1.9: Compiling C code.
Pascal
In Pascal the compiler we will be using is called fpc, which stands for the Free Pascal
Compiler. The command you need to run in the Terminal is shown in Listing 1.10. The -
S2 option is used to tell fpc to compile using the latest ‘Free Pascal’ version of the language.
In our example this will compile the code in HelloWorld.pas and save the machine code
into a program called HelloWorld, which it gets from the name of the Pascal file. ♡
+
/
Listing 1.10: Compiling Pascal code.
Once you get the program to compile you can run it! This will load your program into memory,
and start its steps running. The HelloWorld program will output the text ‘ / ’ to the
Terminal. To run the program you need to use its name. The command you need to enter
is shown in Listing 1.11, and in Figure 1.16. The before the file tells Bash to look in the
current directory for the program.
/
Listing 1.11: Bash command to run HelloWorld
24
1.2. USING THESE CONCEPTS: COMPILING A PROGRAM
Compilers are very specific about the code you give it. If the source code you try to compile
does not follow all of the rules of the language then the compiler will fail, and end with an
error message. These errors, called syntax errors, could be as small as missing a semicolon
(;), or misspelling a name. To get your program to compile you will need to correct any syntax
errors the compiler finds in your code.
Figure 1.17: These Terminals show some syntax errors from programs that are missing a single semi-
colon (;)
Figure 1.17 shows an example output caused by removing a single semicolon from the Hello
World program’s code. The numbers in the error messages give you an idea of where the
compiler got to when it encountered the error. So the text output from the
C compiler indicates that the compiler got to line 6 before it encountered the error. The text
/
output from the Pascal compiler indicates that it got up to line 2 character
1 before it encountered the error.
When the compiler encounters these issues it does not create the executable program. You
need to learn to use these error messages to help you locate errors in your code, so that you
can fix them, and then run the compiler again to generate your program.
Note
• Syntax errors are very common. Do not worry when this occurs to you.
• Always start with the first error. The compiler will try to continue compiling your
code after it finds an error. This can mean that later errors do not really exist, once
you fix the earlier ones. ♠
• Unfortunately compiler error messages are not always very clear on what the cause
of the error is. You need to learn how to read and understand these messages.
• To get good at programming requires lots of practice.
25
CHAPTER 1. BUILDING PROGRAMS
When you are programming you will spend most of your time in a Text Editor. The best kinds
of editors for program code include syntax highlighting where the editor uses details about the
language to highlight parts of the code as you write it. This can make it easier to find and fix
small errors as you go.
There are many different syntax highlighting text editors, each will support different program-
ming languages and operating systems. We recommend that you use Visual Studio Code. It
is fast, extensible, cross platform, and free! The details of how to install this and configure it
for your language are on the SplashKit website.
26
1.4. USING THE C++ COMPILER
The C++ programming language is very powerful and flexible. In this section you will see the
tools that you need to start programming with C++ on your computer.
Now that you have the compiler installed you can create your first program: the famous Hello
World discussed in Section 1.1.6. The C++ code for this is shown in Listing 1.12. This code
tells the computer to ‘write’ the text Hello World! to the Terminal, and follow it with a new line.
Do the following to create this program for yourself, see the notes below for hints:
1. Open your text editor
2. Create a new text file
3. Type3 in the text below, making sure you get every character correct.
4. Save your program’s code in a file called hello-world.cpp, and note the directory where
it is saved
5. Open the Terminal
6. Change into the directory where you save the file
7. Compile the program using
/
8. Run the program using /
( *
Well done, you have now created and run your first C++ program!
C++
7
/ ♢
Listing 1.12: Hello World code in C++.
Note
• Check out the SplashKit installation guide for how to setup the text editor on your
machine.
• See Using Bash in Section 1.1.5 for an example of how to use the Terminal. ♠
• See Section 1.2 Using these concepts: Compiling a Program for the overall process
and the output you should expect from the program.
The Pascal language is a great first programming language. It is both powerful and clear in its
syntax. In this section you will see the tools that you need to get started with Pascal.
3 Do not just copy and paste it out of the text, type it in yourself as this will help you learn the concepts being
covered.
27
CHAPTER 1. BUILDING PROGRAMS
Now that you have the compiler installed you can create your first program: the famous Hello
World discussed in Section 1.1.6. The Pascal code for this is shown in Listing 1.13. This code
tells the computer to ‘write’ the text Hello World! to the Terminal. Do the following to create
this program for yourself, see the notes below for hints:
1. Open your text editor
2. Create a new text file
3. Type4 in the text below, making sure you get every character correct.
4. Save your program’s code in a file called HelloWorld.pas, and note the directory where it
is saved
5. Open the Terminal
6. Change into the directory where you save the file
7. Compile the program using +
/
8. Run the program using /
Well done, you have now created and run your first Pascal program!
Pascal
/
+ #
( *
♡
/$
' / '
Listing 1.13: Hello World code in Pascal.
Note
• See Section 1.3 Installing a Text Editor for details on installing the Text Editor.
• See Using Bash in Section 1.1.5 for an example of how to use the Terminal.
♠
• See Section 1.2 Using these concepts: Compiling a Program for the overall process
and the output you should expect from the program.
4 Do not just copy and paste it out of the text, type it in yourself as this will help you learn the concepts being
covered.
28
1.6. UNDERSTANDING PROGRAM COMPILATION
An in depth look at how programs and compilers work is beyond the scope of this book. Instead,
this chapter focuses on two aspects that can help you understand why we need compilers, and
how these are able to help us. These topics are Levels of Abstraction, followed by Computers
and Intelligent Behaviour.
Programs are very complicated. Trying to keep all of the details about how it works in focus
all of the time would take a large amount of effort, and slow you down. As humans we have
developed strategies for dealing with these kinds of situations. What we do is create layers of
abstraction.
A layer, or level, of abstraction provides a means of managing details at a similar level of detail.
This means that all aspects of that level are similar, and related to each other. When you are
working at a certain level, you think in terms of the tools and artefacts that are available to
you.
These levels build on top of each other, with each layer being built on top of the lower layer,
and providing the foundation for the next higher layer. Within a layer of abstraction you do
not need to think about the lower levels of abstraction, most of the time. However, it is always
good to know the details of at least one level of abstraction below the level you are working
at.
Computers are unintelligent. This is one of the first, and most important, things you need
to understand when starting to create your own programs. A computer is a machine that
can be programmed using Machine Code. These binary commands instruct the computer to
perform basic actions such as adding numbers, reading values from memory, storing values
in memory, jumping to new instructions elsewhere in memory, and other simple tasks. While
this is a very low level, it is not the lowest level of abstraction.
Below machine code, there is the abstraction for binary. This is the idea that you can have
a number system based on two digits, 0 and 1. The machine code level builds on this idea,
creating a set of instructions that can be used to tell the computer what to do. Below binary
there is the concept of gates, which are themselves built on top of electronic circuits, which
in turn are made from discrete electronic components. Even these low level electronic com-
ponents are based upon something else, but to discuss this we would need to delve into the
realm of semiconductors and Quantum Mechanics. From machine code you can also work
up to Assembly, and then to Source Code and the Compiler.
Whenever you are working on something you need to be able to work at that level of abstraction,
and have an understanding of the level below, and the level above. For programming this means
that you will need to understand of the tools provided to you by the language (a level below),
and you need to understand the features and functions of the program you are creating (a level
above).
In this book the Understanding section of each chapter will help you see how the concepts
covered work at a lower level of abstraction. Often this means these sections are very detailed.
You should read these sections to understand how the abstractions (concepts) covered in the
chapter work, at a level of abstraction lower than you will be working at.
29
CHAPTER 1. BUILDING PROGRAMS
If computers are unintelligent, how can they do the awesome things they do?
That is a good question. Computers are unintelligent, but programs are not. The computer
does not know what it is doing. It is following a set of steps that was coded into the program
being executed. These steps, however, were created by people, software developers. When a
computer does something cool, its because a person told it to do that.
This is why it can be really great fun to be a software developer. You get to make computers do
things you want them to. This creativity can be really exhilarating when you finally get your
program to do exactly what you want.
Intelligent Unintelligent
Hello World
Figure 1.18: Computers are unintelligent, any interesting behaviour comes from programs created by
software developers
30
1.7. EXERCISES ON BUILDING PROGRAMS
Read over the concepts in this chapter and answer the following questions:
1. What is a Programs? What does it contain?
2. What is Machine Code?
3. Can you write programs in Machine Code? Explain any issues associated with this.
4. What is Assembly?
5. Can you write programs in Assembly? Explain any issues associated with this.
6. What tool is used to convert Assembly to Machine Code?
7. What is Source Code?
8. What are the advantages of programming at a Source Code level?
9. What tool is used to convert Source Code to Machine Code?
10. Why do you need to convert Source Code and Assembly to Machine Code?
11. What is the Terminal?
12. What is Bash?
13. Which command is used to change directories in Bash?
14. With Bash, how can you check which directory is the current working directory?
15. How can you list all of the files in the current directory?
16. Why program ‘Hello World’? What does it do for you?
17. What is the name of the C or Pascal compiler we will be using in this book?
18. How intelligent is your computer?
31
CHAPTER 1. BUILDING PROGRAMS
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. What is the difference between a compiler and an interpreter? How are programs of
interpreted languages, such as Python, executed?
2. If you compile a program for an Intel CPU on UNIX, can you run this on a UNIX machine
that has a PowerPC CPU?
3. If you compile a program on a Windows machine can you run the resulting program on
a UNIX machine with the same CPU architecture?
4. What is a fat, or Universal, binary?
5. What is a Virtual Machine?
32
Program Creation
2
asting spells crafted by others is alright, but the true power of magic
can only be realised by crafting your own spells. You have done well
mastering the tools, so now let us turn our attention to the study of
the arcane knowledge of spell craft. To create your own spells you need to
know. . .
Compiling programs crafted by others is alright, but the true power of programming can only
be realised by learning to craft your own programs. Chapter 1 introduced you to the tools you
need to compile programs from source code, so now we can turn our attention to the study
program creation.
This chapter introduces the artefacts used to create programs, and how you can code these
using a programming language. You will start by learning to create simple programs that
output information to the Terminal.
When you have understood the material in this chapter you will be able to write the code
needed to declare a program, convert this code into an executable program using a compiler,
and then run the program you created. You will have made those first important steps in your
journey to master this arcane knowledge.
Contents
2.1 Program Creation Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.1.1 Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.1.2 Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.1.3 Procedure Call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.1.4 Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.1.5 Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.1.6 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.1.7 Identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.1.8 Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.1.9 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.1.10Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.2 Using these Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2.2.1 Designing Output Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2.2.2 Understanding Output Test . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
2.2.3 Choosing Artefacts for Output Test . . . . . . . . . . . . . . . . . . . . . . . 47
2.2.4 Writing the Code for Output Test . . . . . . . . . . . . . . . . . . . . . . . . 48
2.2.5 Compiling and Running Output Test . . . . . . . . . . . . . . . . . . . . . . 51
2.3 Program Creation in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
33
CHAPTER 2. PROGRAM CREATION
2.3.1 C Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
2.3.2 C Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
2.3.3 C Procedure Call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
2.3.4 C Identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
2.3.5 C Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
2.3.6 C Literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.3.7 C Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
2.3.8 C Terminal Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
2.3.9 C++ Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
2.3.10Some Common C Errors with Program Creation . . . . . . . . . . . . . . . 69
2.4 Program Creation in Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
2.4.1 Pascal Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
2.4.2 Pascal Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
2.4.3 Pascal Procedure Call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
2.4.4 Pascal Identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
2.4.5 Pascal Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
2.4.6 Pascal Literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
2.4.7 Pascal Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
2.4.8 Pascal Terminal Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
2.4.9 Pascal Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
2.5 Understanding Program Execution . . . . . . . . . . . . . . . . . . . . . . . . . 81
2.5.1 Starting a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
2.5.2 Calling the Write Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
2.5.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
2.6 Program Creation Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
2.6.1 Seven Times Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
2.6.2 Circle Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
2.6.3 Shape Drawing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
2.7 Program Creation Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
2.7.1 Concept Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
2.7.2 Code Writing Questions: Applying what you have learnt . . . . . . . . . . . 101
2.7.3 Extension Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
34
2.1. PROGRAM CREATION CONCEPTS
Our first program is going to display some text to the Terminal. In this section you will be
introduced to the programming artefacts and terminology you will need to use to create this
program. This first step is important and will require you to have installed a C++ or Pascal
compiler, see Chapter 1 Building Programs for instructions.
A programming artefact is something that can be created and used within your code. In this
chapter we will look at creating programs, and using a number of other artefacts. The following
artefacts will be covered in this chapter:
• Program: A program is a sequence of instructions that when compiled creates an exe-
cutable file that a user can run.
• Procedure: A procedure is a named sequence of instructions that will get the computer
to perform a task. When you want the task performed you can call the procedure.
• Library: The program can use code from other Libraries. These libraries contain reusable
Procedures and Types.
• Type: A type defines how data is interpreted by the program. The programming language
will support a number of basic types by default, and libraries can add other types.
In addition to these artefacts, you will need to understand some programming terminology.
The following terms are discussed in this section:
• Statement: An instruction within the program.
• Expression: A value used in a statement.
• Identifier: The name of an artefact.
This section also introduces the following kinds of instructions. You can use these to get the
computer to perform certain actions within your program.
• Procedure Call: The instruction to run a procedure.
We can then use these concepts, artefacts, and instructions to create a program that will write
some text to the Terminal as shown in Figure 2.1.
35
CHAPTER 2. PROGRAM CREATION
2.1.1 Program
In most software projects the top level artefact you are aiming to create is a program. Within
your software a program is a list of instructions the computer will perform when that program
is run on the computer.
When you create a program in your code you should be thinking about the tasks you want the
program to achieve, and the steps you must get the computer to perform when the program is
run. These then become the instructions within the program, with each instruction being a
Statement of what you want performed.
Identifier
My Program
The compiler turns Has a name
the Program's code that is an Library
into an executable file
May use procedures
from one or more
The Program has an Libraries
entry point Program
that indicates where
the program's
instructions start
Contains instructions
Instruction 1
Statement
Instruction 2
Instruction 3
Instruction 4
Each instruction is a Instruction 5
statement commanding ...
the computer to perform
an action
Figure 2.2: A program contains instructions that command the computer to perform actions
Note
• A program is an artefact, something you can create in your code.
• Figure 2.2 shows the concepts related to the program’s code.
• A program is a programming artefact used to define the steps to perform when the
program is run.
• You use a compiler to convert the program’s source code into an executable file.
• By declaring a program in your code you are telling the compiler to create a file the
♠
user can run (execute).
• The program has an entry point that indicates where the program’s instructions
start.
• The name of the program determines the name of the executable file.
• Your program can use code from a Library or number of libraries.
• In programming terminology, an instruction is called a Statement.
36
2.1. PROGRAM CREATION CONCEPTS
2.1.2 Statement
When you are created a program you define the actions the computer will perform when the
program is run. Each of these actions is coded as a statement within the program. This style
of programming is known as imperative programming. Imperative means to give authoritative
commands, and that is what we do in our programs. Our programs are lists of authoritative
commands, statements, that tell the computer the actions it is to perform.
Statement
Procedure
Instruction 1
Instruction 2 Parameter
Instruction 3
Instruction 4
Instruction 5 Parameter
...
Note
• A statement is a term used to describe the instructions in your code.
• Figure 2.3 shows the concepts related to statements.
• A statement is a command, an instruction to perform an action.
• A Program has a list of statements that are followed when it is executed.
♠
• There are only a few kinds of statements. Each statement has a defined set of actions
the computer performs to carry out the command.
• A Procedure Call is a kind of statement that tells the computer to run the code in a
Procedure.
37
CHAPTER 2. PROGRAM CREATION
A procedure call is a kind of Statement that instructs the computer to run the code in a
Procedure. This statement uses the procedure’s name to identify the procedure that must be
run. If the procedure called requires some data, this data is passed to the procedure as part
of the procedure call.
Runs a procedure
Statement
Is a kind of
Procedure Identifier
Figure 2.4: A procedure calls runs a procedure, passing in values for the procedure to use
Note
• A procedure call is an action, you can call procedures in your code.
• Figure 2.4 shows the concepts related to the procedure call.
• A procedure call is an instruction to execute a procedure.
• You can code a procedure anywhere you can code a statement.
♠
• The Identifier indicates the Procedure to run.
• Data values passed to the procedure are coded using Expressions.
• When the procedure’s task is complete the program continues with the next State-
ment.
38
2.1. PROGRAM CREATION CONCEPTS
2.1.4 Procedure
Performs a task
Procedure Identifier
Contains instructions
Instruction 1 Parameter
Instruction 2
Instruction 3
Parameter
Instruction 4
Instruction 5
...
Passes in
Values
Starts the
Contains a
number of
Library reusable Procedure Call
Figure 2.5: A procedure contains instructions to perform a task, and may need to be passed data in
order to do this
Note
• A procedure is an artefact, something that can be created in code.
• Figure 2.5 shows the concepts related to procedures.
• A procedure is a programming artefact that can be called to perform a certain task.
• The name of a procedure is an Identifier.
• Each Library will contain a number of procedures to perform common tasks.
♠
• The standard library will include procedures to write values to the Terminal.
• The SwinGame libraries contain procedures that can draw images on the screen,
play sounds, and perform other tasks needed to create small games.
• Procedures are also known as subroutines, sub-programs, methods or sub-
procedures.
39
CHAPTER 2. PROGRAM CREATION
2.1.5 Expression
Some statements need data, this data can be calculated or provided as a literal value in the
code. The term expression is used in programming to describe the places in a statement
where data must be supplied. At run time each expression becomes a value that is used by
the statement.
Is a value.
7 * 10 + 3
Integ ole
er)
wh
Calculations are evaluated
numb sults in a
Appear as
part of a using BODMAS order
The value may
er (an
of operations
be calculated
e
Statement
This r
Expression
Has a
The value may
These are called
be written directly
Literals
in the code
Type
Literal
This is textual
This is a whole
number (an Integer)
Note
• An expression is a term given to code that calculates a value.
• The concepts related to expressions are shown in Figure 2.6.
• An expression provides a value that is used in a Statement.
• The expression’s value may be calculated or entered directly into the code.
• Calculations can use mathematical operators: + for addition, - for subtraction, * for
multiplication, / for division, and parenthesis ( ) for grouping. ♠
• Expressions are evaluated using the BODMASa order of operations.
• Values entered directly within an expression are Literal values.
a BODMAS indicates that expressions are evaluated B brackets first, O orders (which includes powers and
square roots), DM for division and multiplication (which are of equal precedence, and are evaluated left-to-right),
then AS addition and subtraction (of equal precedence, evaluated left-to-right).
40
2.1. PROGRAM CREATION CONCEPTS
2.1.6 Type
All values within a program will have a type. The type indicates how the data stored in the
computers memory is interpreted by the program. There are three basic data types available
in a programming language, as shown in Figure 2.7.
• Textual data such as ‘Fred’, ‘Hello World’, ‘23’, and ‘This is text!’.
• Whole numbers such as 1, 0, -5, and 37.
• Real numbers such as 0.5, -126.0, 3.141516, and 23.981.
Indicates a kind
of data
Determines how
the program interprets Determines the
the value operations that are
Type permitted with the type
2387226039927203144
If this is a whole number
its value is...
4.186633e-149
'Hello!!!'
If this is a real number
If this is textual data its value is...
its value is...
00100001001000010010000101101111
01101100011011000110010101001000
This is a 64 bit binary value
Figure 2.7: A types define how values are interpreted and the operations that can be performed on the
data.
Note
• A type is an artefact, there will be a number of existing types that you can use, and
later you will see how to create your own types.
• The concepts related to expressions are shown in Figure 2.7.
• A type is a programming artefact that indicates a kind of data.
• The type determines the basic actions that can be performed on the value.
• The type determines the amount of memory needed to store a value of that kind.
♠
• Whole numbers are usually called Integers.
• Real numbers are usually represented as Floating Point values. These values have
a limited precision, supporting only a certain number of digits of precision.
• Textual values can contain numbers as text characters. For example, the text ‘23’ is
the character ‘2’ followed by the character ‘3’ - it is not the number 23.
• You can perform mathematic operations on numeric data, but not on textual data.
41
CHAPTER 2. PROGRAM CREATION
2.1.7 Identifier
An identifier is the technical term for the name/word that identifies something for the compiler.
These can be the name of a programming artefact (such as a Program, Library, or Procedure)
or words that have special meaning for the compiler. You will use identifiers to name the
artefact you create, and to select the artefact you want to use.
Is the name of
something
Is a kind of Identifier
that has special
Identifier meaning to the
language
Program
Instruction 1
Library
Instruction 2
Instruction 3
Instruction 4 Procedure Uses the procedure's
Instruction 5 Procedure name to determine
... Procedure
Instruction 1
Procedure which procedure
Instruction 2 Parameter to call
Instruction 3
Uses the Library's Instruction 4
Instruction 5 Parameter
name to access ...
Procedure Call
its procedures
Figure 2.8: An Identifier is the name of a programming artefact such as a Program, Library, or Procedure.
Note
• Figure 2.8 shows the concepts related to an Identifier.
• The name used to identify a programming artefact (such as a Program, Library or
Procedure) is an identifier.
♠
• You use identifiers to indicate which libraries you want to access in your program.
• Each Procedure Call uses the procedure’s identifier to determine which procedure is
run.
42
2.1. PROGRAM CREATION CONCEPTS
2.1.8 Library
A library is a collection of reusable code artefacts. Each programming language has its own
library, and your programs can make use of the code available in this library.
Library
Contains Procedure
procedures you Procedure
can use
Parts of the
May use code Library can be
from the Library used used by others...
Program
Figure 2.9: A library contains code that can be used by your Program
Note
• A library is an artefact, it contains reusable artefacts.
• Figure 2.9 shows the concepts related to a library.
• A library is a collection of reusable code artefacts that you can use to perform certain
tasks.
• The library will contain Procedures that perform a number of tasks. ♠
• Each language has a standard library with code to perform many commonly per-
formed tasks.
• Other libraries extend the capability of the languages further.
• SwinGame is a external library containing code to help you build games.
43
CHAPTER 2. PROGRAM CREATION
2.1.9 Comments
A program’s source code contains instructions for the actions the computer must perform.
However, this code is written and maintained by people. It is often useful to be able to place
comments in the code to help someone reading that code understand how the code works or
what it is trying to achieve. This text is not something that should be translated into machine
code.
Programming languages support the ability for programmers to embed comments into the
source code that are ignored by the compiler.
Note
• It is good practice to place a comment at the top of your code explaining what the
program does.
• Comments should be included to help other people read your code. You will also find
♠
these comments useful when you return to your code after a long break.
• Make your comments meaningful, try to capture your intentions and ideas.
• Comments have no impact on the output produced by the compiler.
44
2.1. PROGRAM CREATION CONCEPTS
2.1.10 Summary
This section has introduced a number of programming artefacts, some programming terminol-
ogy, and one kind of instruction. An overview of these concepts is shown in Figure 2.10. The
next section will look at how you can use these concepts to design some small programs.
Has a name
that is an Term
Artefact Term
Artefact
Term
Performs a task
when it is called Expression
Artefact
Note
• Artefacts are things you can create and use.
• Terms are things you need to understand. ♠
• Actions are things you can command the computer to perform.
45
CHAPTER 2. PROGRAM CREATION
Armed with the knowledge you have gained in the Section 2.1 you can now start to make your
own small program.
Our first programming task is to extended the classic ‘Hello World’ program to also output
some data values. We will call this program Output Test. This program will allow you to see
all of the different concepts from this chapter in action. A description of the program is shown
in Table 2.1, and a sample execution is shown in Figure 2.11.
Program Description
Name Output Test
Description Displays the text ‘Output Test Program!’ on the Terminal, followed by
‘ 1 + 1 = ’ and the result of the calculation 1 + 1, and then
‘ Area of a circle with radius 3 = ’ and the result of calculating this
value.
46
2.2. USING THESE CONCEPTS
The first step in creating a program is to analyse the problem, and find related material that
we can use to make sure we know what the computer needs to do. You need to understand
what the program needs to do before you can start to design the solution.
For this program you need to understand how to calculate the answer of the equation 1 + 1
(which is a trivial task), and also how to calculate the area of a circle , given its radius . A
quick search of the internet and you can find the equation is 𝑎 = 𝜋𝑟2 . Using these equations
you have the knowhow needed to calculate the values needed to be output.
Designing a program is all about making decisions around how to organise the program’s
instructions. This means deciding on which artefacts you will create, and which you will use.
This chapter has already introduced the concept of creating a Program, and using Procedures.
With these tools it is possible to design simple programs that will get the computer to perform
actions by running procedures in sequence.
Let us return to the design of the Output Test program. The program will require:
• The creation of a Program. This program will contain the instructions to write the three
messages to the terminal.
• The use of a procedure to write to the terminal. Programming languages provide a stan-
dard Library that, amongst other things, contains procedures to write data to the ter-
minal. This means you can call one of these procedures, passing it the data you want
written to the Terminal, and let it take care of the details of how this is done.
The design for this program can be documented using a programming language neutral pseu-
docode1 . This is a structured textural description of how the program works that is indepen-
dent of the programming language used to implement it.
Listing 2.1 shows the pseudocode for the Output Test program. This represents the program
that needs to be created, and shows the three procedure calls that need to be made.
Pseudocode
( ' ,
+
' '' , ( ' ,
♣
' ' '
' ' '
Listing 2.1: Pseudocode for the Output Test program.
C++
In C the procedure to write data to the Terminal is called
, see C Terminal Output. ♢
Pascal
Pascal has two procedures to write data to the Terminal, / and /$
. ♡
1 This is literally translated as ‘false code’; it looks like code, but it is not real code!
47
CHAPTER 2. PROGRAM CREATION
The pseudocode in Listing 2.1 contains the instructions that will get the computer to perform
the actions needed by the Output Test program. These pseudocode instructions are not in a
form that can be used by the computer, which can only use machine code. To make this into
a program the pseudocode must be translated into source code, and then to compile this into
machine code.
Section 2.3 Program Creation in C and Section 2.4 Program Creation in Pascal, contain a
description of the syntax needed to create programs using the C and Pascal programming
languages. Each section outlines how to write the code so that it can be understood by a
compiler. The programming languages are expressed as a number of related syntax rules. You
will find the rules that you need to create a program, the rules for calling a procedure, and
other related rules.
In this book the syntax rules are expressed using syntax diagrams. An example is shown in
Figure 2.12. This diagram shows the syntax related to two rules, first rule, and second rule,
and shows the four main parts of all the syntax diagrams.
1. Text found at the start of a line (not contained in a box) is the name of a rule. There are
two rules in Figure 2.12: first rule, and second rule.
2. Arrows show the order in which the parts of the rule are applied. They start at the rule
name, and point in the direction you need to follow. Each box pointed to by an arrow
represents either another rule to apply, or the text that must written.
3. Rectangular boxes (nodes) on a line indicate points where other rules need to be applied.
For example, the node second rule within the first rule indicates that you must apply
the second rule at this point.
4. Boxes with rounded corners represent text that must be entered into the code. For ex-
ample, the node
within the first rule indicates that you must write the
text ‘write in the code’ at this point in your code.
In order to make use of these syntax diagrams, you must know what it is that you want to write
in code. The rules in Figure 2.12 indicate that you can write either a first rule or a second rule.
If you want to write a first rule you find that rule in the diagram, and then follow its arrows.
Reading the first rule indicates that the second rule must be applied first.
The second rule tells you that you must write the text ‘stuff to’. The vertical bar at the end of
the line indicates the end of the second rule. This means at this stage the code is:
Having finished the second rule, you can return back to finish the first rule. This indicates that
you need to write ‘write in the code’ in the code. This is the last part of the first rule, and so the
code needed to write a first rule from the syntax diagram in Figure 2.12 is shown below.
For a more realistic example have a look at the syntax diagram in Figure 2.13.2 This shows
2 The
...
is used as shorthand to avoid having to list all of the characters between ‘A’ to ‘Z’.
48
2.2. USING THESE CONCEPTS
identifier letter
letter
digit
letter
...
...
digit
...
There are three rules in Figure 2.13, including the identifier rule itself and rules for letter
and digit. These rules show arrows that give you options, and the ability to repeat parts of
the rules.
• A letter is one alphabetic character: i.e. one of ‘A’ to ‘Z’ or ‘a’ to ‘z’. This is an example of
options in the syntax, where you follow one of the available arrows.
• A digit is a single number: i.e. a number between ‘0’ and ‘9’.
• The identifier has a more complicated rule, with the following parts:
1. The first thing in an Identifier must be either a letter or an underscore ( ).
2. Next you have the option of following the top line and ending the identifier, or following
the downward arrow and including other letters, numbers, and underscores.
3. Following the downward arrow you have a new option where you can choose to have
either a letter, a digit, or an underscore as the second character in your identifier.
4. Continuing after this option you have another option where you can return back to
repeat the previous step, allowing you to have identifiers with more than one or two
characters.
Syntax diagrams can help you to map a concept to actual code that needs to be written in your
source code. To use these diagrams you must first know what it is that you want to create or
use, and then you can look up the related syntax. This is where pseudocode code comes into
play. It contains a description of the things that need to be created.
3 Most programming languages have the same rules for identifiers.
49
CHAPTER 2. PROGRAM CREATION
Listing 2.2 shows the pseudocode for the Output Test program. This tells you what needs to
be created; you need to create a Program. This means you need to find the syntax that tells
you the rules of how a Program is written in a programming language.
Pseudocode
( ' ,
+
' '' , ( ' ,
♣
' ' '
' ' '
Listing 2.2: Pseudocode for the Output Test program (repeated from Listing 2.1)
When you write the code for the program you will need to know the actions you want the
computer to perform. The pseudocode in Listing 2.2 indicates that you need to output text
and calculated values to the terminal; this can be achieved using Procedure Calls. You can
lookup the language syntax for a procedure call, and use this to write the required code.
The C and Pascal Syntax needed to create a program are shown in Section 2.3 Program Cre-
ation in C and Section 2.4 Program Creation in Pascal. Each part of the Syntax is presented
on its own page that shows a syntax diagram followed by an example and some notes. The
best way to approach this is to do the following:
1. Find the page with the syntax rule you are interested in knowing about.
2. Have a quick look at the syntax diagram and the rules it contains. Read each rule, and
get a basic feel for how it is going to come together for your program.
3. Read the example to see one way of using the rule. A syntax diagram can be used to
create any number of variations of the rule. However examples show you at least one way
these rules can be coded.
4. Return to the diagram and make sure you can match each part of the example back to
the rule that created it.
5. Now look up any related rules that are not explained on this rule’s page. For example,
a Program will use the Statement rule to code its instructions. The actual rule for a
Statement will have its own page. When you read the rules for a Program you will need
to also find the page with the rules for a Statement so that you know how to code these
within the program.
As you follow this process it is also a good idea to take notes and to try to use these rules in
your own programs. Have your code editor open, and see if you can follow the rules or mimic
the examples to start building your own program’s code. You can also try typing in some of
the examples to see how they work.
Learning to program, and learning a language’s syntax, takes time and practice (like juggling).
Reading about these concepts is one thing, but being able to successfully apply this ideas is
something different. Make sure that you practice using these concepts and syntax.
50
2.2. USING THESE CONCEPTS
Previous sections have shown pseudocode for the Output Test program. These steps can be
coded, using either C or Pascal, into a source code file. In order to actually use these instruc-
tions you will need to compile the source code file. This will produce an executable file that
you can run. To do this you can use the terminal and the command line compiler as shown
in Chapter 1.
• On Ubuntu Linux you can find the Terminal in the Accessories folder within Applica-
tions. See Figure 2.14.
• On MacOS you can find the Terminal in the Utilities folder within Applications. See
Figure 2.15.
• On Windows you will need to download and install MSys2, follow the steps in the SplashKit
installer. The Msys2 Shell is then the equivalent of Terminal on the other operating sys-
tems. You will find this in Program Files, MSys2. See Figure 2.16.
Once you are in the Terminal you have the ability to run a number of text based commands.
These commands instruct the computer to perform actions for you.
• pwd stands for Present Working Directory, and shows you where you are in the file system.
• ls stands for List and it prints out a list of the files that are in the current directory.
• cd stands for Change Directory and it moves you to another directory.
To compile your program you need to do the following:
1. Change into the directory where your code is located using the cd command. For example,
if your code is in a Code folder in your Documents folder you would use:
• Linux:
• MacOS: -
• Windows: (in MinGW Shell) -
4
2. Run the compiler, passing in the name of the file you want to compile. See the language
specific notes below
3. Execute the program using ',
C++
The C compiler is called gcc. To compile your Output Test program you will need to run
the following:
♢
7 ',
Pascal
The Pascal compiler is called fpc. To compile your Output Test program you will need to
run the following:
♡
+
',
4 This example moves you into the ∖-∖ ∖ ∖ folder. You need to use the /c/ to refer to the
C drive.
51
CHAPTER 2. PROGRAM CREATION
52
2.2. USING THESE CONCEPTS
Figure 2.17 shows an example of the instructions needed to compile and run the C version of
the Output Test program on Linux. Figure 2.18 shows an example of the instructions needed
to compile and run the Pascal version of the Output Test program on Linux.
Figure 2.17: Example of compiling and running a C version of Output Test on Linux
Figure 2.18: Example of compiling and running a Pascal version of Output Test on Linux
53
CHAPTER 2. PROGRAM CREATION
Figure 2.19 shows an example of the instructions needed to compile and run the C version of
the Output Test program on MacOS. Figure 2.20 shows an example of the instructions needed
to compile and run the Pascal version of the Output Test program on MacOS.
Figure 2.19: Example of compiling and running a C version of Output Test on MacOS
Figure 2.20: Example of compiling and running a Pascal version of Output Test on MacOS
54
2.2. USING THESE CONCEPTS
Figure 2.21 shows an example of the instructions needed to compile and run the C version of
the Output Test program on MacOS. Figure 2.22 shows an example of the instructions needed
to compile and run the Pascal version of the Output Test program on MacOS.
Figure 2.21: Example of compiling and running a C version of Output Test on Windows
Figure 2.22: Example of compiling and running a C version of Output Test on Windows
55
CHAPTER 2. PROGRAM CREATION
Compiler Errors
A compiler is a very sensitive piece of software; they require that you follow the language’s
syntax precisely. One small mistake, and the compiler will fail to compile your program and
end with an error message. This is a good thing! (Although it may not feel like it at first.)
Why? Because when programs become complicated we need the exact details to help us, and
to assure the program works the way we need it to.
Here are some handy hints related to dealing with compiler errors.
1. Know that errors are inevitable. You will get compiler errors! As you gain more experi-
ence you will get fewer errors, but it will always be a rare event that everything is exactly
as it should be the first time.
2. Error messages may appear cryptic at first. In many cases the compiler’s error mes-
sages can appear cryptic, you need to learn to decode the messages the compiler gives
you.
3. Start with the first error message, and do not move on until it is fixed. The compiler
will read your code ‘top down’. So the first error it outputs will be the first in the file. The
problem is that the compiler will try to continue on, despite the error. This can mean
that other errors further on in the output may actually be caused by the compiler being
confused due to the first error. By fixing the first error you may also fix subsequent
errors.
4. Deal with one error at a time. It is easy to feel overwhelmed when you see a huge list
of errors, but do not be scared off! Start at the first error, and solve them one by one.
Compile after fixing each problem to see if the others still exist.
5. Do not add more code until the errors are fixed. Compile your program frequently.
Add small pieces of functionality, and then fix any syntax errors before adding the next
piece of functionality. Coding in this way makes sure that you do not get too many errors,
and reduces the code you have to search in order to fix the problem.
6. Read the error message carefully. The message will try to tell you what has gone wrong,
and once you understand what the messages are trying to say you will be able find and
fix the issues quickly.
7. Work out what the error messages mean. Understanding the error messages will mean
that you will know what to look for, and will help you avoid these errors in the future.
If your not sure what an error message means ask others developers or search for the
message on the internet.
8. Find the line and character number of the error. One important detail in the error
message will be the line number of the error. This gives you a starting point to help you
locate the problem. It is important to note that this is where the compiler got to when it
noticed the error - this does not mean this is where the error actually is (but it is a good
place to start looking). You may need to look back one or more lines to find the actual
source of the problem.
9. Watch for typos. It is easy to mistype an identifier. When this happens the compiler
will not know what to do (and it will complain about you trying to use ‘unknown’ things).
Make sure you check for these tiny typos when you get errors related to the compiler not
being able to find an identifier.
10. When you get stuck ask for help. Compiler errors are likely to be something small, but
sometimes the causes are hard to find. If you get stuck, ask for help! Having access to
other more experienced developers will be a valuable resource as you learn to program.
Learning to program can be tough at times, and having someone who can help you when
you get stuck will make all the difference.
56
2.3. PROGRAM CREATION IN C
Section 2.2 on page 46 of this chapter introduced an ‘Output Test’ program, and its design.
The pseudocode from this section is shown in Listing 2.3. In this Section you will see the rules
for translating this program’s design into the C code shown in Listing 2.4.
Pseudocode
( ' ,
+
' '' , ( ' ,
♣
' ' '
' ' '
Listing 2.3: Pseudocode for Hello World program (from Listing 2.1).
C++
( 7
/ ,
*
' ♢
7
' , (
7
7
7
7
Listing 2.4: Output Test in C
Note
• Save the C code in a file named .
• Compile this using ', 7 .
• Run using ', .
• The code at the start is a Comment describing what is in the file, see C++ Comments.
• The code
, is part of the C Program. It is a header include, and
gives access to the code in the Standard IO Library.
•
is part of the C Program, it marks the entry point and contains the ♠
instructions that are executed when the program runs.
• The
function contains three C Procedure Calls. Each is a call to the
.
Procedure, which is used to output text to the Terminal. See C Terminal Output.
• Each of the procedure calls contains one or two Expressions that pass values to the
procedure, which will output these to the Terminal.
• This code uses
,
, and types, see C Types.
57
CHAPTER 2. PROGRAM CREATION
2.3.1 C Program
The C programming language does not have an explicit Program artefact for you to create.
Rather, in C a program is implied by the existence of a special function called ‘
’ somewhere
in your source code. Figure 2.23 shows the structure of the syntax you can use to create a
program using the C language.
header include
block { }
statement
The code in Listing 2.5 shows an example C Program. You should be able to match this up
with the syntax defined in Figure 2.23. Notice at the start of the code the syntax indicates we
can have an optional header include, this matches up with the first line in the code where it
includes the ‘stdio.h’5 header file. Declaration of the
function follows the inclusion of the
header file, and it contains the instructions that are executed when the program runs.
C++
7
/ ♢
Listing 2.5: C Hello World
Note
• A C Program starts at the first Statement within the
function (line 5).
• A function is a kind of Procedure, and their details will be covered later.
• The ‘
’ code is a Statement that ends the
function (and the program). ♠
• With the header include syntax you use
to include standard libraries,
and
to include other external libraries.
5 Read ‘stdio.h’ as ‘standard IO’. This is the file that gives you access to a Library that contains procedures you can
58
2.3. PROGRAM CREATION IN C
2.3.2 C Statement
In a Statement you are commanding the computer to perform an action. There are only a small
number of statements you can choose from. At this stage the only statement is the Procedure
Call, known as the procedure statement in C. This is shown in Figure 2.24, where we can see
that at this stage all Statements are calls to Procedures.
C++
!
7
/ #
'& '
/
7
'& ' '(
'
'& ' ♢
7
, #
/ + '& '
7
/
*
Listing 2.6: C Knights
Note
• The code in Listing 2.6 contains a C Program.
• This Program contains five procedure calls, see C Procedure Call.
♠
• Each procedure call runs the
procedure to output text to the Terminal. See
the section on C Terminal Output.
59
CHAPTER 2. PROGRAM CREATION
A procedure call allows you to run the code in a Procedure, getting its instructions to run
before control returns back to this point in the program.
argument
argument expression
C++
7
7
♢
7
*
7
Listing 2.7: C Count Back
Note
• A procedure call is an action which commands the computer to run the code in a
procedure.
• The procedure call starts with the procedure’s Identifier, this indicates the procedure
to be called.
• Following the identifier is a list of values within parenthesis, these are the values
(coded as Expressions) that are passed to the procedure for it to use. ♠
• Remember that C is case sensitive so using (
instead of
will not work.
• The code in Listing 2.7 contains a C Program.
• This Program contains four procedure calls.
• Each procedure call runs the
procedure to output text to the Terminal. See
the section on C Terminal Output.
60
2.3. PROGRAM CREATION IN C
2.3.4 C Identifier
The C Identifier syntax is shown in Figure 2.26. In C, as in most programming languages, the
identifier must start with an underscore ( ) or a letter; in other words your identifiers cannot
start with a number or contain other symbols. This is because the compiler needs a way of
distinguishing identifiers from numbers entered directly into the code.
identifier letter
letter
digit
letter
...
...
digit
*
...
Note
• In the syntax definition an identifier cannot contain spaces, or special characters
other than underscores ( ).
• A letter is any alphabetic character (a to z and A to Z ).
• A digit is a single number (0 to 9).
♠
• Each item in Table 2.2 is a valid identifier.
• The keywords are identifier that has special meaning to the language.
• The example identifiers give you examples of the kinds of names you could give to
artefacts you create.
61
CHAPTER 2. PROGRAM CREATION
2.3.5 C Expression
1.5
1
2
1.5b
6.5
aC does integer division for int values, rounding the value down.
b If either, or both, values are real (floating point) numbers the result is also a real number.
Note
• Table 2.4 shows some example expressions, their values, and types.
• Expressions can be literal values, entered in the code.
♠
• Expression can contain mathematical calculations using standard addition, sub-
traction, multiplication, division, and grouping.
62
2.3. PROGRAM CREATION IN C
2.3.6 C Literal
A literal is either a number or text value stated directly in the code. In other words, it is not
calculated when the program runs - it is already in the code. Figure 2.27 shows the syntax
for the different literal values you can enter into your C code.
single digit
sign
sign
sign digits
*
∖
∖
∖
∖∖
character string
single character
Note
• Within a string the ∖ character is used to indicate that the next character has a
special meaning. The following list includes the most useful special characters:
– ∖
creates a new line
♠
– ∖ creates a double quote
– ∖ creates a % character
– ∖∖ creates a ∖
63
CHAPTER 2. PROGRAM CREATION
2.3.7 C Types
Types are used to define how data is interpreted and the operations that can be performed
on the data. Table 2.5 shows the three basic types of data, the associated C type, size in
memory, and other related information. Table 2.6 shows the operators that are permitted for
each Type.
Text Types
Name Size Known As
1 byte/8 bits
variousa c-string
Note
• The
type is the typical whole number type.
• The type is the typical real number type.
• C has limited support for text data. In most languages, text is represented using a
♠
+
type. The C text type is named
to indicate this limited support. C
includes a Library to add operations to manipulate
values.
• For example values see Table 2.4 on page 62.
64
2.3. PROGRAM CREATION IN C
*
c-string literal
single character
65
CHAPTER 2. PROGRAM CREATION
C comes with a range of libraries that provide reusable programming artefacts, including
reusable Procedures. The C library includes a number of different components, one of which
is - the standard input/output library. This header file gives you access to artefacts
you can use to perform input and output tasks, including code to write output to the Terminal.
The
procedure is used to write output data to the Terminal.
Procedure Prototype
Parameter Description
The text that is to be written to the Terminal. This
text may contain format tags to include other values.
See Figure 2.29 for the syntax of the format tag.
The syntax for the format tag is shown in Figure 2.29, with the details for the values that can
be placed in the flag, width, precision, and specifier section being shown in Table 2.8 on the
next page. A number of examples are shown in Table 2.8, as well as in Listing 2.8.
*
C++
7
%4
$
4
' 4
♢
7
7
Listing 2.8: C
examples
66
2.3. PROGRAM CREATION IN C
numbers
b
Shows a space if posi-
tive
Pad with 0’s rather
than spacesc
*
Precision Description Example Usage & Output
number For integers: same as
Width
For real numbers:
number of
values after the decimal
point
Table 2.8: Details for, and examples of, the format tag specifier, flag, precision, and width.
67
CHAPTER 2. PROGRAM CREATION
Comments allow you to embed documentation and explanatory text within your program’s
code. The comments are skipped by the compiler, so they have no affect on the program’s
machine code. You write comments to help other people understand what you intend the
program to do.
c comment ...
Note
• Figure 2.30 shows the syntax for comments in C++.
• In standard C++ the first style of comments must be used,
.
• Most modern C++ compilers also allow single line comments using
.
• Standard C++ comments can span multiple lines, these are also known as ‘block ♠
comments’.
• A compiler ignores comments when compiling your code.
• You can type almost anything in the comment, represented by the in the diagram.
*
68
2.3. PROGRAM CREATION IN C
The following list shows some of the more common errors you are likely to encounter at this
stage. The C compiler is particularly cryptic with its error messages, but these few should
help you with the more common problems.
Each statement in C must be ended with a semicolon (;). This error
is indicating that the compiler has reached a point where it believes
a statement should have ended. Look back at the previous line, it is
likely that you forgot to put the ending semicolon.
*
You are missing the return at the end of the main function. Add the
code
.
69
*
2.4. PROGRAM CREATION IN PASCAL
Section 2.2 on page 46 of this chapter introduced an ‘Output Test’ program, and its design.
The pseudocode from this section is shown in Listing 2.9. In this Section you will see the rules
for translating this program’s design into the C code shown in Listing 2.4.
Pseudocode
( ' ,
+
' '' , ( ' ,
♣
' ' '
' ' '
Listing 2.9: Pseudocode for Hello World program (from Listing 2.1).
Pascal
', / ,
( *
',
+ #
/$
'' , ( ' ♡
/ ' '
/$
/ ' '
/$
Listing 2.10: Output Test in Pascal
Note
• Save the Pascal code in a file named ', .
• Compile this using +
', .
• Run using ', .
• The code at the start is a Comment describing what is in the file, see Pascal Com-
♠
ments.
• Each of the procedure calls contains one or two Expressions that pass values to the
/$
procedure, which will output these to the Terminal.
• This code uses
,
, and types, see Pascal Types.
71
CHAPTER 2. PROGRAM CREATION
Figure 2.31 shows the structure of the syntax you can use to create a program using the Pascal
language.
uses clause
The code in Listing 2.11 shows an example Pascal Program. You should be able to match this
up with the syntax defined in Figure 2.31. Notice that the uses clause is skipped, this clause
allows you to access code in external libraries (called units in Pascal). By default all Pascal
programs have access to the + unit which contains the /$
procedure and many other
reusable artefacts.
( *
Pascal
/
+ #
♡
/$
' / '
Listing 2.11: Pascal Hello World
Note
• A Pascal Program starts at the first Statement after the program’s
keyword
(line 2).
• The program ends when the instructions get to the program’s
keyword (line 4). ♠
• The /$
procedure comes from a + unit (Pascal’s name for an external li-
brary) that is automatically include in each program.
72
2.4. PROGRAM CREATION IN PASCAL
In a Statement you are commanding the computer to perform an action. There are only a small
number of statements you can choose from. At this stage the only statement we have discussed
is the Procedure Call, formally known as the procedure statement in Pascal. This is shown in
Figure 2.24, where we can see that at this stage all Statements are calls to Procedures.
Pascal
#
+ #
!
/$
'/ #
''&'' '
/$
'/
' ♡
/$
' ''&'' ''(
''
''& '' '
/$
', #
/ + ''& ''
'
/$
'/
'
( *
Listing 2.12: Pascal Knights
Note
• The code in Listing 2.12 contains a Pascal Program.
• This Program contains five procedure calls. See Pascal Procedure Call.
♠
• Each procedure call runs the
procedure to output text to the Terminal. See
the section on Pascal Terminal Output.
73
CHAPTER 2. PROGRAM CREATION
A procedure call allows you to run the code in a procedure, getting its instructions to run
before control returns back to this point in the program.
argument
argument expression
Pascal
+ #
/$
'
'
♡
( *
/$
/$
/$
Listing 2.13: Pascal Count Back
Note
• A procedure call is an action which commands the computer to run the code in a
procedure.
• The procedure call starts with the procedure’s Identifier, this indicates the name of
the procedure to be called.
• Following the identifier is a list of values within parenthesis, these are the values
♠
(coded as Expressions) that are passed to the procedure for it to use.
• The code in Listing 2.13 contains a Pascal Program.
• This program contains four procedure calls.
• Each procedure call runs the /$
procedure to output text to the terminal. See
the section on Pascal Terminal Output.
74
2.4. PROGRAM CREATION IN PASCAL
The Pascal Identifier syntax is shown in Figure 2.34. In Pascal, as in most programming
languages, the identifier must start with an underscore ( ) or a letter; in other words your
identifiers cannot start with a number or contain other symbols. This is because the compiler
needs a way of distinguishing identifiers from numbers entered directly into the code.
identifier letter
letter
digit
letter
...
...
digit
( *
...
Note
• In the syntax definition an identifier cannot contain spaces, or special characters
other than underscores ( ).
• A letter is any alphabetic character (a to z and A to Z ).
♠
• A digit is a single number (0 to 9).
• Each item in Table 2.9 is a valid identifier.
• The keywords are identifier that has special meaning to the language.
75
CHAPTER 2. PROGRAM CREATION
7 !
8 !
5 !
1.5 +
1 !
1 !
2 !
1.5 +
1.5 +
6.5 +
Note
• Table 2.11 shows some example expressions, their values, and types.
• Expressions can be literal values, entered in the code.
♠
• Expression can contain mathematical calculations using standard addition, sub-
traction, multiplication, division, and grouping.
76
2.4. PROGRAM CREATION IN PASCAL
A literal is either a number or text value stated directly in the code. In other words, it is not
calculated when the program runs - it is already in the code. Figure 2.35 shows the syntax
for the different literal values you can enter into your Pascal code.
single digit
sign
sign
sign digits
( *
single char. any character except ’
character string
single character
Note
• ‘0..9’ means the digits 0, 1, 2, etc. up to 9.
• To embed a single quote (’) in a string you need to use two single quotes, for example ♠
/$
! .
77
CHAPTER 2. PROGRAM CREATION
Types are used to define how data is interpreted and the operations that can be performed on
the data. Table 2.12 shows the three basic types of data, the associated Pascal type, size in
memory, and other related information. Table 2.13 shows the operators that are permitted for
each type.
Text Types
Name Size Notes
1 byte/8 bits
+
256 bytes/2048 bits Supports up to 255 characters by default,
( *
Real Numbers
Note
• The !
type is the typical whole number type.
• The type is the typical real number type. ♠
• For example values see Table 2.11 on page 76.
78
2.4. PROGRAM CREATION IN PASCAL
Pascal comes with a range of libraries (called units in Pascal) that provide reusable program-
ming artefacts, including reusable Procedures. The + unit is automatically included in
all Pascal programs. This unit includes artefacts you can use to perform input and output
tasks, including procedures to write output to the Terminal.
Procedure Prototype
Parameter Description
The / procedure takes a variable number of pa-
rameters. Each of the parameters are written to the
Terminal in sequence. See notes for details on for-
matting numeric values.
Procedure Prototype
/$
Parameter Description
Works in the same way as /$
, but also advances
( *
to a new line after writing each parameter to the Ter-
minal.
Pascal
+ /$
+ #
/ ' '
/$
'/ '
/$
'+
$
' ' ♡
/$
'% ' $
'$
' $
'' '
/ ' '
/$
/$
'! '' '
Listing 2.14: Pascal
examples
Note
• Numeric values can be formatted using two format modifiers. You can specify the
minimum number of characters and the number of decimal places.
– To output with a minimum number of characters use -
.
∗ /$
This will write the text
to the Terminal.
♠
∗ /$
This will write the text
to the Terminal.
– To output with decimal places use -
.
∗ /$
This will write the text
to the Terminal.
∗ /$
This will write the text
to the Terminal.
79
CHAPTER 2. PROGRAM CREATION
Comments allow you to embed documentation and explanatory text within your program’s
code. The comments are skipped by the compiler, so they have no affect on the program’s
machine code. You write comments to help other people understand what you intend the
program to do.
{ ... }
Note
• Figure 2.36 shows the syntax for comments in Pascal.
• Block comments can span multiple lines.
♠
• You can type almost anything in the comment, represented by the in the diagram.
• A compiler ignores comments when compiling your code.
( *
80
2.5. UNDERSTANDING PROGRAM EXECUTION
The earlier Sections of this Chapter have covered the concepts and code related to program
creation, but have not looked at how these concepts actually affect the computer when the
program is run. This Section illustrates the actions that occur inside the computer when your
program is executed. A good understanding of these concepts work will enable you to use
them effectively.
This Section will help you answer the following questions:
• What happens when the program is started?
• What happens when the code executes a procedure call?
Double clicking a program’s icon, or launching it from the command line, causes the program
to run. This is as much as most normal users need to know about using programs. However,
as a Software Developer you need to know more about what is actually happening as you will
be the one who defines what the computer does when your program runs.
Starting a program is the responsibility of the Operating System. When the program is launched
the following steps are performed. A discussion of each of these steps follows.
1. Space is allocated in memory for the Program, and partitioned into areas for the program’s
code, and the call Stack.
2. The program’s code is loaded into memory, into the code Section.
3. A frame is added to the Stack with the location of the first instruction in the program.
4. The computer starts running the instructions based on the current frame in the stack.
81
CHAPTER 2. PROGRAM CREATION
To start the program the Computer first needs to get the program’s instructions into memory.
This task is performed by the Operating System when the program is launched. The Operating
System allocates memory for the program to use, and partitions this memory into different
areas. Each area will be used to store different kinds of information needed by the program.
An illustration of this is shown in Figure 2.37.
1 The Program's
Memory
Note
• In Figure 2.37 the indicated areas show the following:
1. The Operating System allocates memory for the program.
2. Part of the allocated memory will be designated to store the program’s instruc-
♠
tions. This can be thought of as the Code Area.
3. Another part of the allocated memory will be set aside to keep track of the cur-
rent instruction. This area is called the Stack.
82
2.5. UNDERSTANDING PROGRAM EXECUTION
Having allocated the program some memory, and partitioned this space into the Stack and
Code area, the Operating System then reads the program’s instructions from the executable
file and loads these into the Code area. This is illustrated in Figure 2.38.
Loads instructions
2
into Memory
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
3
----------------------------
Program: Output Test
----------------------------
Steps:
1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
Figure 2.38: The Operating System loads the program’s code into memory
Note
• In Figure 2.38 the indicated areas show the following:
1. The program’s instructions are read from the executable file the user launched.
2. The instructions are stored into the program’s memory: into the code area.
3. When this finishes, all of the program’s instructions are loaded into memory.
In Figure 2.38 the instructions are shown as the pseudocode from Listing 2.1.
In reality these will be the machine code instructions that were saved into the ♠
executable file by the compiler.
• The Operating System is a software component that is used to control access to the
hardware. In this case the Operating System takes the responsibility for setting up
the machine so that it can run the program the user launched.
83
CHAPTER 2. PROGRAM CREATION
Now that the code is loaded into memory, the Operating System uses the details saved in the
executable file to setup the program’s first instruction. This will be loaded onto the Stack,
which is responsible for keeping track of the current instruction. The compiler will have used
the program’s entry point to store these details when the program was compiled. This is
shown in Figure 2.39.
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
----------------------------
Program: Output Test
----------------------------
Steps:
Program / Main 1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
Instruction: Step 1 3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
2 This is called a
Stack Frame
Note
• In Figure 2.39 the indicated areas show the following:
1. The program’s instruction is tracked on The Stack.
2. Each Stack Frame keeps a record of the current instruction within a Procedure.
This area is called the Stack as the Frames are stacked one on top of the other.
The one on the top of the stack tells the computer which instruction is to be
run.
♠
• The Stack keeps track of the current instruction.
• The current instruction refers to the code loaded into the Code area.
• The compiler will have saved the details for which instruction is first into the exe-
cutable file.
• In your code the program’s entry point tells you which instruction will be first.
84
2.5. UNDERSTANDING PROGRAM EXECUTION
The Operating System has finally finished loaded the Program, and can now start its instruc-
tions running. The CPU uses the Current Instruction that is on the top of the Stack, locates
the Code, and runs the instruction. In this case this is a procedure call to a Procedure that
writes output to the Terminal. When this instruction completes, the text Output Test Program
will have appeared on the Terminal for the user to see. The results of this are shown in Figure
2.40.
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
----------------------------
Program: Output Test
----------------------------
Steps:
Program / Main 1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
Instruction: Step 1
3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
Figure 2.40: The Computer runs the first instruction, outputting details to the Terminal
Note
• In Figure 2.40 the indicated areas show the following:
1. The current instruction is read from the Frame on the top of the Stack.
2. The Computer runs the instruction from the code loaded into memory.
3. The instruction is a procedure call, which starts the execution of the Write Pro-
cedure.
♠
• The computer runs the code one instruction at a time.
• When that instruction is finished it moves onto the next instruction. This is impor-
tant, and means that are programs run the commands in Sequence.
• Writing data to the Terminal takes more than a single instruction, the procedure call
gets the Computer to run the instructions in the called Procedure.
85
CHAPTER 2. PROGRAM CREATION
At this point the Computer has been instructed to / (. This procedure8
will output the data passed to it to the Terminal. In order to do this, the instructions within
the called procedure need to be followed.
Each Procedure contains instructions that when followed get the Computer to perform a task.
The procedure call sets up the Stack so that the instructions within the Write Procedure are
executed.
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
Write Procedure
----------------------------
Instruction: Step 1
Program: Output Test
----------------------------
Steps:
Program / Main 1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
Instruction: Step 1 3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
Figure 2.41: The Write Procedure is called, and has its instructions executed
Note
• In Figure 2.41 the indicated areas show the following:
1. A new Frame is added to the Stack for the Write Procedure.
2. The new Frame appears on top of the Frame that has the program’s Current
Instruction. ♠
3. Now the Computer can run the instructions within the Write Procedure.
4. The instructions are run one at a time until the Write Procedure finishes. At
this time the first output will have appeared on the Terminal.
86
2.5. UNDERSTANDING PROGRAM EXECUTION
When the Write Procedure’s instructions finish control needs to return to the code that called
it, in this case the program’s code.
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
----------------------------
Program: Output Test
----------------------------
Steps:
Program / Main 1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
Instruction: Step 2 3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
Figure 2.42: The Write Procedure is called, and has its instructions executed
Note
• In Figure 2.42 the indicated areas show the following:
1. When the Write Procedure finishes its Frame is removed from the Stack, and
control returns to the program’s code. ♠
2. The first instruction on the program’s code has now finished, so the Computer
moves to the second instruction.
One way to visualise this is to picture the Program, and the Procedure, as a book of instruc-
tions. Imagine you are told to follow the instructions in a book. You get the book, place it on a
table and read the first instruction which tells you to perform the Write Procedure. You leave
the original book on the table, and fetch the Write Procedure book and place it on top of the
book on the table, thereby creating a Stack of books. Now you can follow the instructions,
one by one, from the book on top of the Stack. When you finish the last instruction you take
the book off the top of the stack and return to the book beneath it. This will enable you to
perform the steps within the Procedures without forgetting where you are up to in the earlier
code.
87
CHAPTER 2. PROGRAM CREATION
The second instruction in the program’s code is another call to the Write procedure.
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
Write Procedure
Instruction: Step 1 ----------------------------
Program: Output Test
----------------------------
Steps:
Program / Main 1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
Instruction: Step 2
3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
Note
• In Figure 2.43 the indicated areas show the following:
1. A new Frame is created for the Write Procedure. This allows the Computer to
keep track of which statement is the current statement within this Procedure.
2. The program’s current instruction remains on the Stack for when the call to the
♠
Write procedure finishes.
3. Each of the instructions in the Write procedure are executed to write the data
to the Terminal.
4. The output text appears on the Terminal.
88
2.5. UNDERSTANDING PROGRAM EXECUTION
When the second call to Write ends control returns to the Program, which moves on to its final
instruction.
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
----------------------------
Program: Output Test
----------------------------
Steps:
Program / Main 1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
Instruction: Step 3 3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
Figure 2.44: The second call to the Write Procedure ends, and control returns to the Program
Note
• In Figure 2.44 the indicated areas show the following:
1. When the second call to the Write Procedure ends control returns to the pro-
gram’s code. ♠
2. As the second instruction has now finished the Computer moves to the third,
and final, instruction in the program.
89
CHAPTER 2. PROGRAM CREATION
The final instruction in the program is a third call to the Write Procedure.
----------------------------
Procedure: Write Procedure
----------------------------
Steps:
1: ...
Write Procedure
Instruction: Step 1 ----------------------------
Program: Output Test
----------------------------
Steps:
Program / Main 1: Output 'Extended Hello World' to the Terminal
2: Output ' 1 + 1 = ', and the result of 1 + 1
Instruction: Step 3
3: Output ' Area of a circle with radius 3 = ',
and the result of 3.1415 * 3 * 3
Figure 2.45: The Write Procedure is called a third can final time
Note
• In Figure 2.45 the indicated areas show the following:
1. Once again, a Stack Frame is created to keep track of the progress within the
Write Procedure.
2. The program’s current instruction remains on the Stack so that the Computer ♠
can return to it when the Write Procedure ends.
3. Each of the instructions in the Write Procedure are executed.
4. The Write Procedure writes the data passed to it to the Terminal.
90
2.5. UNDERSTANDING PROGRAM EXECUTION
When the last instruction in the Write Procedure finishes control return back to the Program,
which has no more instructions. This means that the program has finished.
Figure 2.46: The Write Procedure ends, then the program ends
Note
• In Figure 2.46 the indicated areas show the following:
1. The Write Procedure has finished its instructions, and so it ends. This was
also the last instruction in the program’s code, so it also ends. This tells the
Operating System that Program has finished.
♠
2. The Operating System releases the memory used by the program so that it can
be use by other programs.
3. All of this will have happened in an instant, and after the program has finished
all that remains is the output in the Terminal.
91
CHAPTER 2. PROGRAM CREATION
2.5.3 Summary
In this section you have seen the actions that occur behind the scenes when your program is
executed. The most important aspects are the fact that the instructions run one at a time in
sequence, and that a procedure call results in the instructions within the Procedure running
until they end. Its also important to remember that the instructions within the Procedure
must finish before control returns to where the call was made.
Note
• A Program is a sequence of instructions.
• These instructions are organised into Procedures that can be called.
• The program’s instructions are loaded into memory when the program is launched.
• Instructions are run one at a time.
• The Stack is used to keep track of the current instruction. ♠
• When the program starts a Frame is added to the Stack to set the entry point as the
first instruction.
• When a Procedure is called, a Frame is added to the Stack to keep track of its current
instruction.
92
2.6. PROGRAM CREATION EXAMPLES
This program prints out the seven times table from 1 x 7 to 10 x 7. The description of the
program is in Table 2.16, the pseudocode in Listing 2.15, the C code in Listing 2.16, and the
Pascal code in Listing 2.17.
Program Description
Name Seven Times Table
Pseudocode
( +
,,
+
' '+
, , ' ,
' '' ,
' ' '
,
' '
'
,
' ' '
,
' ' '
,
♣
' '
'
,
' ' '
,
' ' '
,
' ' '
,
' ' '
,
' ' '
,
' '' ,
Listing 2.15: Pseudocode for Seven Times Table program.
93
CHAPTER 2. PROGRAM CREATION
C++
(
7
+
, ,
+
, , 4
4
4
4
4
♢
4
4
4
4
4
4
4
4
Listing 2.16: C Seven Times Table
Pascal
( +
,,
+
, ,
+
,,
/$
'+
, , '
/$
''
/$
' '
/$
'
'
/$
' ' ♡
/$
' '
/$
'
'
/$
' '
/$
' '
/$
' '
/$
' '
/$
' '
/$
''
Listing 2.17: Pascal Seven Times Table
94
2.6. PROGRAM CREATION EXAMPLES
This program prints out the area of circles with different radius. The description of the program
is in Table 2.17, the pseudocode in Listing 2.18, the C code in Listing 2.19, and the Pascal
code in Listing 2.20.
Program Description
Name Circle Areas
Description Displays the Circle Areas for circles with radius from 1.0 to
5.0 with increments of 0.5.
Pseudocode
(
+
' ' ' ,
' '' ,
' ' * '
,
' ' *
'
,
' ' *
'
,
♣
' ' *
'
,
' ' * '
,
' ' *
'
,
' ' * '
,
' ' *
'
,
' ' *
'
,
' '' ,
Listing 2.18: Pseudocode for Circle Area program.
95
CHAPTER 2. PROGRAM CREATION
C++
( 7
4
4
*
4
*
4
♢
*
4
*
4
*
4
*
4
*
4
*
4
*
4
4
Listing 2.19: C Circle Areas
Pascal
( 7
96
2.6. PROGRAM CREATION EXAMPLES
This program draws some shapes to the screen using the SwinGame Software Development
Kit (SDK). The SwinGame SDK is a library that provides a number of reusable code artefacts
that you can use to create 2D games. This SDK is available for both C and Pascal, and work
on Linux, Mac, and Windows.
The description of the program is in Table 2.18, the pseudocode in Listing 2.21, the C code in
Listing 2.22, and the Pascal code in Listing 2.23.
Program Description
Name Shape Drawing
Pseudocode
( +
+
'
/
'+
'
+
*
/
*+
*
♣
*+
,
1
*+
* *
Listing 2.21: Pseudocode for Shape Drawing program.
97
CHAPTER 2. PROGRAM CREATION
C++
( 7
+
+
7 7
+
7 7
7
7
♢
7 *
7
7
7
7 7
Listing 2.22: C Shape Drawing Code
The SwinGame procedure for C are named using the standard C naming scheme. The names
are:
•
opens a Window with the title ‘Shape Drawing’ that is 800 pixels
wide by 600 pixels high.
• loads default colors for use in your code.
•
clears the screen to black.
•
uses the color, the x, y location, and width and height to fill a rectangle.
•
updates the screen to show what has been drawn. All SwinGame drawing
is done offscreen, and only drawn to the screen when RefreshScreen is called.
• pauses the program for a number of milliseconds, so 500 will wait for half a second.
• uses the color, given x, y location and radius to fill a circle.
•
fills a triangle with the given x, y points (6 values for 3 points).
98
2.6. PROGRAM CREATION EXAMPLES
Pascal
( +
+
%
, !
* - ,
'
/
'+
'
+
*+
♡
*
*+
* *
Listing 2.23: Pascal Shape Drawing Code
99
CHAPTER 2. PROGRAM CREATION
Read over the concepts in this chapter and answer the following questions:
1. What is a Program? What does it contain?
2. A program is an artefact, something you can create in code. Why would you want to
create a program your code?
3. What is the entry point of a program?
4. Do you have to write all of the code for your program, or are you able to use artefacts
from elsewhere?
5. What is a Statement?
6. What statement was introduced in this chapter?
7. What is a Procedure?
8. Where can you find procedures you may be interested in using?
9. What is an Expression?
10. Where are expressions coded? Give an example of an expression being used in code.
11. What are the three broad kinds of Types that a language will provide?
12. What are the names of the types in the language you are using? Name the main type you
are likely to work with for each of the broad kinds of types.
13. What are the values of the following expressions? Which types could these values be
used with (possibly multiple)? Note: some answers are dependent of the language you
are using.
%
/'/ ''$
100
2.7. PROGRAM CREATION EXERCISES
Program Description
Name Five Times Table
2. Write a program that prints the powers9 of 2 from 21 to 28 . See Table 2.20.
• Think about the artefacts you will create, and use.
• Write pseudocode for the program’s instructions
• Convert your pseudocode to either C or Pascal
• Compile and Run your program, and check that the values are correctly calculated
Program Description
Name Powers of Two
3. Write a program that prints the 73 times table from 1 * 73 to 10 * 73. See Table 2.21.
• Think about the artefacts you will create, and use.
• Write pseudocode for the program’s instructions
• Convert your pseudocode to either C or Pascal
• Compile and Run your program, and check that the values are correctly calculated
Program Description
Name Seventy Three Times Table
9 In the code you will need to calculate these manually using times (21 = 2, 22 = 2*2, 23 = 2*2*2, etc.)
101
CHAPTER 2. PROGRAM CREATION
4. Write a program that prints a table showing calculations of circle dimensions. This
should output the radius, circle area, diameter, and circumference of circles with a radius
of 1cm, 1.5cm, and 2cm. See Table 2.22.
• Find the necessary calculations and think about the artefacts you will use and cre-
ate.
• Write pseudocode for the program’s instructions.
• Convert your pseudocode to either C or Pascal.
• Compile and Run your program, and check that the values are correctly calculated.
Program Description
Name Circle Dimensions
Description Displays a table of circle dimensions for circles with a radius of 1cm,
1.5cm, and 2cm. This will output the radius, circle area, diameter, and
circumference of circles.
5. Write a program with SwinGame that draws a face using primitive shapes. See Table 2.23.
• Draw up an outline of the program. Work out the coordinates of the circles for the
face, circles. Determine three points of the triangle for the mouth.
• Write up the pseudocode for the program’s instructions. Remember to use the
*+
and procedures to see the results.
• Convert your pseudocode to either C or Pascal
• Compile and Run your program, and check that the values are correctly calculated
Program Description
Name Face Shape
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. C and Pascal are imperative programming languages. What does this mean, and how
does it relate to the way you think about code?
2. Artefacts are things that you can create. What artefacts where introduced in this chapter?
If you could create these artefacts, what would you do with them?
102
Procedure Declaration
3
our spell casting is really coming along. As you know, your spells
contain a sequence of incantations. I will now tea you a tenique
to combine incantations into groups. This will make your spells faster
to cast, and easier to use. Now get your wand, and try casting your spell like
this. . .
Programs contain a sequence of instructions, with each instruction commanding the computer
to perform an action. While it is possible to have just a single long list of instructions, this
quickly becomes difficult to understand, hard to extend, and frustrating to maintain. Rather
than coding all of a program’s instructions in a single list, Software Developers arrange a
program’s instructions in meaningful groups that can be called when those steps need to be
performed. These groups are called Procedures. Within a Program, each Procedure is designed
to get the computer to perform a single task, and therefore only contains the instructions
related to that task.
When you have understood the material in this chapter you will be able to create and call
simple Procedures of your own creation. This will help make your programs faster and easier
to write.
Contents
3.1 Procedure Declaration Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . 105
3.1.1 Program (with Procedures) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
3.1.2 Procedure Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
3.1.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
3.2 Using these Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
3.2.1 Designing Morse Calling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
3.2.2 Understanding Morse Calling . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.2.3 Choosing Artefacts for Morse Calling . . . . . . . . . . . . . . . . . . . . . . 111
3.2.4 Writing the Code for Morse Calling . . . . . . . . . . . . . . . . . . . . . . . 113
3.2.5 Compiling and Running Morse Calling . . . . . . . . . . . . . . . . . . . . . 114
3.3 Procedure Declarations in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
3.3.1 Implementing Morse Calling in C . . . . . . . . . . . . . . . . . . . . . . . . 115
3.3.2 C Program (with Procedures) . . . . . . . . . . . . . . . . . . . . . . . . . . 117
3.3.3 C Procedure Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
3.4 Procedure Declarations in Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . 121
3.4.1 Implementing Morse Calling in Pascal . . . . . . . . . . . . . . . . . . . . . 121
3.4.2 Pascal Program (with Procedures) . . . . . . . . . . . . . . . . . . . . . . . 123
3.4.3 Pascal Procedure Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . 124
3.5 Understanding Procedure Declaration and Calls . . . . . . . . . . . . . . . . . 126
103
CHAPTER 3. PROCEDURE DECLARATION
104
3.1. PROCEDURE DECLARATION CONCEPTS
Chapter 2 Program Creation introduced the idea of creating your own Programs as a sequence
of instructions, Statements. The instructions in these programs called existing Procedures
that performed tasks for the program. The code you wrote sequenced these procedures to
produce a desired output.
As you learnt in Chapter 2, Procedures are designed to perform a single task that can be called
when you want that task performed. Using Procedures from Libraries is an important task,
but what about the tasks related to the program we are creating? Can we create our own
procedures that help us to model the actions we want performed in the code?
The simple answer is yes. Yes you can, and should, create your own procedures. These pro-
cedures enable you to model the processes related to your program, capturing the individual
tasks in the Procedures your create.
In this Chapter you will learn how to create the following programming artefacts:
• Program (with Procedures): Lets you create Procedures in your program’s code.
• Procedure Declarations: Declare the actions the Procedure will perform.
105
CHAPTER 3. PROCEDURE DECLARATION
Each Program is a list of instructions (Statements) that command the computer to perform
actions. Unfortunately the computer is only able to perform simple actions, meaning that even
small programs need many instructions in order to perform their tasks. To help manage these
instructions you can group the program’s Statements into Procedures, creating Procedures
that perform the tasks you need completed in your Program.
Library
Declares the code
the compiler turns
into an executable file May use procedures Has a name
from Libraries that is an
Program Identifier
Procedure
Procedure
Procedure
Instruction 1
A Program may declare Instruction2 1
Instruction Parameter
its own Procedures. Instruction
Instruction
Instruction 32 1 Parameter
Instruction
Instruction
Instruction 43 2 Parameter
Instruction
Instruction
Instruction 54 3 Parameter
Instruction
Instruction
... 5 4 Parameter
Instruction
... 5 Parameter
...
Instruction 1
Instruction 2
...
The Program has an
Each instruction is a entry point
Statement Statement commanding that indicates where
the computer to perform the program's
an action instructions start
Note
• A Program is an artefact that you can create in your code.
• A Program can contain a number of Procedures.
• Procedure Declarations allow you to create your own Procedures.
♠
• The program’s instructions can call the Procedures you create in the program’s code.
• In C and Pascal the Procedure Declarations must appear before they are used in
your code.
106
3.1. PROCEDURE DECLARATION CONCEPTS
Procedures contain code that define the steps the computer performs when the procedure is
called. In your Program you can define your own Procedures, allowing you to divide a program’s
tasks into separate Procedures.
Performs a task
Has a Side Effect Has a name Accepts values
that is an that it needs to
perform its task
Procedure Identifier
Contains instructions
Statement
Instruction 1 Parameter
Instruction 2
Each instruction is a Instruction 3
Statement commanding Parameter
the computer to perform Instruction 4
an action Instruction 5
...
Passes in
Values
Starts the
Program
Note
• A Procedure is an artefact that you can create and use in your code.
• Each Procedure contains code to perform a certain task. When you want the task
performed you call the Procedure.
• Procedures should have a side effecta , meaning that it changes something when it
is executed.
• The Procedure’s declaration defines its name, and the steps it performs.
• Each instructions in the Procedure is a Statement.
• The Procedure’s Identifier:
– Is the name used to call the Procedure. ♠
– Should be a verb that reflects the task the Procedure performs.
• When the Procedure is called its instructions are executed.
• Each Procedure’s instructions are isolated from the other code in your Program.
When you are working on a Procedure you do not need to know about the internal
workings of the other procedures.
a Output to the Terminal is an example of a Side Effect. After calling these procedures the text you wanted to
appear was written to the Terminal. These Procedures changed the Terminal.
107
CHAPTER 3. PROCEDURE DECLARATION
3.1.3 Summary
This section has introduced you to the idea of creating and using your own Procedures. The
concepts related to this are shown in Figure 3.4. The next section will examine how these
concepts can be used to design the Morse Code program.
Program
Procedure
Has a name
that is an
Each instruction is a
Calls a Statement
Identifier
Action
Term
Term Is a kind of
Procedure Call
Note
• Artefacts are things you can create and use.
• Terms are things you need to understand. ♠
• Actions are things you can command the computer to perform.
108
3.2. USING THESE CONCEPTS
Procedures give us a means of modelling the tasks we want the computer to perform. Rather
than just having a long list of instructions, we can create procedures that contain the steps
needed to perform individual tasks that the program must carry out. The program’s instruc-
tions can then be very simple, just calling the procedures that we have written to carry out
the tasks as needed.
Table 3.1 contains a description of the next program we are going to design. This program will
output a message in Morse Code to the Terminal. In designing this program we will make use
of the concepts introduced in this chapter; we will divide the program’s code into a number of
procedures each with the instructions to get the computer to perform a single task.
Program Description
Name Morse Calling
Description Displays the morse code for ‘Calling Anyone’ on the Termi-
nal.
109
CHAPTER 3. PROCEDURE DECLARATION
A K U 4
B L V 5
123
D N X 7
E O Y 8
j T !
F P Z 9
G Q 0 .
H R 1 ,
I S 2 ?
J T 3 !
code to signal C and Q. This means that the program needs to output the signals
signals for C and Q), see Table 3.2.
CQ
With some additional searching you can also find that the signal for ‘Calling Anyone’ is the
(the
As you read through this information its important to try and identify the tasks that the
program will need to perform. These tasks can then be modelled in the program’s code. The
following list outlines the tasks that can be identified in the above descriptions. Read back
over the text and make sure you can see where each of these can be identified.
• Perform a Short Signal (a dot)
• Perform a Long Signal (a dash)
• Signal the Character C
• Signal the Character Q
When you design the solution for this program you will be able to use this information to
determine what needs to be created, and the tasks that each of these performs.
• Perform Short Signal will output a dot (.) to the Terminal.
• Perform Long Signal will output a dash (-) to the Terminal.
• Signal C will perform a Long Signal, then a Short Signal, then a second Long Signal,
and a second Short Signal. This will end by printing a space to separate it from the next
character.
• Signal Q will perform a Long Signal, a second Long Signal, a Short Signal, and then a
third Long Signal. This will end by printing a space to separate it from the next character.
110
3.2. USING THESE CONCEPTS
Having finished the analysis of the problem, the next step is to design the solution. This
will involve determining which programming artefacts you will need to build, and the which
programming artefacts exist for you to use.
• Create a program the user can execute. This will signal C and Q using Morse Code.
Within this program there are several sub-tasks that can be coded into their own proce-
dures.
– Short Signal - Morse Code needed the ability to perform a short signal. The in-
structions for this can be coded into a Short Signal procedure. In this case that will
output a dot (.) to the Terminal.
– Long Signal - Similar to the Short Signal, this procedure will contain the instruc-
tions needed to perform a Long Signal, in this case this will output a dash (-) to the
Terminal.
– Signal C - This task will contain the instructions needed to get the computer to signal
the character C. Internally this can call the Short Signal and Long Signal procedures.
– Signal Q - Similar to the Signal C, this procedure will contain the instructions needed
to signal the character Q. Internally it will use the Short Signal and Long Signal
procedures.
• The following procedures already exist and can be used to help implement the procedures
mentioned above:
– The language provides a procedure to write data to the Terminal.
C++
In C the procedure to write data to the Terminal is the
procedure from . ♢
Pascal
In Pascal there are two procedures to write data to the Terminal, / and /$
. ♡
The pseudocode for the Morse Calling program is shown in Listing 3.1, with pseudocode for
the Signal C procedure in Listing 3.2, Signal Q in Listing 3.3, and Listing 3.4 showing the
pseudocode for the Short Signal procedure.
Note
Have a look over the procedures and the Morse Calling Program and note the following
things:
• The procedures appear within the program.
• The name of the procedure indicates what it does.
• + +
is called by the +
and +
) procedures.
♠
• + +
is not directly called by the program.
• The +
Procedure calls the $
+
and + +
procedures.
• In the C or Pascal code, the Procedure’s declaration must appear before its use, so
+ +
and $
+
will need to appear at the top of the code, +
and +
) in the middle, and the program’s instructions at the end.
111
CHAPTER 3. PROCEDURE DECLARATION
Pseudocode
( %
(
+ +
$
+
+
+
)
♣
(
%
+
+
+
)
'
,
Listing 3.1: Pseudocode for Morse Calling program.
Pseudocode
( +
+
$
+
+ +
♣
$
+
+ +
' ' ' ,
Listing 3.2: Pseudocode for the Signal C procedure.
Pseudocode
( +
)
+
$
+
$
+
♣
+ +
$
+
' ' ' ,
Listing 3.3: Pseudocode for the Signal Q procedure.
112
3.2. USING THESE CONCEPTS
Pseudocode
( + +
+ ♣
' '' ,
Listing 3.4: Pseudocode for the Short Signal procedure.
Pseudocode
( $
+
+ ♣
' '7' ,
Listing 3.5: Pseudocode for the Long Signal procedure.
The pseudocode from section 3.2.3 Choosing Artefacts for Morse Calling shows the instruc-
tions, and how these should be divided between a number of custom created procedures.
At this stage these instructions need to be translated into source code, so that they can be
compiled and the resulting program tested.
The following two sections, Section 3.3 Procedure Declarations in C and Section 3.4 Procedure
Declarations in Pascal, contain a description of the syntax needed to create programs in the
C and Pascal programming languages that include Procedure declarations.
Each of these sections will contain extended program declaration rules that show you where
the Procedure Declarations can be coded, along with the rules for how Procedure Declarations
should appear.
Note
Remember the basic process for reading the Syntax Diagrams is to:
1. Find the page with the Syntax rule you are interested in knowing about.
2. Have a quick look at the Syntax Diagram and the rules it contains. Read each rule,
and get a basic feel for how it is going to come together for your program.
3. Read the example to see one way of using the Rule. The Syntax Diagram can be
used to create any number of variations of the rule, the example gives you at least
one way these rules can be coded. ♠
4. Return to the diagram and make sure you can match each part of the example back
to the rule that created it.
5. Now look up any related rules that are not explained on this rule’s page. For example,
a Program (with Procedures) uses the Procedure Declarations rule, you will need to
read this rule to determine how to declare the Procedures you want to create in the
code.
113
CHAPTER 3. PROCEDURE DECLARATION
Once you have completed your program, you need to compile and test it.
1. Open the Terminal1 program for your Operating System
2. Use the command to move to the directory with your code, for example
-
3. Run the compiler with your program’s code. See the language specific details below.
4. Fix any compiler errors, using the tips from Section 2.2.5 Compiler Errors.
5. Execute the program using %
and check the results
C++
The C compiler is called gcc. To compile your Morse Calling program you will need to run
the following:
♢
%
Pascal
The Pascal compiler is called fpc. To compile your Morse Calling program you will need
to run the following:
♡
+
%
114
3.3. PROCEDURE DECLARATIONS IN C
Section 3.2 of this chapter introduced the ‘Morse Calling’ program, and its design. Its im-
plementation requires the definition of some procedures in the program’s code. This section
of the chapter introduces the C syntax rules for declaring your own procedures, with the C
implementation of Morse Calling being shown in Listing 3.6.
C++
(
'
*
7
7
♢
7
7
7
7
7
7
7
7
7
7
4
Listing 3.6: C Morse Calling
115
CHAPTER 3. PROCEDURE DECLARATION
Note
• Save the C code in a file named
.
• Compile this using %
.
• Run the resulting program using %
.
• Check that the output matches the expected values.
• Looking over the code you should be able to see the instructions for each Procedure.
• Notice how the indentation makes it easy to see where each Procedure starts and
ends. Always lay your code out so that it is easy to see its structure. ♠
• See how the procedures are declared before they are used. This is important as the
C compiler must know about the Procedure before you can call it.
• To see how to create this have a look at the Syntax for declaring C Program (with
Procedures).
• The program’s declaration can contain a number of Procedures using the C Proce-
dure Declaration syntax.
*
116
3.3. PROCEDURE DECLARATIONS IN C
The C code for a Program contains the program’s instructions in
, along with your proce-
dure declarations.
header include
declarations
procedure declaration
block { }
statement
*
Figure 3.5: C++ Syntax for a Program (with procedures)
C++
(
' ' ' ,
7
4
7
7
77
7
Listing 3.7: Is Anyone There?
117
CHAPTER 3. PROCEDURE DECLARATION
Note
• The header includes, main function, and block are all the same as previously seen.
– The header include gives you access to the Standard IO library.
– The main function is the entry point for your program, it contains the instruc-
tions that are followed when the program is launched.
– The block contains the instructions used within the
function.
• You can place declarations after the header includes and before the main function.
• The declarations can contain any number of procedure declarations. See C Procedure ♠
Declaration for details on this code.
• The code in Listing 3.7 shows a Program with two procedures: and
.
• Notice that these procedures are declared after the header include
and before the main function.
*
118
3.3. PROCEDURE DECLARATIONS IN C
block { }
statement
C++
(
7
(
*
4
(
4
7 77
7
Listing 3.8: Cooking a Meal
119
CHAPTER 3. PROCEDURE DECLARATION
Note
• There are three Procedures declared in the code in Listing 3.8.
• A Procedure Declaration starts with the word . This indicates that the following
code is a procedure declaration to the compiler.
• The Procedure Name is an identifier. It is the name of the Procedure. This can be
any valid C Identifier that has not been used before.
• The empty parenthesis must appear after the procedure’s name, and before the block.
• The block should look familiar. This is the same as was used in the main function
♠
of the program to define its instructions, and is used for the same purpose within
the Procedure Declaration.
• There are a number of conventions, called coding standards, that describe how your
code should appear for a given language. In this text we will use a common C con-
vention of having all Procedure Names in lower case, with underscores ( ) used to
separate words. So the Get Ingredients procedure becomes
.
*
120
3.4. PROCEDURE DECLARATIONS IN PASCAL
Section 3.2 of this chapter introduced the ‘Morse Calling’ program, and its design. Its imple-
mentation requires the definition of some procedures in the program’s code. This section of
the chapter introduces the Pascal syntax rules for declaring your own procedures, with the
Pascal implementation of Morse Calling being shown in Listing 3.9.
Pascal
'
'
'
%
( *
/ ''
+
/ ' '
$
+
++
$
+
++
♡
+
)
/ ' '
$
+
$
+
++
$
+
%
+
+
)
/$
%
Listing 3.9: Pascal Morse Calling
121
CHAPTER 3. PROCEDURE DECLARATION
Note
• Save the Pascal code in a file named %
.
• Compile this using +
%
.
• Run the resulting program using %
.
• Check that the output matches the expected values.
• Looking over the code you should be able to see the instructions for each procedure.
• Notice how the indentation makes it easy to see where each procedure starts and
ends. Always lay your code out so that it is easy to see its structure. ♠
• See how the procedures are declared before they are used. This is important as the
Pascal compiler must know about procedures before you can call them.
• To see how to create this have a look at the syntax for declaring Pascal Program (with
Procedures).
• The program’s declaration can contain a number of procedures using the Pascal
Procedure Declaration syntax.
( *
122
3.4. PROCEDURE DECLARATIONS IN PASCAL
The Pascal code for a program contains the program’s instructions, along with your own pro-
cedure declarations.
uses clause
Pascal
( *
+ ( ' ' ' ,
+
/$
' '
%
Listing 3.10: Is Anyone There?
Note
• Within your program you can declare your own procedures.
• See Pascal Procedure Declaration for the syntax to declare your own procedures.
• Listing 3.10 shows a program with three procedures: %
, + , and ♠
+ !
, .
• Procedures are declared between the program’s header and the program’s statements.
123
CHAPTER 3. PROCEDURE DECLARATION
Pascal
/$
(
%
/ ,
!
%
Listing 3.11: Cooking a meal
124
3.4. PROCEDURE DECLARATIONS IN PASCAL
Note
• There are four procedures declared in the code in Listing 3.11.
• A procedure declaration starts with the word . This indicates to the com-
piler that the following code is a procedure declaration.
• The procedure’s name is an identifier. This can be any valid Pascal Identifier that
has not been used before.
• The empty parenthesis must appear after the procedure’s name, and before the semi-
colon and the block. ♠
• There are a number of conventions, called coding standards, that describe how your
code should appear for a given language. In this text we will use a common Pascal
convention of having all procedure names in Pascal Case, this uses an uppercase
character for the first letter of each word in the identifier. So the Get Ingredients
procedure becomes !
.
( *
125
CHAPTER 3. PROCEDURE DECLARATION
This Chapter has introduced the idea of creating Procedures within your program’s code. These
procedures can be used to implement the different tasks that you want your program to per-
form.
This Section will help you answer the following questions:
• How can I visualise the Procedures within a program?
• What happens when my Procedures are called?
When you are writing the code, the internal details of how a Procedure works are important.
But, it is equally important to be able to picture how these procedures interact within the
program as a whole. One technique for visualising this is to draw a Structure Chart.
A Structure Chart is a diagram that has two elements: rectangles representing the procedures
in your code, and arrows representing calls. The Structure Chart for the Morse Calling program
is shown in Figure 3.9. In this you can see that the Morse Calling program has four main
procedures that implement its functionality, in addition to the program’s main logic: the +
, +
), $
+
, and + +
procedures. It also shows that the program’s main
logic calls +
and +
), that +
calls $
+
and + +
, as does
+
).
Main
Signal C Signal Q
The rectangles in the Structure Chart represent the Procedures. As the name of the proce-
dure should reflect its task/actions this means that the reader of the diagram can get some
insight into what the program is doing, and how it is achieving its tasks. From Morse Calling’s
Structure Chart you can see that the program is Signalling the character’s C and Q, which
internally use Long and Short signals to achieve their tasks.
The arrows in the Structure Chart show procedure calls. The arrow from the +
proce-
dure to $
+
tells us that somewhere in the code for +
there is one or more calls
126
3.5. UNDERSTANDING PROCEDURE DECLARATION AND CALLS
to $
+
. There is no indication of the order, or frequency, of these calls. Its just simply
saying that +
calls $
+
.
The Structure Chart is useful for getting an overall picture of how the program is structured. It
can help the designer communicate such things as What Procedures are there in this program?
and How are these Procedures related to each other? It helps developers new to the project
to get a feeling for how the code is distributed within the solution, and to know where the
core logic can be found. It also provides a means of determining the impact of changing the
functionality of the tasks in the program. For example, if you change how $
+
works
that may impact on +
and on +
). Any changes you made here would mean you
needed to test that +
and +
) still worked as expected.
The Structure Chart is a great communication tool for getting an overall picture of how a
solution fits together, but it only shows the static structure. Communicating things about
the code, but not things about how the code executed. An effective designer will want to
communicate both the static structure, as well as the dynamic behaviour of the solution. To
communicate these details you need to look for complementary techniques.
The Structure Chart communicates the static structure of the solution, showing the Proce-
dures and their relationships but lacking any details on how this structure works dynamically.
This dynamic information can be captured in a Sequence Diagram, which works together
with the Structure Chart to complete the overview of the program’s structure and dynamic
behaviour.
Figure 3.10 shows the Sequence Diagram for the Morse Calling program. This shows the pro-
cedure calls that will occur within an execution of the program’s code. The Sequence Diagram
shows the order in which procedure calls occur, with time travelling down the page and the
calls travelling across.
You start reading this diagram from the top, with each arrow representing the call to a Proce-
dure, and the thin vertical rectangles representing the time taken for the called procedure to
complete its task. Reading the Sequence Diagram for Morse Calling you can see that the first
thing to occur is the %
body of the program’s code is started. The arrow from the far left
indicates that something, in this case being the user launching the program, starts this code
running.
The first thin vertical rectangle is the program’s main instructions, and its first action is to call
+
as shown by the arrow pointing to the second vertical bar. This is our first procedure
call, the program’s instructions call +
. Notice that at this point there are two vertical
bars. These represent the two frames on the Stack, and show us that when +
finishes
the execution will return to the program’s main instructions.
Within +
the first action is to call $
+
, as shown be the arrow. Time-wise
this is the second procedure call. First the Main code called +
, which in turn called
$
+
. The details on the diagram show us that $
+
does not call any other
procedures that we created. Notice that we have avoided putting in the call to the output
procedure to allow us to focus on the Procedures we have created. At this point there are three
frame’s on the Stack, the first for the %
code, second for +
, and third for $
+
.
You can see these if you turn your head on the side. Notice the notice that the vertical bars
will mirror the stack.
As $
+
does not call any other Procedures that we created there are no calls coming
out from this procedure’s execution. The actions within this code will be performed, and then
$
+
will end. This is shown by the ending of the vertical bar, and a dashed returning
arrow showing where the code returns to. This tells us that when $
+
ends at this
point, the computer returns to execute the next instruction in +
.
127
CHAPTER 3. PROCEDURE DECLARATION
Main
Signal C
Long Signal
Short Signal
Long Signal
Short Signal
Signal Q
Long Signal
Long Signal
Short Signal
Long Signal
The next instruction in +
is the call to + +
. Once again this is shown with
the calling arrow, and a vertical bar is added to show the steps of the + +
executing.
+ +
does not call any other Procedures we created so it ends without any additional
calls occurring, and control returns to +
.
This process continues, with the diagram showing that $
+
is called again followed by
a call to + +
, and then +
ends. At this point control returns to the program’s
main code, where the next call starts +
) running. Within +
) you can see two calls
to $
+
, followed by a call to + +
, and a final call to $
+
. When the
final call to $
+
ends this marks the end of the +
) procedures, and the end of
the program’s instructions as a whole.
As you can see from the above text the Sequence Diagram communicates a large amount of
detail in a relatively small space. Trying to communicate the calling sequence in words is far
harder than doing so in a diagram like this. The Sequence Digram allows software designers
to communicate the dynamic behaviour of a software solution.
One issue with a Sequence Diagram is that it can quickly become very large if you use it to try
and explain all of the actions within a program. As the complexity of your programs grow you
will see that it becomes more and more difficult to try to communicate all of the program’s be-
haviour in a single diagram. Instead of trying to communicate the entire program’s behaviour,
128
3.5. UNDERSTANDING PROCEDURE DECLARATION AND CALLS
effective Software Designers will use Sequence Diagrams to communicate important details
that may be missed otherwise. Focusing on areas where the interaction between the proce-
dures is particularly important. As you progress as a Software Developer see if you can use
these diagrams to effectively communicate important points in your designs.
Together Structure Charts and Sequence Diagrams allow Software Designers to communicate
the static structure and dynamic behaviour of their designs. As a software developer you will
need to understand how to read these diagrams, and use them to communicate your designs
decisions.
The Sequence Diagram gives you a way of visualising what happens at run time, but let
us return to our virtual computer and see how these actions actually work within the com-
puter.
1. Morse Calling is Loaded into Memory
2. Signal C is Called
3. Long Signal is Called
4. Control Returns to Signal C
5. Short Signal is Called
6. Short Signal Ends
129
CHAPTER 3. PROCEDURE DECLARATION
When the program is launched the Operating System loads the code for Morse Calling into
memory, and starts it executing in the program’s entry point.
----------------------------
Procedure: Write Procedure
----------------------------
...
----------------------------
Procedure: Short Signal
----------------------------
...
2
----------------------------
Procedure: LongSignal Loads instructions
---------------------------- into Memory
...
Main is loaded onto ----------------------------
the Stack Procedure: SignalQ
----------------------------
...
----------------------------
Procedure: SignalC
3 ----------------------------
...
----------------------------
Program: Morse Calling
----------------------------
Program / Main Steps:
1: Call Signal C
Current Instruction:
2: Call Signal Q
3: Call procedure to write a new line to the Terminal
Figure 3.11: The Operating System loads the code for Morse Calling into memory
Note
• In Figure 3.11 the indicated areas show the following:
1. The Operating System reads the code from the Morse Calling executable.
2. This code is then loaded into the program’s memory.
3. A frame is added to the Stack for the entry point, the start of the program’s
instructions. ♠
• The memory for the program is divided into areas for the stack, and the code.
• Only part of the program’s code is shown in Figure 3.11, but in reality all of the
program’s code is loaded into memory.
130
3.5. UNDERSTANDING PROCEDURE DECLARATION AND CALLS
Signal C is Called
The first action in the program’s code is a procedure call that starts the code in +
running.
----------------------------
...
----------------------------
Procedure: LongSignal
----------------------------
...
----------------------------
Procedure: SignalQ
A frame is added to the ----------------------------
Stack for Signal C ...
----------------------------
Procedure: SignalC
----------------------------
2 Steps: Signal C is called
1: Call Long Signal
2: Call Short Signal
3: Call Long Signal 1
Signal C 4: Call Short Signal
5: Call procedure to write ' ' (a space) to the Terminal
Current Instruction: ----------------------------
Program: Morse Calling
----------------------------
Steps:
Program / Main 1: Call Signal C
2: Call Signal Q
Current Instruction:
3: Call procedure to write a new line to the Terminal
Note
• In Figure 3.12 the indicated areas show the following:
1. The first instruction in the program’s is a call to +
.
2. When this is executed a frame is added to the Stack to keep track of the current
instruction within +
’s code.
3. As +
is now on top of the Stack its instructions are executed. The first
instruction in +
is a call to $
+
. ♠
• Notice that the previous Stack Frame keeps track of where the instructions return
when +
finishes.
• The computer runs each instruction one at a time, using the stack to remember
where to return when the current Procedure ends.
131
CHAPTER 3. PROCEDURE DECLARATION
----------------------------
...
A frame is added to the ----------------------------
Procedure: LongSignal
Stack for Long Signal ----------------------------
...
----------------------------
2 Procedure: SignalQ
----------------------------
Long Signal is called
...
----------------------------
Procedure: SignalC 1
Long Signal ----------------------------
Current Instruction: Steps:
1: Call Long Signal
2: Call Short Signal
3: Call Long Signal
Signal C 4: Call Short Signal
5: Call procedure to write ' ' (a space) to the Terminal
Current Instruction: ----------------------------
Program: Morse Calling
----------------------------
Steps:
Program / Main 1: Call Signal C
2: Call Signal Q
Current Instruction:
3: Call procedure to write a new line to the Terminal
Note
• In Figure 3.13 the indicated areas show the following:
1. The first instruction in the +
is a call to $
+
.
2. When this is executed a frame is added to the Stack to keep track of the current
instruction within $
+
’s code.
3. As $
+
is now on top of the Stack its instructions are executed.
• Notice that the previous Stack Frames remain on the Stack to keep track of where ♠
the instructions return when $
+
and +
finish.
• The computer runs each instruction one at a time, using the stack to remember
where to return when the current Procedure ends.
• If you look at the Stack you can see that %
called +
that called $
+
.
Flip back and have a look at the Sequence Diagram for Morse Calling, notice that
the arrows at the start of the diagram match the current state of the Stack.
132
3.5. UNDERSTANDING PROCEDURE DECLARATION AND CALLS
When $
+
finishes running, it has written an underscore to the Terminal, and control
returns back to +
.
----------------------------
...
----------------------------
Procedure: LongSignal
----------------------------
...
Long Signal's frame is ----------------------------
removed from the Stack, Procedure: SignalQ
returning control to ----------------------------
... 1
Signal C ----------------------------
Procedure: SignalC
---------------------------- Long Signal's
3 Steps:
1: Call Long Signal instructions end
2: Call Short Signal
3: Call Long Signal
Signal C 4: Call Short Signal
5: Call procedure to write ' ' (a space) to the Terminal
Current Instruction: ----------------------------
Program: Morse Calling
---------------------------- Long Signal has the
Steps: Side Effect of writing
Program / Main 1: Call Signal C an _ to the Terminal
2: Call Signal Q
Current Instruction:
3: Call procedure to write a new line to the Terminal
2
The computer advances
to the next instruction
in Signal C
Note
• In Figure 3.14 the indicated areas show the following:
1. The computer runs the instructions in $
+
until they end.
2. $
+
has the side effect of writing an underscore to the Terminal.
3. When $
+
’s instructions end control returns to +
.
4. The computer now advanced to the next instruction in +
.
• Procedures should have side effects, changing something as a result of being called. ♠
• +
is now at its second instruction as the computer has finished its first in-
struction.
• In the Sequence Diagram for Morse Calling the program is now at the point after the
first returninga arrow and is now about to call + +
.
a The dashed arrow returned back from $
+
.
133
CHAPTER 3. PROCEDURE DECLARATION
----------------------------
...
A frame is added to the ----------------------------
Procedure: LongSignal
Stack for Short Signal ----------------------------
...
----------------------------
2 Procedure: SignalQ
----------------------------
...
---------------------------- Short Signal is called
Procedure: SignalC
Short Signal ----------------------------
Steps: 1
Current Instruction:
1: Call Long Signal
2: Call Short Signal
3: Call Long Signal
Signal C 4: Call Short Signal
5: Call procedure to write ' ' (a space) to the Terminal
Current Instruction: ----------------------------
Program: Morse Calling
----------------------------
Steps:
Program / Main 1: Call Signal C
2: Call Signal Q
Current Instruction:
3: Call procedure to write a new line to the Terminal
3
_
Note
• In Figure 3.15 the indicated areas show the following:
1. The second instruction in the +
is a call to + +
.
2. When this is executed a frame is added to the Stack to keep track of the current
instruction within + +
’s code.
♠
3. As + +
is now on top of the Stack its instructions are executed.
• In the Sequence Diagram for Morse Calling the program is now in the call to +
+
.
134
3.5. UNDERSTANDING PROCEDURE DECLARATION AND CALLS
When + +
ends control returns again to +
, with + +
having output
a . to the Terminal.
----------------------------
...
----------------------------
Procedure: LongSignal
----------------------------
... 1
Short Signal's frame is ----------------------------
removed from the Stack, Procedure: SignalQ
returning control to ----------------------------
... Short Signal's
Signal C ---------------------------- instructions end
Procedure: SignalC
----------------------------
3 Steps:
1: Call Long Signal
2: Call Short Signal
3: Call Long Signal
Signal C 4: Call Short Signal
5: Call procedure to write ' ' (a space) to the Terminal
Current Instruction: ----------------------------
Program: Morse Calling
---------------------------- Short Signal has the
Steps: Side Effect of writing
Program / Main 1: Call Signal C a . to the Terminal
2: Call Signal Q
Current Instruction:
3: Call procedure to write a new line to the Terminal
2
The computer advances
to the next instruction
in Signal C
_.
Note
• In Figure 3.16 the indicated areas show the following:
1. The computer runs the instructions in + +
until they end.
2. + +
has the side effect of writing an dot to the Terminal.
♠
3. When + +
’s instructions end control returns to +
.
4. The computer now advanced to the next instruction in +
, the third State-
ment in the code.
135
CHAPTER 3. PROCEDURE DECLARATION
----------------------------
...
----------------------------
Procedure: LongSignal
----------------------------
... The Instructions in
----------------------------
Procedure: SignalQ Signal C each run, one
---------------------------- at a time
...
----------------------------
Procedure: SignalC
---------------------------- 1
Steps:
1: Call Long Signal
2: Call Short Signal
3: Call Long Signal
Signal C 4: Call Short Signal
5: Call procedure to write ' ' (a space) to the Terminal
Current Instruction: ----------------------------
Program: Morse Calling
---------------------------- The Side Effects of each
Steps: procedure can be seen
Program / Main 1: Call Signal C in the Terminal
2: Call Signal Q
Current Instruction:
3: Call procedure to write a new line to the Terminal
_._.
Note
• In Figure 3.17 the indicated areas show the following:
1. Each instruction in +
is run until all of the instructions in +
are
complete.
C
2. The side effects of the calls to $
+
and + +
can be seen in the ♠
Terminal.
3. The final state of the Terminal, showing , shows the side effect of calling
+
.
136
3.5. UNDERSTANDING PROCEDURE DECLARATION AND CALLS
Signal Q is Called
When +
finished the computer returns to the program’s main instructions, where it
moves on to the call to +
).
----------------------------
...
----------------------------
Procedure: LongSignal
----------------------------
...
----------------------------
Procedure: SignalQ
----------------------------
When Signal C ends ...
----------------------------
control returns to Procedure: SignalC
the Program's main ----------------------------
instructions Steps: Next will be a call to
1: Call Long Signal Signal Q
2: Call Short Signal
1 3: Call Long Signal
2
4: Call Short Signal
5: Call procedure to write ' ' (a space) to the Terminal
----------------------------
Program: Morse Calling
----------------------------
Steps:
Program / Main 1: Call Signal C
2: Call Signal Q
Current Instruction:
3: Call procedure to write a new line to the Terminal
_._.
Figure 3.18
Note
• In Figure 3.18 the indicated areas show the following:
Q
1. When +
ends its frame is removed from the Stack and control returns to
the program’s main instructions.
2. The next call will be to +
). The code in +
) will run, and output
to the Terminal, with each of the individual characters being written by the calls ♠
to $
+
and + +
in the same way as it occurred in +
.
• If you look at the Sequence Diagram for Morse Calling you can see that this is the
point where control has returned to main, before it calls into +
).
137
CHAPTER 3. PROCEDURE DECLARATION
Section 3.5.3, procedure calls in Action, showed the actions the computer performs in order
to execute the procedures that we create, but how does this information help us create our
own programs and procedures?
One important aspect about procedures is the fact that they are isolated from each other.
Notice that $
+
does not care who called it, it is responsible for performing a long signal
and carries out this task when it is called. Similarly, + +
does not care who called it,
it is responsible for performing a short signal and carries out this task when it is called. Look
back at the illustrations of execution and you should be able to see each Procedure carrying
out its actions before control returns to where the procedure was called. In each case the
called Procedure finishes the task it is responsible for performing before it ends.
This isolation also works in the other direction. +
calls $
+
when it needs a
long signal to be performed. It does not care about how $
+
achieves this, and can
reply upon the fact that $
+
will take care of its responsibilities before it ends. When
you are working on designing or coding +
you focus on the task that +
needs
to perform and make use of the other Procedures without needing to worry about how these
Procedures achieve their responsibilities internally.
For Software Design and Development the isolated nature of procedures means that you can,
and should, focus on the Procedure you are working on and ignore details of how other proce-
dures work internally.
Note
• A Procedure has responsibilities. It is responsible for performing some actions to
create a certain side effect.
• Each Procedure is isolated from the other code in your program.
♠
• Focus on the Procedure you are designing or implementing, get it to meet its respon-
sibilities and you will be one Procedure closer to your solution. Repeat this process
for each Procedure in your design.
3.5.5 Summary
This Section has covered the use of Structure Charts and Sequence Diagrams to help vi-
sualise the relationships between procedures in a program, and to see how these Procedures
work dynamically. This was supported by the illustration of how Procedures are executed by
the computer.
Note
The key messages to take away from this Section are:
• A Procedure has the responsibility to perform a given task.
• The Procedure’s name should reflect the task it performs.
• A Structure Chart shows the Procedures in a program, and how they are connected
by procedure calls.
• The dynamic behaviour of the program can be shown using a Sequence Diagram,
this sequence of procedure calls within the program.
• When a Procedure is called its instructions are followed. These instructions get the ♠
computer to perform the task the Procedure is responsible for.
• Procedures should cause side effects, changing something as a result of being
called.
• Making sure each Procedure performs a single task will make your job easier.
• A single task may have sub tasks that can be coded in their own procedures. For
example, +
has sub tasks for performing long and short signals that can be
coded into their own Procedures.
138
3.6. PROCEDURE DECLARATION EXAMPLES
This program prints out a short knock knock joke to the Terminal.
• The description of the program is in Table 3.3
• The pseudocode is in Listing 3.12
• Figure 3.19 shows the Structure Chart for the Program
• The dynamic behaviour of the program is shown in the Sequence Diagram in Figure 3.20
• Listing 3.13 has the C code for the Program
• Listing 3.14 has the Pascal code for the Program
Program Description
Name Tell Joke
Main
HaHa HeHe
C++
The C language does not have a standard pause or delay procedure, instead of pausing
♢
execution the C version will just print ”.. pause ..” to the Terminal.
Pascal
In Pascal you can use the *, unit to access a procedure that pauses execution. ♡
139
CHAPTER 3. PROCEDURE DECLARATION
Main
TellJoke Call
SetupJoke
Return
Procedure
PunchLine
PauseForDramaticEffect
Laugh
Ah
HaHa
Ha
Ha
HaHaHeHe
HaHa
Ha
Ha
HeHe
PauseForDramaticEffect
HeHe
StopLaughing
Ah
PauseForDramaticEffect
140
Pseudocode
( , "
(
+
/ ' ' ,
( + "
+ (
/ '#
#
' ,
/ '/ '' ' ,
+
/ ' ' ,
/ ' ' ,
/ ' /' ,
(
( (
+
+
(
( (
$
( $
+ + ♣
(
/ '
''
' ,
(
( , "
+
+ "
( +$
(
$
+
/
,
(
(
+ /
,
/ ' ' ,
/ '1
' ,
+
( , "
$
+ +$
Listing 3.12: Pseudocode for Tell Joke program.
C++
(
7
,
7
#
#
4
/ '' 4
4
7 7
/ 4
7
7
77 7
4
7
7
7 7
77 7 77 7 ♢
'
4
7
7
7
7
4
7
77 7
4
1
4
7 7
7
Listing 3.13: C Knock Knock Joke
7
Pascal
( ,"
,
,"
*,
/ ' '
+"
/$
'#
#
'
/$
'/ '' '
/$
' '
/$
' /'
This Chapter explained the development of a Morse Calling program that output text to the
Terminal. This version of the program uses SwinGame to play audio for the long and short
signals.
• The description of the program is in Table 3.4
• The pseudocode is in Listing 3.15
• The Structure Chart is very similar to the version that wrote its output to the Terminal,
see Figure 3.9. This code also include a $ +
procedure called from %
.
• The dynamic behaviour is the same as the the Sequence Diagram in Figure 3.10
• Listing 3.16 has the C code for the Program
• Listing 3.17 has the Pascal code for the Program
Program Description
Name Morse Calling
C++
SwinGame has the following procedures that can help you implement this program:
•
: you pass it the name of the sound effect to play.
• : allows you to pause execution for a number of milliseconds.
•
: you pass it the name to use, and the filename to load.
SwinGame will load the file from Resources/Sounds.
♢
•
: starts SwinGame’s audio system, you cannot load or play sounds until
after this is called.
• : closes SwinGame’s audio system, needed at the end of the program to
match the
.
• : releases the loaded sound effects.
Pascal
SwinGame has the following procedures that can help you implement this program:
• ( +
: you pass it the name of the sound effect to play.
• : allows you to pause execution for a number of milliseconds.
• $ +
& : you pass it the name to use, and the filename to load.
SwinGame will load the file from Resources/Sounds.
♡
• '
: starts SwinGame’s audio system, you cannot load or play sounds until
after this is called.
• : closes SwinGame’s audio system, needed at the end of the program to
match the '
.
• * *: releases the loaded sound effects.
144
3.6. PROCEDURE DECLARATION EXAMPLES
Pseudocode
( %
( ++
+
( ' ' +
( $
+
+
( ' ' +
( +
+
$
+
++
$
+
++
♣
( +
)
+
$
+
$
+
++
$
+
( $ +
+
$ +
& ' ' ' '
$ +
& ' ' ' '
+
'
$ +
+
+
)
* *
Listing 3.15: Pseudocode for Morse Calling with Audio.
145
CHAPTER 3. PROCEDURE DECLARATION
C++
( %
' )
+
7
7
7
7
7
7
7
7
7
7
7
7
♢
7
7
7
7
7
7
77
7
77
7
7
7
7
7
7 7
Listing 3.16: C Audio Version of Morse Calling
146
3.6. PROCEDURE DECLARATION EXAMPLES
Pascal
( %
%
' ) '
'
%
++
( +
' '
$
+
( +
' '
+
$
+
++
$
+
++
+
)
$
+
♡
$
+
++
$
+
$ +
$ +
& ' ' ' '
$ +
& ' ' ' '
%
'
$ +
+
+
)
* *
%
Listing 3.17: Pascal Audio Version of Morse Calling
147
CHAPTER 3. PROCEDURE DECLARATION
This small SwinGame creates a procedure to draw a sun in the top left corner of the screen.
• The description of the program is in Table 3.5
• The pseudocode is in Listing 3.18
• Listing 3.19 has the C code for the Program
• Listing 3.20 has the Pascal code for the Program
Program Description
Name Morse Calling
C++
SwinGame has the following procedures that can help you implement this program:
•
: you pass it the title of the window, and a width and height in
pixels.
• : allows you to pause execution for a number of milliseconds.
•
: you pass it the name to use, and the filename to load.
SwinGame will load the file from Resources/Sounds.
•
: clears the screen to the indicated color.
•
: displays the screen. All SwinGame drawing is performed in the ♢
background, this displays the screen to the user.
• and : draws the outline or fills a circle on the screen. This
is passed the color of the circle, its x and y locations, and its radius.
•
: draws a line from one point to another. This is passed the color of the
line, the x and y coordinates of the start point, and the x and y coordinates of the
end point.
• : releases the loaded sound effects.
Pascal
SwinGame has the following procedures that can help you implement this program:
• '
/
: you pass it the title of the window, and a width and height in
pixels.
• : allows you to pause execution for a number of milliseconds.
• +
: clears the screen to the indicated color.
• *+
: displays the screen. All SwinGame drawing is performed in the back-
ground, this displays the screen to the user. ♡
• and : draws the outline or fills a circle on the screen. This is
passed the color of the circle, its x and y locations, and its radius.
• $
: draws a line from one point to another. This is passed the color of the line,
the x and y coordinates of the start point, and the x and y coordinates of the end
point.
• * *: releases the loaded sound effects.
Note
SwinGame colors are
* /
1 (
, %
♠
$.
148
3.6. PROCEDURE DECLARATION EXAMPLES
Pseudocode
( +
+
( +
+
1
*
*
+
'
/
' +
'
+
+
*+
* *
Listing 3.18: Pseudocode for Draw Sun Scene program
149
CHAPTER 3. PROCEDURE DECLARATION
C++
( +
+
+
7
7 1
7 *
7 *
7 *
7 *
7 /
7
1
7
1
7
1
7
1
7
1
7
1
7
1
♢
7
1
7 7
+
7 7
7
7 7
Listing 3.19: C Draw Sun Scene Program
150
3.6. PROCEDURE DECLARATION EXAMPLES
Pascal
( +
+
%
- *
+
1
*
*
*
*
/
$
1
$
1
$
1
$
1
$
1
$
1
$
1
$
1
♡
%
'
/
' +
'
+
+
*+
* *
%
Listing 3.20: Pascal Draw Sun Scene Program
151
CHAPTER 3. PROCEDURE DECLARATION
Read over the concepts in this chapter and answer the following questions:
1. What is a Program? What does it contain?
2. What is a Procedure? What does it contain?
3. If %
calls +
, and +
calls +
, what order must these procedures
be declared in your program’s code?
4. Why create your own procedure? Why not just code all the instructions in the one main
procedure?
5. It is stated that a procedure should have a side effect, what does this mean?
6. Examine the ‘Tell Joke’ program, see Section 3.6.1, then answer the following questions.
(a) How many times is the procedure called?
(b) How many times is the procedure written? What does this mean for the use of
procedures in our code?
(c) At its deepest, how many stack frames will be on the stack when the ‘Tell Joke’
program is run?
(d) Which procedures call ( ?
(e) What does the name of each procedure tell us?
7. Picture yourself in the following scenario, and then answer the following questions.
As a graduate you start work as a software developer in a startup building some
really cool software. The project that you are working on has around 100 fea-
tures, which are implemented in 10,000 procedures. You are asked to fix a
specific bug in the program.
• This bug effects just a single feature.
• The other developers believe that the issue is located in a single procedure
but they want you to learn how the program is structured, so they will not
tell you which procedure it is.
• You have played with the software and you know how to cause the bug.
• There are about four or five steps from the program’s start, up to the point
where the bug occurs.
(a) When you get the code, what strategy would you use to locate the one procedure that
has the bug?
(b) Would you need to understand all ten thousand procedure? Explain your reasoning.
(c) Do you think you would need to read the procedures called by the procedure with
the bug? Explain your reasoning.
(d) When you understand the section of the code related to the bug you will need to
implementing a fix. Explain why you would be able to focus your attention to this
one procedure when you are implementing the fix.
(e) How would you test that your fix has solved the problem?
(f) The next bug you need to fix occurs across a number of different features of the
program. The cause is still expected to exist within a single procedure. How would
this change the way that you approach locating and fixing the bug?
152
3.7. PROCEDURE DECLARATION EXERCISES
Program Description
Name Morse SOS
Description Displays the morse code for a distress signal on the Termi-
nal.
2. Create a Morse Name program that outputs your name in morse code to the Terminal.
See Table 3.7.
Program Description
Name Morse Name
Description Displays the morse code for your name on the Terminal.
3. Update your Morse SOS program to use SwinGame, and either flash the screen to signal
your message or play morse code sound effects.
4. Update your Morse Name program to use SwinGame, and either flash the screen to signal
your message or play morse code sound effects.
5. Take the Seventy Three Times Table program from Chapter 2, and re-implement it so that
it has a (
, , procedure.
6. Take the Face Shape program from Chapter 2, and re-implement it so that the face is
drawn in a procedure.
7. Download the code for the Scene Drawing program from the website, and rewrite it to
make use of Procedures.
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. Are the procedures in the libraries any different from the procedures you create?
2. Explore the procedures that are available to you in the standard library that comes with
your language. Name some of the procedures you think will be useful to know about in
the future.
3. Explore the procedures that are available to you in the SwinGame library. Name some of
the procedures you think will be useful to know about in the future.
4. Why must procedures have side effects?
5. How should procedures be named?
153
Storing and Using Data
4
ow it is time to turn your attention to a the finer details of spell
craft. So far the magic you are working has not made use of material
components. Fet the Dragon scales from off the est in the corner,
and place them in that goblet. Prepare you wand, and. . . . . .
So far our programs have only been able to work with Literal values. This Chapter introduces
new artefacts you can use to store data, and from which you can read the value stored called
Variables and Constants. It will also introduce a new artefact that can be used to calculate
values called a Function. Using these artefacts you will see how you can store and manipulate
values in your code.
When you have understood the material in this chapter you will be able to write code that
uses Variable and Constants to stores and manipulates data. You will be able to share data
between different Procedures, and create and use Functions to calculate values.
Contents
4.1 Concepts Related to Storing and Using Data . . . . . . . . . . . . . . . . . . . 157
4.1.1 Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
4.1.2 Constant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
4.1.3 Local Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
4.1.4 Global Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
4.1.5 Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
4.1.6 Pass by Value and Pass by Reference . . . . . . . . . . . . . . . . . . . . . . 164
4.1.7 Statement (with Assignment) . . . . . . . . . . . . . . . . . . . . . . . . . . 165
4.1.8 Assignment Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
4.1.9 Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
4.1.10Function Call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
4.1.11Expressions (with Function Calls, Variables, and Constants) . . . . . . . . 169
4.1.12Program (with functions) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
4.1.13Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
4.2 Using these Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
4.2.1 Designing Change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
4.2.2 Understanding the Change Calculator . . . . . . . . . . . . . . . . . . . . . 173
4.2.3 Choosing Artefacts for the Change Calculator . . . . . . . . . . . . . . . . . 174
4.2.4 Writing the Code for the Change Calculator . . . . . . . . . . . . . . . . . . 182
4.2.5 Compiling and Running the Change Calculator . . . . . . . . . . . . . . . . 183
4.3 Storing and Using Data in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
4.3.1 Implementing Change Calculator in C . . . . . . . . . . . . . . . . . . . . . 185
4.3.2 Implementing Change Calculator using C++ . . . . . . . . . . . . . . . . . 187
155
CHAPTER 4. STORING AND USING DATA
156
4.1. CONCEPTS RELATED TO STORING AND USING DATA
Chapter 3, Procedure Declaration, showed you how you can create your own procedures, with
each procedure performing a task for the program. The procedures that you created did use
some data, but in each case the data was entered directly into the code of the program, as a
Literal.
This next step introduces the idea of creating your own artefacts that can be used to store, or
calculate a value. Using these artefacts you can start to work with values in a more dynamic
way, allowing you to get the computer to perform calculations, and to store and manipulate
values.
In this Chapter you will learn how to create the following programming artefacts:
• Variable: You can store a value in a Variable, and retrieve the value from the Variable.
• Constant: Is similar to a Variable, except that its value cannot change after it is declared.
• Function: Is similar to a Procedure, but is used to calculate a value rather than to produce
a side effect.
You will learn about the following terminology:
• Global Variable: Variables declared within the program’s code are called Global Variables.
• Local Variable: Variables declared within a Function or Procedure are called Local Vari-
ables.
• Parameter: Parameters are variables that allow values to be passed into a Function or
Procedure.
• Expressions (with Function Calls, Variables, and Constants): See how Functions, Con-
stant, and Variables can be used in Expressions.
Additionally, you will learn how to perform the following actions:
• Assignment Statement: You use an Assignment Statement to store a value in a Variable.
• Function Call: This is part of an Expression, and is used to call the Function and to read
the returned result.
157
CHAPTER 4. STORING AND USING DATA
By the end of this material we will have worked through an example where you create a program
that calculates change for a vending machine. This program will read the cost and amount
paid from the user, and will then output the number of coins that need to be returned. The
output of several runs of this program are shown in Figure 4.1.
158
4.1. CONCEPTS RELATED TO STORING AND USING DATA
4.1.1 Variable
A Variable is a container into which you can store a value, which can then be retrieved later.
The Variable allows you to store values you want to work with in your program, you store values
in the variable so that you can read them back later. The variable’s themselves are either a
Global Variable, Local Variable, or Parameter.
Assigns a value
to a Variable
101 Assignment
Stores a value 001 Statement
Occupies a location
01
in memory Has a name
Variable that is an
Type
Figure 4.2: Variables store a value that can be read and changed
Note
• A Variable is an artefact, you can create variables to store values in your programs.
• You can think of a Variable like a ”box with an item in it”. The Variable is the box,
its value is the item within it.
• Each Variable has a ...
– Name that can be used to refer to it.
– Value that it is storing.
– Type that determines the size of the Variable and how its value is interpreted. ♠
• You use an Assignment Statement to store a value into the Variable.
• You can read the value from Variable in Expressions.
• The Variable is different to its value:
– The Variable is a container into which a value can be stored.
– You can read the value from the Variable.
– The Variable is not the value, it is a container into which the value is stored.
159
CHAPTER 4. STORING AND USING DATA
4.1.2 Constant
A Constant is just like a Variable, but its value cannot be changed. Constants are declared
within the Program, and given a value when they are created. Once they are created the value
within the Constant cannot be changed. This is useful for data where you do not want the
value changing during the program’s execution.
Identifier
Has a name
Has a value
that is an
Occupies a location
in memory
Constant
10100...
The Type determines the
number of bytes used to
Value is assigned The variable has a Type store the value in memory
when it is created, that determines how
then it cant be changed its value is interpreted
Type
The value can be read
in an expression
Expression
Note
• A Constant is an artefact. You can create Constants in your Program to store values
that must not change.
• A Constant is similar to a Variable, they have a...
– Name that is used to access them.
– Value that can be read in an Expression.
♠
– Type that determines how their data is interpreted.
• You read values of Constants in Expressions.
• Constants are useful for data you do not want to change during the program.
• The name of the Constant is an Identifier.
• The Constant’s name should reflect the value it is storing.
160
4.1. CONCEPTS RELATED TO STORING AND USING DATA
Variables can be declared at a number of different places in your code. Variables that are
declared within Procedures are called Local Variables. Most of the variables in your code will
be Local Variables.
Performs a task
Has a name
that is an Accepts values
that it needs to
Local variables perform its task
exist entirely within Procedure
a the Procedure Identifier
10100101
Variable 101
001
10100101 01
Variable Parameter
The Procedure's
10100101
instructions can Variable 101
read and assign 001
01
values to the Parameter
Local Variables Instruction 1 Passes in
Values
...
Starts the
Contains a
number of
Library reusable Procedure Call
Note
• Local Variable is the term given to a Variable that is declared within a Procedure.
• Variables that are declared within Procedures are called Local Variables.
• Local Variables are located within the Procedure they are declared in.
• They can only be accessed by instructions in the Procedure.
• It is good practice to use Local Variables to store values. These variables can only ♠
be accessed from the instructions within the Procedure, this makes it easier to un-
derstand how the variable is being used and where it is being changed.
• Space is allocated for the Local Variables when the Procedure is called.
• When the call ends, the Local Variables for that call are destroyed.
161
CHAPTER 4. STORING AND USING DATA
Variables and Constants can be declared within a Program. Variables declared in this way
are called Global Variables. It seems tempting to use Global Variables to share values between
procedures, but this is a bad idea. Global Variables should be avoided, and for many programs
are unnecessary. The issue with Global Variables is that their values can be changed from
anywhere within the program’s code. This can make it difficult to locate the source of errors
when globals are used.
While Global Variables should be avoided, Constants should be declared globally. As these
values can not change, the issues with Global Variables do not affect Constants.
Program Identifier
Note
• Global Variable is the term given to a Variable that is declared within the program.
• Variables that are declared within a Program are called Global Variables.
• Global Variables can be accessed by the program’s instructions, and by the instruc-
tions in any of the Procedures.
• You should avoid using Global Variables. These variables can be accessed anywhere
♠
within the Program, making it difficult to locate errors.
• Using Global Variables introduces hidden dependencies between Procedures, break-
ing the isolated nature of the Procedures.
• Constants should be declared globally, and used to give meaning to values entered
into your code.
162
4.1. CONCEPTS RELATED TO STORING AND USING DATA
4.1.5 Parameter
The instructions within a Procedure define the actions that occur when that procedure is
called. In most cases these instructions need to be given values to work with. These values
can be passed to the Procedure using Parameters. The Parameter is a Variable that has its
value set in the procedure call.
Procedure Call
Call the Procedure
Note
• Parameter is the term given to the Variables declared to accept values passed to
Procedures.
• The procedure call assigns values to each of the Procedure’s Parameters.
• Parameters allow you to pass values into a Procedure. ♠
• Within the Procedure the Parameters can be used in the same way as any other
Variable.
• It is good practice to use Parameters to pass values into a Procedure.
163
CHAPTER 4. STORING AND USING DATA
There are actually two ways that values can be passed to Parameters. This relates back to
the fact that Variables have two aspects: the Value within the Variable, and the Variable
itself. These two means of passing parameters allow you to either pass a value, or pass a
Variable.
Value is copied
Function or into Parameter
Procedure
10100101
10100101 Variable
Variable 101
001
10100101 01
Variable Parameter
(by Value)
10100101
Variable
01010101
Variable
Note
• Pass by Reference and Pass by Value are terms that explain how data is passed to
a Parameter.
• Most parameters are passed by value.
• Pass by value copies the value to the parameter. This means pass by value can work
with any Expression.
• Pass by reference allows you to pass the Variable itself to the parameter. ♠
• The main use for pass by reference is to allow the Procedure or Function to store a
value in the Variable passed to the parameter.
• It is called pass by reference due to the way it is implemented, with the parame-
ter receiving a reference to the Variable. Section 4.2 will cover this in more detail,
conceptually the Variable itself is passed to the Parameter.
164
4.1. CONCEPTS RELATED TO STORING AND USING DATA
Statements are the actions that we can get the computer to perform. At this stage we have
covered the statements that run procedures, the Procedure Call, and the statement to assign
values to variables, the Assignment Statement.
Statement
Is one kind of
Each instruction is a
Commands the Computer
Procedure Call to perform the action
Is one kind of
Program
Commands the computer to
Instruction 1 'run the code in a
Instruction 2
Instruction
Procedure3 Assignment
Instruction 4 Statement
Instruction
10100101
5
...Variable
10100101 Parameter
Variable
Commands the computer to
Instruction 1 Parameter 'store a value in a 101
Instruction 2 001
01
Variable
Note
• Statement is the term given to the instructions in our code.
• Statements can be either:
– Procedure Call used to run the code in a Procedure, as covered in Chapter 2.
♠
– Assignment Statement used to calculate a value and store it in a Variable.
• All instructions in your code are Statements, these include the instructions in your
Program as well as the instructions in your Procedures and Functions.
165
CHAPTER 4. STORING AND USING DATA
The Assignment Statement calculates a value, and stores it in a Variable. You use an assign-
ment statement to store values in variables.
Value is Expression
Calculated
and stored
in a Variable The Value is
an Expression
101
001
01
Variable
stored in 7 * 10 + 3
Note
• An Assignment Statement is an action you can get the computer to perform.
• The right hand side of the Assignment is an Expression that calculates the value to
be stored.
• The left hand side of the Assignment is a Variable into which the value is stored.
• When the Assignment Statement is executed the Expression is evaluated first, and
♠
then the resulting value is stored in the variable.
• Its important to remember that the Variable is a location at which to store a value.
When the Variable appears on the left hand side of an assignment it is being use to
store the resulting value. If the variable appears on the right hand side its value is
being used as part of the expression.
166
4.1. CONCEPTS RELATED TO STORING AND USING DATA
4.1.9 Function
Functions are used to calculate values. In many ways a Function is just like a Procedure, it
has a name, can be called, can accept parameters, can have local variables, and performs a
number of instructions when it is called. Unlike a Procedure, however, Functions are used to
calculate values. When the function you called ends it returns back to you with a value.
Calculates a Value
The Function's
Has a name instructions calculate
that is an and return a value
Function Identifier
10100101
Variable
Result
10100101
Variable 101
Like a Procedure, 001 Gets the value
10100101 01
a Function can Variable returned
Parameter
have Local Variables,
and Instructions 101
Instruction 1 001
01
... Parameter
Values are
passed into
Starts the Parameters
Contains a
number of
Library reusable
Function Call
Figure 4.10: A Function is just like a Procedure, except it calculates and returns a Value
Note
• A Function is an Artefact. Something that you can create and use in your program’s
code.
• A Function is just like a Procedure in that it ...
– Has a name that is used to call it.
– Performs instructions when it is executed.
– Can accept Parameters to allow the caller to pass in values.
– Is allowed to create its own local variables. ♠
• Unlike a Procedure, a Function...
– Should not have any side effects.
– Calculates and returns a value.
– Is called as part of an Expression.
• You use Functions to calculate values.
• You use a Function Call to call a function as part of an Expression.
167
CHAPTER 4. STORING AND USING DATA
A Function Call is used to execute a Function, and to read the value that is returned. This is
similar to a Procedure Call, but unlike a procedure call it must be done as part of an Expres-
sion.
Calls a Function
Is part of an
Expression Expression
Function Call
Provides values to
the Parameters Gets the value returned
by the Function
Function
10100101
10100101 Variable
Parameter
10100101 Result
10100101 Variable
Parameter
Instruction 1
...
Figure 4.11: A Function Call is part of an Expression where the value is calculated
Note
• A Function Call is an action, but one that is performed as part of an Expression.
• Function calls can appear in any expression. For example, you can use a Function
♠
Call to calculate the value in an Assignment Statement. You can use a Function Call
to calculate the argument values for a procedure call.
168
4.1. CONCEPTS RELATED TO STORING AND USING DATA
You can read the values from Variables and Constants within Expressions. The value of the
expression is calculated by reading the values from the Variables and Constants when the
expression is calculated1 .
Is a value.
Expression 01101110
Variable
Constant
Part or all of the 10100...
value can be Calculated Reads value from
by a Function, or read the Variable
from Variables and
01
10
10
Constants
10
the Constant
11
0.
10
..
sin(deg * PI / 180)
This expression is evaluated
Calls the Function, and
first. If the value in deg
then reads its result
is 90 then this has the value
1.570796326794897 this value
This expression is evaluated is passed to the first parameter
second. The sin Function is called in the sin Function.
to calculate the sine of
1.570796326794897. The sin
Function will return the result 1.
Figure 4.12: Expressions can read values from Function Calls, Variables, and Constants
Note
• Expression is the term given to the code that calculates values within your State-
ments.
• You can read values from Function Calls, Variables, and Constants.
• You use the Variable or Constant’s name to access its value within an Expression.
• The Function Call runs the code in the Function, and then reads the result returned.
• There are actually two expressions in Figure 4.12:
1. The first Expression is the value passed to the
function (𝑑𝑒𝑔 × 𝑃 𝐼 × 180).
This value is calculated by reading the values from the variable and the (!
♠
constant. These values are then used in the Expression to determine that value
that is passed to the Parameter in
.
2. The second Expression is the result returned from the call to the
function.
This will calculate the sine of the value calculated in the first expression.
• The Expression reads the value of the Variable at the time it is executed.
• Expressions are used to calculate values that are...
– Passed to Parameters within Procedure Calls.
– Assigned to Variables within Assignment Statements.
1 This means that the value will be affected by the statements that occurred before the expression was calculated.
169
CHAPTER 4. STORING AND USING DATA
You can declare your own Functions within the program’s code.
Program Identifier
10100101
10100...
Variable
10100... Result
Variable
10100...
10100101
Parameter
Parameter
Instruction 1 and within the
Instruction
Variable 1 Parameter
...
Instruction
Parameter
1 Parameter Instruction 2 Program's code
...
Instruction 1 Parameter
... ...
Figure 4.13: You can declare your own Functions in your program’s code
Note
• A Program is an Artefact, you create Programs that the user can execute. Inter-
nally these programs contain other artefacts such as Procedures, Functions, and
Variables. ♠
• You can declare your own Functions within your program’s code.
• With C and Pascal the Function must be declared before it is used.
170
4.1. CONCEPTS RELATED TO STORING AND USING DATA
4.1.13 Summary
This section has introduced a number of programming artefacts, some programming terminol-
ogy, and one kind of instruction. An overview of these concepts is shown in Figure 4.14. The
next section will look at how you can use these concepts to design some small programs.
Artefact
Variable
Function Call Term
Action
Are kinds of
Runs the code
in a Variables in a Global Variable
Program are
Term
Program
Local Variable
Artefact Term
Can contain
Functions Variables in a Term
Function / Procedure
are Parameter
Artefact
A Procedure / Function
Function accepts values using
Procedure Parameters
using...
Artefact
Term
Term
Pass by Value Pass by Value
Note
• Artefacts are things you can create and use.
• Terms are things you need to understand. ♠
• Actions are things you can command the computer to perform.
171
CHAPTER 4. STORING AND USING DATA
Variables, Constants, and Functions give us the ability to work with data in new ways in our
programs. Previously the data within the program was limited to values entered directly into
the code. Now with these concepts we can interact more meaningfully with data, performing
calculations, and storing and manipulating values.
Table 4.1 contains a description of the next program we are going to design. This program
will calculate and output the ideal change for a given transaction from a Vending Machine. In
designing this program we will make use of the concepts introduced in this chapter; we will
use a Function to calculate the coins to give, Variables to store values such as the amount
paid, Constants for the values of the different coins, and Parameters to pass values to the
Function.
Program Description
Name Change Calculator
Figure 4.15: The Change Calculator running in the Terminal, from Figure 4.1
172
4.2. USING THESE CONCEPTS
Receiving change from a transaction is something that you should be familiar with, and deter-
mining the ideal change is not an overly complex task. While the task itself is common, it does
not mean that you can skip thinking about it. If you had to give $6.50 in change you know
without thinking that you should give three $2 coins, and one 50c coin. What you need to do
now is think through the steps that you perform intuitively.
Think about all the steps for how you actually calculated the change to be given. The first
secret is to realise that you need to start with the coin with the largest value, and then work
down from there to the coin with the smallest value. The number of coins you give each time
can then be calculated by dividing the amount of change to be given by the value of the current
coin. Lastly you need to reduce the amount of change that remains to be given. These steps
are shown in the pseudocode in Listing 4.1.
Pseudocode
(
,/'7'$$*+
'&7'$$*
!,17&,+
,/&,17&,+
,&7&,+
!.7&,+
.
,
.
(
.
.
♣
(
%
.
. !
+
.
.
' '
' ,
. ,/'7'$$*+ '$
'
. '&7'$$* '$ '
. !,17&,+ '
'
. ,/&,17&,+ '
'
. ,&7&,+ ' '
. !.7&,+ '
'
'
,
Listing 4.1: Pseudocode for Change Calculator program.
173
CHAPTER 4. STORING AND USING DATA
The design for any program should involve thinking about the data as well as the tasks in-
volved. You can start by dividing the program’s tasks into functions and procedure, and then
look at the data that will be needed by these in order to achieve their tasks.
Think about the process of calculating change. At the start you need to determine the amount
of change that needs to be given. Next you need to determine how many of each kind of coin
you are going to give. These steps can be coded into their own functions and procedures.
These functions and procedures are outlined in the following list, and shown in the structure
chart in Figure 4.16.
•
. : This Function will be responsible for asking the user to enter the cost
of the item, and the amount paid. It will then calculate the amount of change that needs
to be given, in cents.
•
: This Procedure will be responsible for the calculations related to giving one
kind of coin as change. This will involve getting the number of coins to give, updating the
amount of change remaining, and outputting the details (for that coin) to the Terminal.
•
: This Function will be responsible for calculating the number of coins to
give as change, given an amount of change and the value of the coin.
Main
Co
Co De
in
in scr
Ch
e
Va ipt
lu
an
lue ion
Va
ge
,
ge
Va
an
lu
Ch
Coins to Give
To understand how this is going to work you now need to think about how the kinds if data
these different tasks are going to need.
Designing data is much like designing the procedures in your program. You need to think
about the solution and try to identify the different values that are being used. Each of these
values can then become either a Variable, a Parameter, or a Constant. Looking over the steps
174
4.2. USING THESE CONCEPTS
for calculating change you should be able to identify several different values you will need to
work with. You need to be able to store things like the cost of the item being purchased, the
amount of money paid, and the amount of change you need to give. A good way to approach this
is to think about the values the program will output, as well as the values the user will need
to input and any intermediate values you will need to perform the required calculations.
You can use the input/output/processing ideas to help you think about the data that will be
required for each function or procedure. Let us examine each of the functions and procedures
in turn.
Get Change Value The first task we can examine if the
. Function. This
task will be responsible for determining how much change needs to be given to the user. To
design the data needed for this task you can think about its inputs, outputs, and temporary
values.
When you are designing a function or procedure it can be given input by the calling code in
the Function Call or Procedure Call. Inputs provided via the function or procedure call are
coded using Parameters. To determine the parameters you need, think about the information
that this function or procedure will need to be given to fulfil its responsibilities. In the case of
the
. , it does not require any input from the caller.
•
. does not require any input from the calling code, so there is no need
for any parameters with this function.
The
. task will be coded as a function because it has some output. The result
returned by a function is an output, it is what makes it different from a procedure. When you
call a function it runs some steps and then returns a value, the value returned is the output
from the function.
. needs to return back the amount of change, this is why
it is a function in this design.
•
. returns a number. The number returned is the value of the change to
be given in cents.
Within the
. function there will need to be some values that it uses to cal-
culate its output.
. will need to read the cost of the item from the user, and
the amount paid. These two values need to be stored somewhere, so the design of this func-
tion will require two Local Variables: they can be called ! and (
. These
will exist entirely within the function, being the values the function requires to calculate its
output.
•
. will have two local variables: ! and (
.
The pseudocode for this function is shown in Listing 4.2.
Pseudocode
.
*
!
.
! !
(
!
+ ♣
' '
'
*
!
' '
'
*
(
*
(
!
Listing 4.2: Pseudocode for the
. function
175
CHAPTER 4. STORING AND USING DATA
Give Change The next task to consider is the
Procedure. This procedure will be
responsible for coordinating the actions for giving a certain coin in change. Once again you
need to think about the inputs it requires (parameters), its outputs, and any values it will work
with internally.
Put yourself in the place of the computer.2 You (as the computer) have been asked to
. What data will you need to complete this request? At a minimum you will need to know
the total change value that is being given, and the value of the coin that you are issuing.3
There is one more input that you can only find by thinking about the tasks the computer needs
to perform in this code. A part of giving the change will be to output a message, something like
‘3 x 20c’ or ‘1 x $2’. The number of coins can be calculated within the procedure, but the text
is another issue. The computer will not know what text to output. This data must, therefore,
come as input into the procedure.
•
needs to be given the
. variable, and it needs to be told value
of the coin and the coin’s description. These will be coded as parameters, with
. being passed by reference.
will output text to the Terminal, but it also needs to update the
.
variable it is given. This can be considered as output from the procedure. As the
.
variable is passed by reference, you can picture this as receiving the variable from the caller.
Any changes this procedure makes on its
. parameter will actually be changing
the value in the variable passed to the
procedure. In this way the procedure is
able to output a value.4
•
will output the updated
. , as this is passed by reference.
Within
you will need to store the number of coins to give in change. This will
become a local variable that can be used to calculate the updated
. and to output
the details to the Terminal.
•
will have one local variable: used to store the number of this coin to
be given in the change.
The pseudocode for this procedure is shown in Listing 4.3.
Pseudocode
(
(
. !
. !
+
. ♣
, !
+
,
.
.
.
. ,
.
' &
' '
Listing 4.3: Pseudocode for the
function
2 Remember the computer is unintelligent. You cannot rely upon your knowledge. Try to think about the information
you are using and the steps you are performing to make sure you can capture what needs to be done in your code.
3 In this design the
procedure will be called once for each coin.
4 An alternative implementation could have been to code this as a Function, with the new change value being
returned. It would then be the responsibility of the caller to assign this into their change variable.
176
4.2. USING THESE CONCEPTS
Coins to Give The
function is used to calculate the number of coins to give.
This code could have been written within the
procedure, but it was decided to
code this in its own function.
will need to be told the value of the change, and the value of the coin. Both of
these parameters will be passed by value, as it is only the values that are required. Internally
will not require any additional data, as it can calculate its output from the two
input values.
•
needs to be told the value of the change and the value of the coin, it can
then use these values to calculate the number of these coins that need to be given in the
change.
•
will output the number of the indicated coin that needs to be given in the
change.
The pseudocode for this procedure is shown in Listing 4.4.
Pseudocode
Entry Point (Main) The program’s code always performs the same task. It coordinates the
actions the program is performing. The pseudocode for this was shown in Listing 4.1. This
code will need to store the value of the change. It will get the value to store in this by calling
. . It will call
for each of the coin values, and pass this variable to
the procedure for it to update. These actions are shown in Figure 4.17.
• The
(
%
needs a local variable to store the
. .
Thinking further about the program there are also the constant values of the different coins.
These values are almost taken for granted when you think about giving change yourself, but
remember the computer is unintelligent so you need to specify everything for it. The values of
the coins can be coded using a constant for each coin. Using constants is a better option than
hard coding these values directly in the program, as the name helps provide a context for the
value when it is used.
Note
• Notice that the functions and procedures are isolated from each other. They have
defined inputs and outputs, but their local variables are hidden within their code.
• This means you can focus on the function/procedure you are working on, and do
not have to think much about the details of the other functions/procedures in your
code.
♠
• Parameters allow you to pass data into a function/procedure.
• Passing a parameter by reference allows you to output a value by updating the vari-
able you are passed. This means a procedure can output values by having param-
eters passed by reference, and functions can also use this mechanism to update
values in variables as well.
177
CHAPTER 4. STORING AND USING DATA
Main
Get Change Value ( )
Change Value
(Change Value)
178
4.2. USING THESE CONCEPTS
179
CHAPTER 4. STORING AND USING DATA
In addition to these artefacts the program will make use of some procedures from the available
libraries. This will include the following:
• Output: You need to use your language’s procedures to write output to the Terminal.
• Input: Languages also provide a means of reading values from the user. In C and Pascal
these input procedures need to be passed the variables that you want the value assigned
to. This uses pass by reference to enable the input procedure to store the values read
into a variable for you.
C++
In C the input procedure to read values from the Terminal is called
, see C
♢
Terminal Input.
Pascal
In Pascal the input procedure to read values from the Terminal is called * $
, see
♡
Pascal Terminal Input.
Figure 4.16 shows the Structure Chart for the Change Calculator. This shows the structure of
the solution, visually showing the functions and procedures and the calls between them. This
diagram has been enhanced to show the parameter values being passed into the functions
and procedures, and the values being returned. These data flows are shown alongside the call
arrow, with their own smaller arrow to indicate the direction of the flow.
By reading Figure 4.16 you can tell that
is going to be a function as it is returning
data to %
.
could be a function or a procedure as it is accepting and returning
the
. , in this design it is a procedure, and updates the value in the
.
variable using pass by reference. You can also see that
and
both
require parameters to accept the data being passed into them.
The Structure Chart shows the static structure of the code, indicating the calls between the
functions and procedures, but not communicating when these are called, or how many times.
This dynamic information is captured in the Sequence Diagram shown in Figure 4.17. This
diagram shows the sequence in which the function and procedure calls are performed. Notice
that this diagram has also been enhanced to show the data that flows into and out of the
functions and procedures.
The Sequence Diagram indicates how values are being returned. The return of a function’s
value is shown by indicating the value on the returning arrow. Notice the indication of this
value on the arrow returning from the call to
. , this indicates that
. is a function. On the other hand, the brackets around the return value from
indicates that this is being performed by updating a parameter that was passed using pass
by reference. You can use this information to determine how the design intends these to be
coded. As
. is directly returning a value it must be a function,
updates a parameter and does not return a value itself so it must be a procedure.
Note
• A structure chart shows the static structure of the program. This tells you which
procedure/functions call which, and the data that is passed between them. It shows
you what is written in the code.
♠
• A sequence diagram shows the dynamic operation of a program. This tells you how
the functions and procedures interact to achieve some goal. It shows you what is
happening when the code is run.
180
4.2. USING THESE CONCEPTS
When you are designing a program you need to think about each function or procedure, and
determine if it requires data to be given to it to enable it to perform its action. Any data it
requires must then be passed to it using Parameters. The key to understanding parameters
is to remember that each function/procedure is its own isolated domain. It can have its own
data, using local variables, and has its own instructions. In most cases these instructions will
need to be given some starting data, some information upon which to act.
One strategy you can use to picture this is to put yourself in the place of the function, or
procedure. For example, what would you need to be told in order to determine the number of
coins to give in change for a single coin type. You can not work out the answer without being
told the value of the change to be given, and the value of the coin. With these two pieces of
information you now have enough to calculate the required output. For example, how many $2
coins should be given for $6.50 in change. These two pieces of data can be used to calculate
the answer 3. This is exactly what is being coded in the
function.
In this respect Procedures are the same. In order to give change, the
procedure
needs some information. It can not act without this information. If you needed to give change,
you need to be told something about the amount of change you are giving and the value of
the coin you are issuing. In this case,
needs to be told the
, the
, and the description of that coin. With these details the procedure can then code the
steps needed to produce its desired side effects.
Parameters are mostly used to pass a value into a function or procedure. However, in some
cases it is useful to pass in the variable rather than the value. This is the case when you want
the function or procedure to change the value in the variable passed to it. Take the
parameter in
as an example. When this procedure issues some coins, the
amount of change still to be given must be updated. For example, when you issue ‘3 x $2’ for
the $6.50 in change, the new change value will be 50c (650 − (3 × 200)). By passing the variable
into
it is possible for this code to change the value in the callers variable, ensuring
that the correct change is given.
One of the main keys to understanding programs, and to creating good designs, is to see
how each artefact you create models something from the problem. The procedures that you
create model the processes, performing actions that relate to the task at hand. The functions
model calculations that need to be performed, such as determining how many coins should be
given. In the same way the variables that you create will store values related to the problem.
Each variable represents something, some information related to your program. The thing it
represents should be reflected in the name given to the variable.
The act of trying to model the problem in software is called abstraction. It is the process of
determining the features of the problem that are essential to the solution, and capturing these
in a way that models reality but keeps only the details we care about. The ability to create
your own model is a skill that you learn with experience, taking a lot of practice to really
master.
Note
• A good design will closely model the program’s domain. You should be able to relate
♠
the artefacts you are creating with things related to the program.
181
CHAPTER 4. STORING AND USING DATA
The pseudocode from Listing 4.1 shows the instructions, and how these should be divided
between the
Function and '
Procedure. At this stage these
instructions need to be translated into source code, so that they can be compiled and the
resulting program tested.
The following two sections, Section 4.3 Storing and Using Data in C and Section 4.4 Storing
and Using Data in Pascal, contain a description of the syntax needed to create programs in the
C and Pascal programming languages that include Variable and Function declarations.
Note
Remember the basic process for reading the Syntax Diagrams is to:
1. Find the page with the Syntax rule you are interested in knowing about.
2. Have a quick look at the Syntax Diagram and the rules it contains. Read each rule,
and get a basic feel for how it is going to come together for your program.
3. Read the example to see one way of using the Rule. The Syntax Diagram can be
♠
used to create any number of variations of the rule, the example gives you at least
one way these rules can be coded.
4. Return to the diagram and make sure you can match each part of the example back
to the rule that created it.
5. Look up any related rules that are not explained on this rule’s page.
182
4.2. USING THESE CONCEPTS
Once you have completed your program, you need to compile and test it.
1. Open the Terminal5 program for your Operating System
2. Use the command to move to the directory with your code, for example
-
3. Run the compiler with your program’s code. See the language specific details below.
4. Fix any compiler errors, using the tips from Section 2.2.5 Compiler Errors.
5. Execute the program using +
and check the results
C++
The C compiler is called gcc. To compile your Change Calculator program you will need
to run the following:
♢
+
C++
C does not have support for pass by reference, though it can be achieved using other
means (see Chapter 8). The C++ language is an extension to C that fixed a number of
issues, as well as added some new features. One of the new features was built in pass by
reference. To compile the C++ version of the Change Calculator you need to use the C++
♢
compiler called g++. To compile your Change Calculator program you will need to run the
following:
Pascal
The Pascal compiler is called fpc. To compile your Change Calculator program you will
need to run the following:
♡
+
+
183
CHAPTER 4. STORING AND USING DATA
Now that our program is making greater use of data it becomes more important to think about
how to test your program. Testing is the process of trying to locate issues with your code.
There are two main classifications for issues, syntactic errors and semantic errors.
Syntactic errors indicate places in your code where you have not correctly followed the syntax
of the language. These are the easiest kind of error to find as the compiler will not be able to
compile the program if its syntax is not correct. The errors that the compiler report are all
syntax errors. As you gain experience with a Language you will find that you make fewer and
fewer of these kinds of errors.
Semantic errors, on the other hand, will not be found by the compiler. These are errors in the
logic within the program. They are cases where you have correctly structured the code, but
the code itself does not get the computer to perform the actions you require. These are the
kinds of errors that you need to learn to be able to detect yourself. Selecting the right kind of
test data is an important task when you start to think about testing programs.
For the Change Calculator there are two inputs provided by the user. In order to test this
program you need to determine the values that are passed to the ! and the
(
inputs. You want to choose values that can help you uncover any unexpected issues
with the programs code.
The data we use to test an execution of a program is called a Test Case. Each test case provides
a set of input values, and the expected results given this input. Example test cases for the
Change Calculator are shown in Table 4.2. This table shows the input values, the expected
output values, and some rational for why this test case should be run. To perform the testing
you run the program once for each test case and check the output of the program against the
expected output. If there are any differences you know that their is a problem, and need to
check the program’s code to find the source of the logic errors.
184
4.3. STORING AND USING DATA IN C
Section 4.2 of this chapter introduced the ‘Change Calculator’ program, and its design. Its
implementation requires the definition of functions as well as procedures. These functions
and procedures accepted parameters and use local variables.
This section of the chapter introduces the C syntax rules for implementing these concepts
using the C language. The C implementation of the Change Calculator is shown in Listing
4.5. To get support for pass by reference you need to use C++, an extended version of the C
language. This means that the C version is an alternate design, with
becoming
a function so that it can return the new change value. The C++ implementation is shown in
Section 4.3.2.
(
,/'7'$$*+
'&7'$$*
!,17&,+
,/&,17&,+
,&7&,+
*
!.7&,+
7
7
77
77
185
CHAPTER 4. STORING AND USING DATA
7
7 7
7
7 7
7 ,/'7'$$*+ $
7 7
7 '&7'$$* $
7 7
7 !,17&,+
7 7
7 ,/&,17&,+
7 7
7 ,&7&,+
7 7
7 !.7&,+
4
Listing 4.5: C code for the Change Calculator
Note
• Save the C code in a file named
.
• Compile this using +
.
• Run the resulting program using +
.
• Perform each of the Test Cases from Table 4.2 and check that the output matches
the expected values.
• Look over the code and examine how the Variables, Parameters, Constants, and
Function are being used.
♠
*
186
4.3. STORING AND USING DATA IN C
C++ contains a number of extensions that can make programming in C easier. One of these
extensions is the ability to use pass by reference. The code in Listing 4.6 shows the C++
implementation of the Change Calculator. In this code
is a procedure with the
parameter being passed by reference.
(
,/'7'$$*+
'&7'$$*
!,17&,+
,/&,17&,+
,&7&,+
!.7&,+
*
7
7
7
77
77
7
7 7
7
7
7 ,/'7'$$*+ $
7
7 '&7'$$* $
7
7 !,17&,+
7
7 ,/&,17&,+
7
7 ,&7&,+
187
CHAPTER 4. STORING AND USING DATA
Listing 4.6: C++ code for the Change Calculator
Note
• Save the C++ code in a file named
.
• Compile this using +
.
• Run the resulting program using +
.
• Perform each of the Test Cases from Table 4.2 and check that the output matches ♠
the expected values.
• Look over the code and examine how the Variables, Parameters, Constants, and
Function are being used.
*
188
4.3. STORING AND USING DATA IN C
A Variable Declaration allows you to create a Variable in your Code. In C you can declare
variables in the program’s code, and in Functions and Procedures.
expression
C++
*
( 7
,
(!
7
7
7
7
7
7
7 4
7
7
4
7
7
4
7 7
♢
7
7
7 (! 7 7
4
7
4
7 7
(!
4
(!
Listing 4.7: Variable Declaration Tests
189
CHAPTER 4. STORING AND USING DATA
Note
• This is the C Syntax for creating your own Variable.
• This syntax can be used to declare . . .
– Local Variables within Functions and Procedures.
– Global Variables within the program.
• In C the Variable Declaration starts with the Type name indicating the kind of data
that will be stored.
• Following the Type is a list of the identifiers for the Variables that are being created.
You can create one or more variables in a single Variable Declaration, but all of these
Variables will have the same type.
♠
• Each variable can be assigned a value when it is declared.
• The const modifier can be added to the start of a Variable declaration to create a
Constant.
• See C Procedure Declaration (with Local Variables) for details on declaring Local
Variables within Functions and Procedures.
• See C Program (with Global Variables and Constants) for details on declaring Global
Variables within the program itself.
• The syntax for declaring Parameters is very similar, see C Procedure Declaration
(with Parameters).
*
190
4.3. STORING AND USING DATA IN C
You can declare global variables and constants within a C Program file.
header include
hash define
value
declarations
procedure declaration
variable declaration
*
Figure 4.19: C++ Syntax for a program (with global variables and constants)
Note
• This syntax allows you to declare Global Variables and Constants.
• See Listing 4.7 for an example of declaring Global Variable and Constants.
• In Listing 4.7 . . .
– and
are Global Variables. These can be accessed in
both the procedure and
.
– (! is a Global Constant, with the value 3.1415. This can be read in both the
procedure and
.
• Global variable should be avoided.
• Global constants can be declared in two ways, using a C Variable Declaration with
♠
the
modifier or using
.
• See Listing 4.8 for an example of
and constants.
• With
you are defining a ‘value’ for the identifier, this identifier is then substi-
tuted with the ‘value’ throughout your code. This means you have to pay particular
attention to what ‘value’ you use.
• There are a number of conventions, called coding standards, that describe how your
code should appear for a given language. In this text we will use a common C conven-
tion of having all Constants in UPPER CASE, with underscores ( ) used to separate
words. So the Maximum Height constant becomes %0!%-% ! ,.
191
CHAPTER 4. STORING AND USING DATA
C++
4
(! 7,'7*
4
7,'7*
Listing 4.8: C program with a defined constant, and constant variable
*
192
4.3. STORING AND USING DATA IN C
The Functions and Procedures in C can contain declaration for Local Variables.
variable decls.
variable declaration
statements
statement
Figure 4.20: C++ Syntax for Procedure Declaration (with Local Variables)
Note
• This is the syntax for declaring Local Variables in a Procedure.
• See Listing 4.7 for an example of declaring Local Variables.
• In Listing 4.7 . . .
*
– The procedure has two local variables: and
.
– The
function has one local variable called
.
• The Local Variables must be declared before the statements within the Function and ♠
Procedure’s block.
• In C you cannot declare variables after the first statement in the block.
• In this text we will use a common C convention of having all Local Variables in lower
case, with underscores ( ) used to separate words. So the My Name local variable
becomes
.
193
CHAPTER 4. STORING AND USING DATA
post increment
post decrement
pre increment
pre decrement
Note
• This is the C syntax for the Assignment Statement.
• In C assignment is indicated by the equals sign ( = ).
• The left hand side of the assignment must be a valid variable, this is where the value
is to be stored.
• The right hand side of the assignment is an expression, this calculates the value
that will be stored in the Variable.
• There are multiple versions of the assignment, giving short hand ways of using the
current value.
– is the standard assignment, this stores the value of the expression in the
Variable. ♠
– increments the variable’s value,
is equivalent to
– decrements the variable’s value,
is equivalent to
– multiplies the value in the variable by a given factor.
is equivalent to
– divides the value in the variable by a factor.
is equivalent to
• The and operators allow a variables value to be increments or decremented.
194
4.3. STORING AND USING DATA IN C
C++
7
7
7
7 4
7
7
7
7
7
'
4
7
7
*
7
7
7
7
,
4
7
Listing 4.9: Assignment Tests
195
CHAPTER 4. STORING AND USING DATA
parameter list
parameter declaration
variable decls.
variable declaration
statements
statement
Note
• The syntax in Figure 4.22 shows the C code for declaring Procedures with Parame-
ters.
♠
• Parameters in C are declared in a similar way to other Variables, with the Type name
appearing first followed by the Parameter’s name.
C++
♢
7
7
Listing 4.10: Assignment Tests
196
4.3. STORING AND USING DATA IN C
C has limited support for pass by reference, but this feature was added with the extensions in
the C++ language. The following syntax shows how to declare a parameter that will be passed
by reference. Please note that this is not standard C code, and will require you to use a C++
compiler.
C++
*
!
4
7
4
Listing 4.11: Example of passing by reference using C++
Note
• This requires a C++ compiler, such as the compiler.
• C++ to an extension of the C compiler, so your C code should be able to be compiled
with the C++ compiler.
• The C++ compiler is more strict on some rules than the C compiler. This means the ♠
compiler will give you more help in avoiding some poor programming practices.
• Notice that with pass by reference you do not need to do anything special in the call,
the compiler takes care of the necessary details needed to achieve this.
197
CHAPTER 4. STORING AND USING DATA
Many languages support pass by reference in the compiler. This is where the compiler manages
the passing of the reference for you in the background. Unfortunately C does not do this
transparently and you need to manually pass the reference yourself. Its good to know that
the concept remains the same, but it does mean that you must manually add code to achieve
this.
argument
argument expression
variable name
Figure 4.24: C++ Syntax for Procedure Call (with pass by reference)
Note
• With C you must manually pass parameters by reference using the ampersand ()
operator.
• C++ does have support for pass by reference, see C++ Reference Parameters.
• The ampersand () operator gets the address of the variable given to it, in effect you
♠
*
manually fetch the reference to the variable and pass that as the argument.
• Passing the address of a variable allows the called code to use that address to find
your Variable’s value. The code can read and store values in this Variable for you.
• Reading input from the Terminal is one of the common use of pass by reference.
C++
,
4
1
4
Listing 4.12: Testing Pass by Reference in C
198
4.3. STORING AND USING DATA IN C
C comes with a range of Librarys that provide reusable programming artefacts, including
reusable Function and Procedures. The refers to the Standard Input/Output library,
and including code to read input from the Terminal. The
function is used to read data
from the Terminal.
Function Prototype
Returns
The number of values read by
.
Parameter Description
The format specifier describing what is to be read
from the Terminal. See Table 4.4.
*
The
function is controlled by the parameter. This parameter tells
what
it must read from the input. Details of how to construct the String are shown in
Table 4.4.
width modifier
199
CHAPTER 4. STORING AND USING DATA
C++
(
,
♢
Listing 4.13: Example of reading data using
.
*
200
4.3. STORING AND USING DATA IN C
*
Type Data Read Example Usage
A single character.
or Decimal integer. This is able to read a
starting + or - if present.
Decimal floating point number. Can be
signed, or in scientific notation.
Text data. Should be preceded by the
number of characters to read. The c-
string must have sufficient space to store
the data reada .
3
5 Text data. As with , but this allows you
3
5
7
to specify the pattern of characters that
can be read.
36
5 Text data. As with , but this allows you
36∖
5
to specify the pattern of characters that
can not be read.
a This will be covered in future chapters.
Table 4.5: Details for ’s Format Tag type, specifiers, modifiers, and width
201
CHAPTER 4. STORING AND USING DATA
header include
hash define
value
declarations
procedure declaration
function declaration
variable declaration
C++
♢
7
(
7
,
4
77
Listing 4.14: Example of declaring a Function in a C Program.
Note
• A C program may contain declarations for custom Functions.
♠
• The Function must be declared before it is used.
202
4.3. STORING AND USING DATA IN C
parameter list
parameter declaration
C++
*
♢
4
Listing 4.15: Example Function Declaration of a Function.
Note
• In C Function and Procedure declarations are very similar.
• In C, a Function’s declaration starts with the Type of data the Function will return.
• This if followed by the name of the Function, and its Parameters. In the same way
as is done in the C Procedure Declaration (with Parameters).
• The body of the function is a
, in the same was as a C Procedure Declaration
(with Parameters).
• See C Function Call for the syntax needed to call your functions.
♠
• See the Return Statement to see how to return a result from a function in C.
• is a type, so in C functions and procedures are identical. See C Procedure
Declaration (as Function) to see how C handles procedures.
• The entry point of the program is the
function. It returns a number to the
Operating System that can be used to indicate the success or failure of the program.
You can read the value returned from the last program to execute in the Terminal
using $ .
203
CHAPTER 4. STORING AND USING DATA
C does not have a strong separation of Functions and Procedures. Instead, in C all Procedures
are Functions that return a special Type. This means that the standard C Syntax does
not include a separate definition for Procedure declarations. Even though C does not have
direct syntax for Procedures, the concept is still very important.
Note
• In C all Procedures are Functions that return a type.
• The type indicates an empty type. This indicates that Procedures return no ♠
data to the caller.
*
204
4.3. STORING AND USING DATA IN C
argument
argument expression
variable name
C++
*
♢
4
4
4
Listing 4.16: Example of Function Calls.
Note
• A C function call is similar to a Procedure Call.
• You use the name of the Function, its identifier, to indicate which function is called.
• Following the Function’s name is the list of arguments, these are the values (or vari-
ables) that are being passed to the called Function.
• The return type of the Function determines where the Function may be called.
– Procedure, Functions, can only be called in a Procedure Call Statement.
– Other Functions can be used in Expressions, see Expressions (with Function
♠
Calls, Variables, and Constants). In these cases the type of data returned by
the Function will determine the type of the Function Call.
• In Listing 4.16 the values of the inner function calls are passed to the arguments of
the outer calls. This means that
is calculated first then . The
results of these two Function Calls are then passed as the arguments into the call
to the Function. In this case the Function call will be
with
being
the result returned by
and being the result returned by .
205
CHAPTER 4. STORING AND USING DATA
expression
C++
7
4
♢
7
4
7
*
Note
• The Return Statement is used to end a Function, or Procedure, and to return a value.
• Procedures can end completing all of their instructions.
• Functions that return a value must have a
to indicate the value to be returned
by the caller.
• The Expression in the Return Statement is optional so that you can use the statement
♠
to end a Procedure.
• When the Return Statement is executed the current Function or Procedure ends,
and the value of the Expression is returned to the Function Call.
• Listing 4.17 illustrates the point that
ends the current function, with only
the first
call being run in the
Function.
206
4.3. STORING AND USING DATA IN C
The different statements of a Programming Language allow you to command the Computer to
perform different actions. We have covered three kinds of statements so far.
assignment statement
return statement
Note
• At this point you have seen how to command the computer to:
– Call a Procedure ( Function) using a procedure call.
– Assign a value to a Variable using an Assignment Statement.
– End the current Function or Procedure, and return a value to the caller using ♠
a Return Statement.
• These Statements can be placed within the blocks of the Functions and Procedures
of your Programs.
*
207
*
4.4. STORING AND USING DATA IN PASCAL
Section 4.2 of this chapter introduced the ‘Change Calculator’ program, and its design. Its
implementation requires the definition of functions as well as procedures. These functions
and procedures accepted parameters and use local variables.
This section of the chapter introduces the Pascal syntax rules for implementing these concepts
using the Pascal language. The Pascal implementation of the Change Calculator is shown in
Listing 4.18.
,/'7'$$*+
'&7'$$*
!,17&,+
,/&,17&,+
,&7&,+
!.7&,+
( *
.
'!
%
. !
.
.
209
CHAPTER 4. STORING AND USING DATA
%
Listing 4.18: Pascal code for the Change Calculator
Note
• Save the Pascal code in a file named +
.
• Compile this using +
+
.
• Run the resulting program using +
.
• Perform each of the Test Cases from Table 4.2 and check that the output matches
the expected values.
• Look over the code and examine how the variables, parameters, constants, and func-
♠
tion are being used.
• Notice how the indentation makes it easy to see where each function and procedure
starts and ends. Always lay your code out so that it is easy to see its structure.
( *
• See how the function and procedure are declared before they are used. This is im-
portant as the Pascal compiler reads the code from the start, and must know about
the artefacts before you use them.
210
4.4. STORING AND USING DATA IN PASCAL
You can declare global variables and constants within a Pascal Program file.
uses clause
decl. part
constant declarations
procedure declaration
variable declarations
( *
variable decl. identifier type name
expression
Figure 4.32: Pascal Syntax for a program (with global variables and constants)
Note
• This syntax allows you to declare Global Variables and Constants.
• See Listing 4.19 for an example of declaring Global Variable and Constants.
• In Listing 4.19 . . .
– and !
are global variables. These can be accessed in both
the procedure and
procedure.
– (! is a global constant, with the value 3.1415. This can be read in both the
♠
procedure and
procedure.
• Global variable should be avoided.
• There are a number of conventions, called coding standards, that describe how your
code should appear for a given language. In this text we will use a common Pascal
convention of having all Constants in UPPER CASE, with underscores ( ) used to
separate words. So the Maximum Height constant becomes %0!%-% ! ,.
211
CHAPTER 4. STORING AND USING DATA
Pascal
(!
+
!
!
, !
(! !
!
( *
%
Listing 4.19: Example variable and constant declarations
212
4.4. STORING AND USING DATA IN PASCAL
The functions and procedures in Pascal can contain declaration for Local Variables.
decl. part
variable declarations
Figure 4.33: Pascal Syntax for Procedure Declaration (with Local Variables)
( *
Note
• This is the syntax for declaring Local Variables in a procedure.
• See Listing 4.19 for an example of declaring local variables.
• In Listing 4.19 . . .
– The procedure has two local variables: $ and
$ .
– The
function has one local variable called !
.
♠
• The local variables are declared before the procedure’s statements.
• In this text we will use a common Pascal convention of having all local variables
in camel Case, where the first character is lower case but subsequent words in the
identifier start with an upper case character. So the My Name local variable becomes
& .
213
CHAPTER 4. STORING AND USING DATA
Note
• This is the Pascal syntax for the Assignment Statement.
• In Pascal assignment is indicated by a colon followed by an equals sign ( ).
• The left hand side of the assignment must be a valid variable, this is where the value
is to be stored.
• The right hand side of the assignment is an expression, this calculates the value
that will be stored in the variable.
( *
• There are multiple versions of the assignment, giving short hand ways of using the
current value.
– stores the value of the expression in the variable. ♠
– increments the variable’s value,
is equivalent to
– decrements the variable’s value,
is equivalent to
– multiplies the value in the variable by a factor.
is equivalent to
– divides the value in the variable by a factor.
is equivalent to
214
4.4. STORING AND USING DATA IN PASCAL
Pascal
%
!
!
%
*
!
/$
' '
/$
' '
/$
' '
♡
/$
' '
!
%
!
%
/$
''
' !
%
'
'
( *
%
Listing 4.20: Sample assignment statements
215
CHAPTER 4. STORING AND USING DATA
expression
Note
• The syntax in Figure 4.22 shows the Pascal syntax for declaring procedures with
Parameters.
• Parameters in Pascal are declared in a similar way to other variables.
• Pascal supports passing parameters by reference and by value. The parameters in
Listing 4.21 are all passed by value.
• There are three ways of passing references by reference in Pascal (see Listing 4.22
for examples of these):
♠
– const: The parameter is passed a reference to the variable, but cannot change
its value. This can be used to pass a value in to the procedure by reference.
– out: The parameter is passed a reference to the variable, but cannot assume
it contains a meaningful value. This can be used to pass a value out to the
procedure by reference.
– var: The parameter is passed a reference to the variable. This can be used to
pass a value in and out of the procedure by reference.
216
4.4. STORING AND USING DATA IN PASCAL
Pascal
( ,
Pascal
( ,
( *
,'* ' !
/$
'!
'
/$
'!
'
/$
' !
'
'
%
!
,'*
,!
*
,!
'*
/$
'
'
%
Listing 4.22: Example of the different parameter types
217
CHAPTER 4. STORING AND USING DATA
Pascal comes with a range of Librarys that provide reusable programming artefacts, including
reusable Function and Procedures. The + unit includes procedures to read input from
the Terminal. The * $
procedure is used to read data from the Terminal.
Procedure Prototype
* $
Parameter Description
The * $
procedure takes a variable number of pa-
rameters. A value is read from the Terminal for each
parameters.
Pascal
&
%
+
!
( *
/ '
'
* $
/$
' '
♡
/ '
'
* $
/$
' ' ' ' ' '
%
Listing 4.23: Example of reading data from the Terminal
218
4.4. STORING AND USING DATA IN PASCAL
Your Pascal program can contain definitions for your own Functions.
uses clause
decl. part
constant declarations
function declaration
procedure declaration
variable declarations
variable declaration
( *
variable decls.
Note
• A Pascal program may contain declarations for custom Functions.
• The function must be declared before it is used. ♠
• See C Function Declaration for the Syntax for declaring your own Functions.
219
CHAPTER 4. STORING AND USING DATA
Pascal
(
( *
%
Listing 4.24: Example of declaring a function in a Pascal program
Note
• Listing 4.24 contains a program with a custom function that converts temperature
♠
from Fahrenheit to Celsius.
220
4.4. STORING AND USING DATA IN PASCAL
decl. part
variable declarations
( *
Pascal
,+
Note
• In Pascal Function and Procedure declarations are very similar.
• In Pascal, a function’s declaration includes the Type of data the function will return.
• This if followed by the name of the Function, and its Parameters. In the same way
as is done in the C Procedure Declaration (with Parameters).
• The body of the function is the same as a Pascal Procedure Declaration (with Pa- ♠
rameters).
• See Pascal Function Call for the syntax needed to call functions.
• Each Pascal function has a special variable, the value of this variable is re-
turned to the caller when the function ends.
221
CHAPTER 4. STORING AND USING DATA
argument
argument expression
Pascal
,
%
♡
!
/$
'
'
/$
'
' + +
+
/$
'
' + +
%
Listing 4.26: Example function calls
Note
• A function call can be used to calculate a value within an expression.
• A Pascal function call is similar to a Procedure Call.
• You use the name of the Function, its identifier, to indicate which function is called.
• Following the function’s name is the list of arguments, these are the values (or vari-
ables) that are being passed to the called function.
♠
• In Listing 4.26 the values of the inner function calls are passed to the arguments of
the outer calls. This means that +
is calculated first then + . The
results of these two function calls are then passed as the arguments into the call to
the + function. In this case the function call will be +
with
being the
result returned by +
and being the result returned by + .
222
4.5. UNDERSTANDING DATA
This Chapter has introduced the idea of creating Variables within your program’s code to store
values. These variables can be stored in Global or Local Variables, and passed to Functions
or Procedures using Parameters.
This Section will help you answer the following questions:
• How do local and global variables work?
• What happens with Parameters when Functions and Procedures are called?
• How do Function’s return a value?
• How does Pass by Reference work?
• How can I demonstrate or check the execution of a program with Variables?
4.5.1 Variables
To get started let us have a look at the basic concept of Variables. Rather than working through
the Change Calculator program we can use a simpler program to start with. Understanding
this will then help you understand what is happening in the Change Calculator. The program
we will use is in Listing 4.27. This program will contain two variables that are local to the
function in C or the %
procedure in Pascal: and
.
Pseudocode
.
!
♣
+
'
,
Listing 4.27: Pseudocode illustrating variable use
To get started understanding this let us return to the Conceptual Computer we have been
using to explain how these concepts work.
• Test Assignment’s Program Launches, putting Main on the Stack.
• The assignment statement stores a value in the Variable.
• The second assignment statements stores a value in the
Variable.
• The values of the Variables are output to the Terminal.
223
CHAPTER 4. STORING AND USING DATA
When the program starts space is allocated on the Stack for the program’s Main Function or
Procedure. When a Function or Procedure has Local Variables, these are also allocated onto
the Stack.
----------------------------
Main is loaded onto Procedure: Write Procedure
the Stack ----------------------------
...
1 Program: Test Assignment
----------------------------
Variables: Variables are allocated
Main * val (Integer) space on the Stack
* range (Double) 2 within Main
val: 207 Steps:
1: Assign to val, 23
range: 167.0192371 2: Assign to range, 1 + val / 100
3: Output val and range to the Terminal
Current Instruction:
Note
• The program’s instructions are loaded into memory when the program is executed.
• In Figure 4.39 the indicated areas show the following:
1. When the program starts, %
is loaded onto the Stack. This keeps track of all
of the details related to the execution of %
.
2. The Variables that are declared in %
are allocated space on the Stack.
• The two aspects of the Variable are shown in the illustration. The variable is the
box drawn next to its name. The value is then written within the Variable.
♠
• Notice that the variables each have a value to start with, even though the code has
not yet assigned a value. The variable is allocated memory into which its value will
be stored. Memory is not automatically cleared after its use, so the variables will
get whatever value happened to be at that location previously.
• Each Variable is allocated enough space to stores its value. The Variable needs
32 bits to store an !
value, whereas the
Variable needs 64 bits to store
its value.
224
4.5. UNDERSTANDING DATA
The first action of this program is to store the value 23 in the Variable.
----------------------------
Procedure: Write Procedure
----------------------------
...
First Instruction
is executed
1
Note
• In Figure 4.40 the indicated areas show the following:
1. The Assignment Statement is executed. This code has two sides. The right hand
side executes first and needs to evaluate the Expression. Next the left hand side
is used to determine where the resulting value needs to be stored. ♠
2. The value of the Expression is the Literal value 23.
3. 23 is stored in the Variable.
• Once this line of the program has executed the variable now has the value 23.
225
CHAPTER 4. STORING AND USING DATA
The next step in the program is to store the value in the
Variable. This
must read the value from the Variable to determine the value to be stored.
----------------------------
Procedure: Write Procedure
----------------------------
...
1 Second Instruction
Value is stored in the is executed
5 range variable.
Note
• In Figure 4.41 the indicated areas show the following:
1. The Assignment Statement is executed. As before, this needs to evaluate the
Expression on the right hand side and store the result in the Variable on the
left hand side.
2. The first step to performing the assignment is to evaluate the expression. This
♠
requires the value from the Variable.
3. Within the Expression the value of is read. At this point in the program
has the value 23.
4. The Expression is now
, giving the result
.
5. The calculated value is then stored in the
Variable.
226
4.5. UNDERSTANDING DATA
The third, and final, instruction in the program’s main function or procedure is to output
the values of each of these variables to the Terminal. This uses the values from within the
Variables to determine what is output.
----------------------------
Procedure: Write Procedure
----------------------------
...
1 Third Instruction
is executed
23 1.23
5
Output appears in
Terminal
Note
• In Figure 4.42 the indicated areas show the following:
1. The final instruction is a call to the output procedure of the language. This
must be passed the data to output.
2. The Write Procedure is passed a number of values to output.
3. The values of the Variables will be read to get the argument values to pass. ♠
4. The values read from the Variables are then passed to the Write Procedure
(
in C, or /$
in Pascal).
5. When the / ( finishes its task the values will have been written to
the Terminal.
227
CHAPTER 4. STORING AND USING DATA
There are three locations at which you can declare variables. Global Variables are declared
within the program, Local Variables are declared within Functions and Procedures, and Pa-
rameters are used to pass values into Functions and Procedures.
Pseudocode
.
!
( , (
(
!
.
!
+
'
♣
.
!
+
, (
'
,
Listing 4.28: Pseudocode used to examine how Global Variables, Local Variables, and Parameters
work
Listing 4.28 is the code that we will use to demonstrate how these Variables work when code
is executed by the Computer. This program does not have any meaningful purpose beyond
interacting with Global Variables, Local Variables, and Parameters, so do not read too much
into the actions being performed. What is important is to examine how the different variables
work when the code is executed.
This Section will examine these Variables by looking at the following:
• Memory Partitions include space for Global Variables
• Program is loaded into memory
• Initial Commands Occur
• Passing Parameters in a Procedure Call
• Test Params Commands are Executed
• Control returns to Main when Test Params ends
228
4.5. UNDERSTANDING DATA
When the program is executed the Operating System allocates it space in memory. This space
is partitioned into different areas, with each area storing an aspect of the program’s data or
instructions.
Globals 4
The Program's
Memory
1
Figure 4.43: Memory is partitioned into spaces for the Code, Stack, and Global Variables
Note
• In Figure 4.43 the indicated areas show the following:
1. The program’s memory is allocated by the Operation System, and divided into
areas to store different kinds of values.
♠
2. The program’s instructions are loaded into the Code Area.
3. The Stack is used to manage the execution of Functions and Procedures.
4. Global Variables are stored in their own area of memory.
229
CHAPTER 4. STORING AND USING DATA
When the program is executed its global variables are allocated space, and then the main code
is executed.
evil: 1263
Figure 4.44: The Global Variables are allocated space, then the Entry Point is loaded onto the Stack
Note
• In Figure 4.44 the indicated areas show the following:
1. The global variables are allocated space when the program is loaded. Some Op-
erating Systems ensure that this memory is cleared by zeroing each value, but
♠
others do not so you cannot rely upon the value these variables will have when
they are loaded unless you initialise it yourself with an Assignment Statement.
2. The main code is then loaded onto the Stack, with space for its local variable.
230
4.5. UNDERSTANDING DATA
The program executes each of the statements, one at a time. Figure 4.45 shows the val-
ues in memory by the time the Computer has completed the execution of the first two com-
mands.
evil: 1
Note
• In Figure 4.45 the indicated areas show the following:
1. This picture is showing the computer at the point just before it executes the call
to , ( .
♠
2. The first assignment statement assigned the value to the Global Variable.
3. The second assignment statement assigned the value to the Local Vari-
able.
231
CHAPTER 4. STORING AND USING DATA
At this point the Computer is executing the call to , ( . This involves passing a value
to the parameter.
evil: 1
Figure 4.46: The value of the Argument is passed to the Parameter when the Procedure is called
Note
• In Figure 4.46 the indicated areas show the following:
1. The Computer calls the , ( procedure. This must be passed a single
value that will be copied into the Parameter.
2. The first part of the call requires the Computer to evaluate the Expression be-
ing passed to the Procedure. In this case that involves reading the Local
Variable and passing its value to the Parameter.
♠
3. Once the values for the Parameters are determined, the next step is to allocate
space for , ( on the Stack. Within , ( there will be space
allocated for the parameter, as well as space allocated for the Local
Variable. The value of the argument is copied into the parameter, and the called
Function or Procedure’s code can now execute. In this case the value is stored
in .
232
4.5. UNDERSTANDING DATA
The commands in , ( are executed one at a time. These instructions will interact with
the Variables that are visible to the , ( Procedure, which include its Local Variables
as well as the Global Variables.
evil: 0
1 0 1
Note
• In Figure 4.47 the indicated areas show the following:
1. Each instruction is executed one at a time. This picture shows the instructions
at the end of the last instruction in , ( before it ends.
2. The steps of the Procedure are able to read and write values to the Function or
Procedure’s Parameters and Local Variables, as shown here.
3. The Procedure is also able to read and write values to the Global Variables. ♠
• Notice that , ( cannot see the Variable. It exists within the %
code
and cannot be accessed from other Functions or Procedures.
• You can decrease the value of a Variable using an Assignment Statement. For exam-
ple ‘
’. This will read the current value from the
Variable, subtract one from that, and then store the result back in the variable.
233
CHAPTER 4. STORING AND USING DATA
When , ( ends control returns to the program’s main code. The space allocated to
, ( is now released, including the space allocated to the Parameter and the
Variable.
evil: 0
1 0 1
1 0
Note
• In Figure 4.48 the indicated areas show the following:
1. Control returns to %
when , ( ends.
2. Notice that the value of the Global Variable has changed as a side effect
of running , ( . This is easy to follow in a small program, but can
cause difficulties when you start building larger programs. As a result, Global
Variables should be avoided.
♠
3. The last instruction in the main code outputs the values of and to the
Terminal.
• The value within has been passed to the Parameter in , ( . This
copies the value, not the . , as it is using the standard Pass by Value mech-
anism. This means the code in , ( has no way of affecting the value in the
Variable.
234
4.5. UNDERSTANDING DATA
The next kind of data is the result returned by a call to a Function. A Function is just like a
Procedure, except that it calculates a value and is therefore called from within an Expression.
To examine how this works within the Computer we will see how the code in Listing 4.29
executes. This code declares a + function that calculates the square of a number (
passed in as a Parameter).
Pseudocode
+
*
!
(
!
+ ♣
*
.
!
+
+
'
,
Listing 4.29: Function example, to illustrate how data is returned from a Function
This Section will examine how Functions return values by looking at the following:
• Test Functions is loaded into memory
• Square Function is Called
• Square’s result is calculated
• Returned value is used
235
CHAPTER 4. STORING AND USING DATA
When the program is executes the Operating System loads its code into memory, and starts
the main code running on the Stack.
Figure 4.49: Code is loaded into Memory and Main is loaded onto the Stack
Note
• In Figure 4.49 the indicated areas show the following:
1. Main is loaded onto the Stack, with space for its
local variable.
♠
• Notice the Global Variables section is empty as this program does not use Global
Variables.
236
4.5. UNDERSTANDING DATA
The + function is called in the same way that a Procedure would be called. It is given
space on the Stack, and its instructions are run.
Figure 4.50: + is called, with the value 5 passed to its Parameter
Note
• In Figure 4.50 the indicated areas show the following:
1. When the main code calls + it passed in the value
, calculated simply by
reading the Literal value.
2. + is added to the top of the Stack, and its parameter is assigned the
value passed in from the Function Call. In addition to any Parameter and Local
♠
Variables the Function also has space for its . This will be the value
returned to the caller when the Function ends.
• The value of the result will initially be whatever happens to be at that location in
memory the last time it was used. You must make sure you assign a value to this
within the Function.
C++
In C the Return Statement assigns the value returned by the Function. There is no
special Variable that you can interact with. Conceptually, however, the value must
♢
be stored in order to be returned by the Function. In C the compiler takes care of these
details for you.
237
CHAPTER 4. STORING AND USING DATA
Figure 4.51: + prepares the value that will be returned to the caller
Note
• In Figure 4.51 the indicated areas show the following:
1. The expression ‘ ’ is evaluated. This reads the value of the variable
twice and multiplies the two values read. In this case this will calculate ‘
’, ♠
giving
.
2. The result of the expression is returned, setting the Function’s result.
C++
In C this is accomplished with the Return Statement. It assigns the result for the function
♢
and ends the Function at the same time.
Pascal
In Pascal you directly store the value in the special Variable. This will not end the
♡
Function directly, but does store the value to be returned by the Function.
238
4.5. UNDERSTANDING DATA
When the Function ends, control is returned to the main code. This called the Function in
order to evaluate an Expression. That expression will now continue to be evaluated using the
value returned by the Function.
Function: Square
1 ----------------------------
Returns: An Integer
result: 25
Parameters:
1: val (Integer)
Steps:
1: Returns the result, val * val
Main
Variable:
answer: 25 *: answer (Integer)
Steps:
Current Instruction: 1: Assign to answer, Square( 5 )
2: Output answer to the Terminal
2
The expression's value
is stored in answer
Figure 4.52: The result of calling + is used within the Expression, and the value is stored in
Note
• In Figure 4.52 the indicated areas show the following:
1. The result of the Function is made available to the caller. This will be read as
part of the Function Call, and is then used within the Expression.
2. In this case the Expression does not alter the value returned by the Function,
and the result is stored in the
variable.
• The expression that contains the Function Call can operate on the result returned
♠
from the function in the same way that it uses any other value. For example, the
following expression is valid: +
+ +
.
• The key is to think of each Function Call as a value. So nested Function Calls like
+ +
can be broken down into their individual values. In this example
+
is evaluated first, and returns the value . This is then passed to the outer
Function Call giving + and a final result of .
239
CHAPTER 4. STORING AND USING DATA
Working with data involves working with Variables of one form or another. When thinking
about Variables it is important to realise the two aspects of each Variable: the Variable and
its value. The Variable is a location in memory, it is a place at which you can store a value.
The value within the Variable is a separate concern. This value can be read from the Variable
in Expressions.
Pseudocode
.
!
+ ♣
' '
' ,
*
' '1
'
,
Listing 4.30: Example used to illustrate how Pass by Reference works with the standard input
Functions and Procedures.
This Section will examine how Pass by Reference works by looking at the following:
• Main starts and a prompt is written for the user
• The Input Procedure is called to read a value into
• The Input Procedure stores the value read from the user into
• Control returns to Main and has been updated with the value from the user
C++
In C the * !
( is the
Function. This requires that you pass in
a format string that indicates what will be read as well as passing in the Variables into
♢
which these values will be stored. You can read about this in C Terminal Input. Step 2
from Listing 4.30 can be implemented in C using
.
240
4.5. UNDERSTANDING DATA
The Program starts as normal with the Operating System allocating space for the Stack,
Code, and Global Variables. Main is then loaded onto the Stack and its instructions are
executed.
Instructions get to
the call to the Read
Input Procedure
2
Figure 4.53: Code is loaded into Memory, Main is started, and the first instruction outputs a prompt
Note
• In Figure 4.53 the indicated areas show the following:
1. Main is loaded onto the stack, with space for the Variable.
2. The first instruction outputs ‘Enter your age: ’ to the Terminal. ♠
• When writing a prompt it is a good idea to keep the output on a single line. Just
write the prompt without writing a new line.
241
CHAPTER 4. STORING AND USING DATA
The next instruction in the main code is to call the Language’s input procedure to read a value
from the user and to store that value in the variable. In order to achieve this you must
pass the variable itself to this procedure. That will enable the input code to store the value
it reads into the variable that you give it.
Figure 4.54: The input procedure starts, and the age Variable is passed to the Parameters
Note
• In Figure 4.54 the indicated areas show the following:
1. A variable is a location in memory, so it is not possible to actually move this
location into the Parameter. What happens instead is that you pass the address
of the Variable to the Parameter. This is why it is commonly called Pass by
Reference, you are passing a reference to the Variable, in effect telling it where
the Variable is that you want the data stored in.
♠
2. The value passed to the Parameter is then the address of the Variable where
the data should be stored. This Parameter is now storing the location of the
Variable.
3. An good way to picture this is as an arrow, or a pointer, that points from value
within the Parameter to the Variable. This helps visualise the fact that this
Parameter is storing the location of the Variable.
C++
In C you must manually get the address of the variable using the ampersand (&) operator.
So the call
in Main is passing the address of . You can read ♢
as ‘The address of age’.
242
4.5. UNDERSTANDING DATA
The Input Procedure stores the value read from the user into
The language’s input procedures are responsible for reading values from the user and storing
these into Variables for you. The instructions in this code will do the work to convert the data
from the text the user enters into the types required by the Variables the values are being read
into.
4
The value read from
standard input is assigned
to the age Variable that
was passed to the Parameter
Figure 4.55: Within the input code the address is used to find where to store the value read from the
user
Note
• In Figure 4.55 the indicated areas show the following:
1. The input code waits for the user to enter a value at the Terminal. Once the
value is entered it is scanned and stored in the Variables passed to the Input
Procedure.
2. The input code needs to work out where the values read are to be stored. It does
this by looking up the address stored in its Parameter. ♠
3. The address is used to locate the Variable into which the value will be stored.
4. In this case the Parameter has the address of the variable, and therefore the
value read from the user is stored into Main’s Variable.
• The language’s Input Procedures can be used to read in more than one value at a
time. In these cases the inputs code will read values for each Variable one at a time.
C++
In C you are responsible for determining how the data read is interpreted. This is the
purpose of the format string passed as the first parameter to
. In
♢
the indicates that the first Variable needs to be assigned a decimal integer value.
243
CHAPTER 4. STORING AND USING DATA
Control returns to Main and has been updated with the value from the user
When control returns to the main code, the variable has been updated to include the
values read from the user.
Figure 4.56: Control returns to Main, and the value of age has been updated by the input code
Note
• In Figure 4.56 the indicated areas show the following:
1. Control returns to %
when the input code completes.
2. The value from the Variable is then passed to the Output procedure. ♠
• Pass by Reference is used when you want to pass the Variable, but in most cases
you only want to pass the value so most code uses Pass by Value.
244
4.5. UNDERSTANDING DATA
One valuable skill you need to develop is the ability to step through a program in the same
way the computer will. You will find that this skill will get more and more important as you
progress to write larger programs. You will use this skill to help you detect and correct any
semantic errors, in a process commonly referred to as debugging.
Semantic errors are errors in the logic of your program. This means that the program compiles,
but does not do what you want it to. The tests that you use will help you locate these errors,
but in many cases you will need to work out why the error is occurring so that you can make
the required changes.
One of the better techniques to help you make these corrections is to reading your code, and
to think about the actions the computer is performing. Often these errors only require one or
two lines of code to change, but before you can make these changes you need to identify where
the error is occurring, why it is occurring, and how you can correct the issue. By reading
your code, and hand executing it you have the best chance of working out where the problem
is, and why the problem is occurring.
These activities are very popular with Programming Tests, both in University subjects and
job interviews. Being able to execute some code by hand means that you really understand
what the code is doing. Once you have this level of understanding you just need to add some
imagination and experience to become a very valuable software developer.
Hand executing an entire program would take a very long time. As a result you want to narrow
down your search to one or two Functions and/or Procedures. You can use your Structure
Charts, or knowledge of the program’s structure, to help you narrow down your options. Think
about where the test failed, and where the code for this is located in your Program. With a
small program you are likely to know immediately where the issue is, but as the program size
grows it will become more difficult to know exactly where the problem is.
Listing 4.31 contains the pseudocode for a Procedure that will calculate and output the area
of a Trapezoid. Unfortunately this code contains a number of errors. The following sections
will demonstrate how to execute this procedure by hand. If this were a programming test you
may be asked a question such as:
‘What is the value in area when this program is run and the user enters 5 for base 1,
7 for base 2, and 4 for height?’
Executing this by hand will give you the necessary skills to be able to answer questions such
as this.
245
CHAPTER 4. STORING AND USING DATA
Pseudocode
Once you have located the Function or Procedure that you need to test you can start to execute
it. The main obstacle in most peoples way is, unfortunately, their brain. You are going to think
about what you wanted the program to do. This is something the computer cannot do. The
computer is unintelligent. It is a machine that does as you command. To run this program as
the computer does you will need to stop thinking and start doing as commanded.
Rules:
• Do not think about what you want or expect the program to do.
• Perform the commands as they are, one at a time
• You cannot remember anything that is not written down.
• Focus only on the current command (Statement). Do not look at other Statements!
• Perform the actions you are commanded to perform, and only those actions. Do not do
more than you are commanded to.
• Use the language’s Statements to determine the actions you must perform:
– An Assignment Statement will evaluate its expression, and assign a value to a vari-
able.
– A Procedure Call runs the code in a Procedure, a Function Call runs the code in a
Function. To optimise this step you can perform the actions within called Functions
or Procedures without stepping through their code in most cases.
246
4.5. UNDERSTANDING DATA
One of the rules when running your code by hand is that you can not remember anything. The
values you use must come from the ‘memory’ that you setup for the Function or Procedure.
So, the first step for executing this code performs the actions that called the procedure: you
need to allocate space on the stack. You can simulate this using a piece of paper. This piece
of paper will be the ‘memory’ used by the code as it executes. To set this memory up you will
need to do the following:
1. Get a blank piece of paper.
2. Write (
, to remember that is the procedure you are in.
3. Do the following for any Variables6 in the Function or Procedure:
(a) Draw a box to represent the Variable. Make sure that it is large enough for you to
write values inside.
(b) Write the name of the Variable next to the box.
(c) If the Variable is a Parameter, copy the value from the argument into the box, other-
wise leave it empty.
When you have finished these steps for the code in Listing 4.31 you should have a piece of paper
that looks like the image in Figure 4.57. The empty boxes represent the different Variables,
the fact we have not written a Value into these boxes tells us that at this point the value has
not been set, and therefore should not be used.
Figure 4.57: Draw space for all of the Function or Procedure’s Variables
247
CHAPTER 4. STORING AND USING DATA
Now that the memory has been initialised it is time to run each instruction in the code. You
need to do this one instruction at a time. It does not matter how large the code is, the
computer will always run it one Statement at a time. Do not think, just read the Statement
and perform the action.
1. Step 1 calls the output procedure of the Language. This will output the text ‘Enter base
1: ’ to the Terminal. You do not need to step into the internal actions of each Function
or Procedure called, as long as you can replicate the actions that it would perform. If
you had been asked ‘What is output by the the call to (
, ?’ it would be
important to put this in the answer, but as we just want to know the final result you can
skip this.
2. Step 2 reads a value from the user and stores it in . The user is responding to the
prompt from step 1, and therefore enters 5, the value indicated in the question. As the
variable is passed to this call you now write 5 into the box, representing the
fact that this Variable now has the value 5. See Figure 4.58.
3. Step 3 outputs the next prompt, ‘Enter base 2: ’.
4. Step 4 reads a value from the user, and stores it in . This is the source of the first
error. This is most likely the result of a copy/paste error, where the developer has copied
the instructions to prompt the user and read a value into , and then changed it to
read a value into
. When you copy and paste code you need to pay extra attention
to making sure that the pasted code is changed correctly.
When this code is run a new value will be written into the Variable. Cross out
the old value, and write in the new value. The value entered in this case is 7, as indi-
cated in the question. See Figure 4.59.
5. Step 5 outputs the prompt for height.
6. Step 6 reads 4 from the user and stores it into the Variable. See Figure 4.60
7. Step 7 now reads the values from , and . The equation for calculating the area
of a Trapezoid is ℎ𝑒𝑖𝑔ℎ𝑡( 𝑏𝑎𝑠𝑒1+𝑏𝑎𝑠𝑒2
2 ), this has been coded incorrectly again, with several
errors. Firstly is read twice, and
is not used at all. Second, using BODMAS
2 ). Performing this
the current code is actually performing the equation ℎ𝑒𝑖𝑔ℎ𝑡(𝑏𝑎𝑠𝑒1 + 𝑏𝑎𝑠𝑒1
calculation you will find that the value stored in is 4(7 + (7/2)) = 42.
8. Step 8 outputs the area to the Terminal, displaying ‘Trapezoid area is 42’. See Figure
4.61.
At this point the Procedure has ended, and you have collected all of the details about how
the program actually works. You need to use this information to determine where the error
is. If this failed to find the problem then the problem may be located elsewhere in the pro-
gram’s code, or you have misread something. Getting someone else to help you debug your
programs is always a good option, they are likely to see things that you may miss as the code’s
developer.
Note
• Pay careful attention to exactly what the statement is getting the computer to do.
• Proceed slowly and carefully, as mistakes can be as small as a single character in
the wrong place.
• Make sure that you are aware of exactly what the different Statements do, and how ♠
they work.
• Always use the values of the Variables from ‘memory’, i.e. read/write them on to
your piece of paper.
248
4.5. UNDERSTANDING DATA
249
CHAPTER 4. STORING AND USING DATA
250
4.5. UNDERSTANDING DATA
4.5.6 Summary
In this Section you have seen how Variables work within the Computer, and been introduced
to the idea of Functions. With these concepts you can now work more meaningfully with the
data in your programs.
Note
• A Variable has two main aspects:
– The Variable itself, a space in memory. You can think of this like a box, into
which a value can be placed.
– The value that is stored within the Variable.
• Variables can be declared in one of three locations:
– Local Variables are declared within Functions and Procedures.
– Parameters are also declared within Functions and Procedures, but are given
a value as part of the call to this code.
– Global Variables are declared within the Program, and are accessible within all
Functions and Procedures. ♠
• The Assignment Statement can be used to store a value in a Variable. The left hand
side of an assignment is a Variable, the right hand side is an Expression.
• You can read the value of a Variable in an Expression.
• When you call a Function or a Procedure you can pass the Parameter either by
value or by reference. When passed by reference the Parameter must be passed a
Variable.
• A Function is just like a Procedure, except that it returns a result and is therefore
called inside Expressions so that the returned value can be used.
• A Function is called to calculate a value.
251
CHAPTER 4. STORING AND USING DATA
This program prints out the times table for a number entered by the user, displaying from 1
x n to 10 x n. The description of the program is in Table 4.7, the pseudocode in Listing 4.32,
the C code in Listing 4.33, and the Pascal code in Listing 4.34.
Program Description
Name Times Table
Pseudocode
( , ,
.
!
+
' ', , ' ,
' '
' ,
*
' '' ,
' ' '
' '
,
' '
'
' '
,
♣
' ' '
' '
,
' ' '
' '
,
' '
'
' '
,
' ' '
' '
,
' ' '
' '
,
' ' '
' '
,
' ' '
' '
,
' ' '
' '
,
' '' ,
Listing 4.32: Pseudocode for Times Table program.
Note
This is an updated version of the Seven Times Table Program. See Section 2.6.1 Seven
♠
Times Table.
252
4.6. DATA EXAMPLES
C++
( 7
, ,
Listing 4.33: C Times Table
253
CHAPTER 4. STORING AND USING DATA
Pascal
( ,,
, ,
,,
%
!
/$
', , '
/$
''
/$
' '
' '
♡
/$
'
'
' '
/$
' '
' '
/$
' '
' '
/$
'
'
' '
/$
' '
' '
/$
' '
' '
/$
' '
' '
/$
' '
' '
/$
' '
' '
/$
''
%
Listing 4.34: Pascal Times Table
254
4.6. DATA EXAMPLES
This program prints out the area of a circle. The description of the program is in Table 4.8,
the pseudocode in Listing 4.35, the C code in Listing 4.36, and the Pascal code in Listing
4.37.
Program Description
Name Circle Areas
Description Displays the Circle Areas for circles with radius from 1.0 to
5.0 with increments of 0.5.
Pseudocode
(
(!
+ ♣
' ' ' ,
' '' ,
' ' * ' ,
' ' *
'
,
' ' *
'
,
' ' *
'
,
' ' * ' ,
' ' *
'
,
' ' * ' ,
' ' *
'
,
' ' *
'
,
' '' ,
Listing 4.35: Pseudocode for Circle Areas program.
Note
This is an updated version of the Circle Areas Program. See Section 2.6.2 Circle Area. ♠
255
CHAPTER 4. STORING AND USING DATA
C++
( 7
(!
♢
4
4
*
4
7
*
4
7
*
4
7
*
4
7
*
4
7
*
4
7
*
4
7
*
4
7
*
4
7
4
Listing 4.36: C Circle Areas
256
4.6. DATA EXAMPLES
Pascal
( 7
(!
%
/$
' ' ♡
/$
''
/$
' * '
/$
' *
'
/$
' *
'
/$
' *
'
/$
' * '
/$
' *
'
/$
' * '
/$
' *
'
/$
' *
'
/$
''
%
Listing 4.37: Pascal Circle Areas
257
CHAPTER 4. STORING AND USING DATA
Water Tank
The Water Tank program draws four water tanks to the terminal. Each water tank is drawn as
a cylinder that fills a given area on the screen, and shows its current water level. An example
execution is shown in Figure 4.62.
Program Description
Name Water Tank
258
4.6. DATA EXAMPLES
C++
7 7
7
7
7 7
77 77
7 7
/
7 77 7
7
77 7
7
7 7
,
7 77 7
7
77 7
7
7
7
7
77 7
7
7
77 7
Listing 4.38: C Water Tank drawing code
259
CHAPTER 4. STORING AND USING DATA
C++
7
/
7 7
7 7
7 7
♢
7 7
%07 ! ,
%07/!,
7
7 7
7
Listing 4.39: C Water Tank drawing code (continued from Listing 4.38)
260
4.6. DATA EXAMPLES
Pascal
%
, !
* - ,
%07 ! ,
%07/!,
/ ,
!
+
+
1 +
1 1 +
1 +
1
1
/
1 *
1 *
*
1 *
,
1 *
1 *
*
$
1
$
1
Listing 4.40: Pascal Water Tank
261
CHAPTER 4. STORING AND USING DATA
Pascal
%
'
/
'/ ,
'
+
/
/ ,
/ ,
/ ,
/ ,
*
%07 ! ,
*
%07/!,
*+ ♡
* *
%
Listing 4.41: Pascal Water Tank (continued from Listing 4.40)
262
4.6. DATA EXAMPLES
The Bicycle Race program will simulate a thirty second sprint race between a number of bi-
cycles. The race has a standing start, and then each racer accelerates as fast as they can for
thirty seconds. The winner is the racer who makes it the furthest.
Program Description
Name Bike Race
• You can calculate distance the racers cover using Equation 4.1.
– t is time.
– a is acceleration.
𝑎𝑡2
𝑠 = 𝑢𝑡 + 4.1
2
• This race has a standing start, so the initial speed of each racer will be 0.
• Each racer will have a randomly determined acceleration, with a maximum acceleration
of 10 𝑝𝑖𝑥𝑒𝑙𝑠/𝑠𝑒𝑐𝑜𝑛𝑑2
263
CHAPTER 4. STORING AND USING DATA
C++
(
+
+
/ $7+!2
/ $7(
+,7(
%07$*,!'&
*7-*,!'&
07+$7,'*
777
264
4.6. DATA EXAMPLES
C++
(
7
7
77 77 7
7 7
77 / $7+!2
77 77 / $7+!2
/ $7(
7
7 77 7 / $7+!2
7
7 77 7 / $7+!2
7
7 77 7
77 7
7 7
7
7 77 7 77
%
(
♢
*
7
7 7
*
7 7
7 /
7
*
777
7
7
777
7
7
777
7
7
777
7
7
777
7
7
777
7
7
7
777
7
7
7
7 7
Listing 4.43: C Bicycle Race
265
CHAPTER 4. STORING AND USING DATA
Pascal
%
, !
* - ,
/ $7+!2
/ $7(
+,7(
%07$*,!'&
*7-*,!'&
07+$7,'*
0
+
+
+
,
*7-*,!'&
07+$7,'*
266
4.6. DATA EXAMPLES
Pascal
(
+
/0 /0 1 +
0 1 +
/0 / $7+!2
/0 /0 / $7+!2
/ $7(
0 /0 /0
/0
1 +,7(
/0 1 / $7+!2
/0 1 / $7+!2
,
/0 1
/0 1
0 1
$
/0 1 /0
♡
%
(
%
'
/
'
* '
+ /
*
0 *
0 *
0 *
*
0 *
*
0 *
*
0 *
*
0 *
*+
* *
%
Listing 4.45: Pascal Bike Race (continued from Listing 4.44)
267
CHAPTER 4. STORING AND USING DATA
Read over the concepts in this chapter and answer the following questions:
1. What is a Variable?
2. What is the relationship between a variable and a value?
3. What is the relationship between a variable and a type?
4. Where can you use variables? Think both reading the value, and storing a new value.
5. What does it mean if a variable appears on the right hand side of an assignment? What
will happen to this variable when the code is run?
6. What does it mean if a variable appears on the left hand side of an assignment? What
will happen to this variable when the code is run?
7. What is a Constant? How does it differ from a variable?
8. What is a local variable? What code can access the value in a local variable?
9. What is a global variable? What code can access the value in a global variable?
10. Why is it considered good practice to use local variable, but not global variables?
11. How do parameters help make procedures more powerful?
12. What are the two parameter passing mechanisms for passing parameters? How are they
different?
13. When would you use each of the parameter passing mechanisms? For what kind of
parameters?
14. How does the Terminal input procedure store a value in the variable you pass to it? What
kind of parameter passing is involved here?
15. What statement was introduced in this chapter?
16. What does this statement allow you to do?
17. What is a function? How does it differ from a procedure?
18. A procedure call is a statement. What is a function call? Why is this different?
19. What does it mean when you say a function returns a value?
20. What are the values of the following expressions?
268
4.7. DATA EXERCISES
21. When creating a program, types allow you to reason about the kind of data the program
is using. The three most basic types of data are Double, Integer and String. Use the
Double7 data type to represent any real numeric value; such as 1, 2.5, -75.201 etc. The
Integer data type is used to represent any whole numeric value; such as 1, 0, -27 etc.
Use the String data type for any textual data. There are many other data types, but these
three are the most frequently used.
When assigning a data type think about the following:
• How will the data be used?
• The range of values expected. Does the type have a sufficient range to cover this?
• Is precision important? Think carefully, especially with fractional values represented
as floating point numbers (i.e. Double).
What data type is most appropriate to store the following?
7 Computer programming languages often use floating point values to represent real numbers. This format stores
an approximation for a large range of values. You need to keep this in mind when thinking about the kind of data you
will use.
269
CHAPTER 4. STORING AND USING DATA
270
4.7. DATA EXERCISES
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. Write a small program to experiment with parameter passing. Create in this program a
procedure called (
! that takes a integer parameter and prints it to the Terminal.
Also create a Double It procedure that takes an integer parameter passed by reference8
and has its value doubled in the procedure. Try the following (not all will work):
(a) Call (
!, passing in a literal value like
.
(b) Call !, passing in a literal value like
.
(c) Call (
!, passing in a calculated expression like .
(d) Call !, passing in a calculated expression like .
(e) Call (
!, passing in a variable’s value.
(f) Call !, passing in a variable’s value.
2. Further adjust your Face Drawing program so that the caller can pass in a custom color,
width, and height for the face.
3. Adjust the bike race example from Section 4.6.3 so that the racers have a rolling start.
Each bike will then have a different initial speed, calculated as a random value. You will
need to define a maximum starting speed, and recalculate the x scale factor to ensure
that the bikes are all drawn to the screen.
8 If you are using C, you will need to do this with C++. With C++ your compiler is now g++, rather than gcc.
271
Control Flow
5
ime has come for you to learn how to control the flow of the magical
energies. This arcane knowledge will unlock great power. Making it
possible to do things that until now seemed impossible. Close your eyes
and picture the energy travelling through your spell. Take control of that flow
by. . .
The focus so far has been on learning the programming artefacts that you can create within
your code. You have seen how to create Programs, Procedures, Functions, and Variables. The
actual instructions that you can issue to the computer have been limited to Procedure Calls,
Function Calls, and Assignment Statements. This Chapter will introduce you to the other
actions that you can command the computer to perform. It will show you how to control the
flow of the instructions, unlocking great power, and making it possible to do things that until
now seemed impossible.
When you have understood the material in this chapter you will be able to write code that
commands the computer to perform a wider range of actions by controlling the sequence in
which the basic commands are performed.
Contents
5.1 Control Flow Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
5.1.1 Boolean Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
5.1.2 Branching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
5.1.3 Looping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
5.1.4 Jumping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
5.1.5 Compound Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
5.1.6 Statement (Simple and Structured) . . . . . . . . . . . . . . . . . . . . . . . 291
5.1.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
5.2 Using these Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
5.2.1 Designing Guess that Number . . . . . . . . . . . . . . . . . . . . . . . . . 293
5.2.2 Understanding Guess that Number . . . . . . . . . . . . . . . . . . . . . . . 294
5.2.3 Choosing Artefacts for Guess that Number . . . . . . . . . . . . . . . . . . 294
5.2.4 Designing Control Flow for Perform Guess . . . . . . . . . . . . . . . . . . 296
5.2.5 Designing Control Flow for Play Game . . . . . . . . . . . . . . . . . . . . . 310
5.2.6 Designing Control Flow for Print Line . . . . . . . . . . . . . . . . . . . . . 315
5.2.7 Designing the Control Flow for Main . . . . . . . . . . . . . . . . . . . . . . 317
5.2.8 Writing the Code for Guess That Number . . . . . . . . . . . . . . . . . . . 319
5.2.9 Compiling and Running Guess that Number . . . . . . . . . . . . . . . . . 319
5.3 Control Flow in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
5.3.1 Implementing the Guess that Number in C . . . . . . . . . . . . . . . . . . 320
273
CHAPTER 5. CONTROL FLOW
274
5.1. CONTROL FLOW CONCEPTS
Programming is about designing code that commands the computer to perform actions. Earlier
chapters have introduced the Program, Procedure, and Function artefacts into which you can
enter these instructions, but have not elaborated on the actions that you can perform.
Most of a program’s actual work will be carried out in Assignment Statements, and through
Procedure Calls and Function Calls. These are the main commands, allowing you to alter
values stored in memory and to execute stored instructions. The remaining commands relate
to controlling the order in which the computer performs the instructions; called control flow
statements.
This chapter introduces the following kinds of instructions. You can use these to get the
computer to perform certain actions within your program.
• If Statement: Run some code if a condition is true.
• Case Statement: Selectively run a branch of code.
• Compound Statement: Group statements together.
• Pre-Test Loop: Loop after testing a condition.
• Post-Test Loop: Loop then test a condition.
In addition to these actions, you will need have a look at an existing artefact:
• Boolean Data: An existing Type that has either a true or false value.
275
CHAPTER 5. CONTROL FLOW
The Boolean1 Data Type is a Type used to represent truth. A Boolean value will either be true
or false. These values are used extensively in the control flow statements to determine the
action to perform.
Is a kind of data...
a Type
Type
Boolean
True False
(yes) (no)
Tru
eF
lse
Variable
a area > 23.5
Variable
Function
10100101 Result Procedure
Variable
Instruction 1
10100101
Parameter
A Functions result may Instruction 2 Parameter
Variable
be a Boolean value Instruction 3
Instruction 1 Parameter Instruction 4
Parameter
... Instruction 5
...
Note
• Boolean is an existing artefact, it is a Type that has been defined to represent truth
values.
• A Boolean value is either true or false. You can also think of these as yes and no. ♠
• Boolean values are used in most of the control flow statements.
• The Boolean type can be used in the same way as other types.
276
5.1. CONTROL FLOW CONCEPTS
Comparisons
Comparisons are a common way of getting Boolean values in your code. These Expressions
allow you to compare two values to check for a given condition. For example, the Expression
shown in Figure 5.2 is asking if the value in the variable is larger than
. The result
of this expression will be either or depending on the current value stored in .
Table 5.1 lists some example values for this expression, given different values stored in the
variable.
Value in
Programming languages offer a range of different comparison operators. These typically in-
clude comparisons to check if values are the same or different, and to check if one value
is larger or small than another. The different operators for C and Pascal are listed in Table
5.2.
Description C Pascal
Equal Are the values the same?
Not Equal Are the values different?
Larger Than Is the left value larger than the right?
Less Than Is the left value smaller than the right?
Larger Or Equal Is the left value equal or larger than the right?
Less Or Equal Is the left value smaller or equal to the right?
Note
• Comparisons can only be performed between two values.
• The values on either side of the comparison are Expressions, allowing you to calcu- ♠
late the values being compared.
C++
C uses a double equal () for comparison as the single equals () is used for assignment. ♢
277
CHAPTER 5. CONTROL FLOW
Logical Operators
The comparison operators allow you to compare two values. This is very useful, but in itself
is incomplete. What, for example, do you do when you want to compare three or more values?
While you are limited to two values with the comparison operators, there are other operators
that allow you to combine Boolean expressions. This will enable you to combine together
multiple Boolean values into a single Expression.
There are four main logical operators: and, or, xor, and not. Each of these operators works
on two Boolean values, combining them to give a new Boolean value. For example, the and
operator allows you to check if both of the expressions are true. The expression
will be true only when area is both larger than zero and less then ten.
Logical Operators
b b
True False True False
a and b a or b
b
True False
a xor b not a
Description C Pascal
And Are both values True?
Or Is at least one value True?
Xor Is one value True, and the other False? 6
Not Is the value False?
area
and or xor
True True True True False
True False False True True
False True False True True
Note
• Table 5.4 has some example expressions.
• The tables in Figure 5.3 show the values of the different logical operators. These are
known as Truth Tables. ♠
• Table 5.3 outlines the different logical operators, and how they are coded in C and
Pascal.
278
5.1. CONTROL FLOW CONCEPTS
5.1.2 Branching
There are two main ways of controlling the sequence of actions in a program. The first of these
is called branching, or selection. Branching allows you to get the computer to take one of a
number of paths based on the value of a condition.
Branching
Condition
Paths converge
after the branch
Figure 5.4: Branching commands the computer to take one of a number of possible paths
Note
• Branching is a kind of action. You can command the computer to take of a number
of paths.
• A branch has a condition that is evaluated, and based on the condition the computer
takes one path.
• The branch is the act of choosing the path, when its command is performed the
computer evaluates the condition and then moves to the instructions in the indicated
path.
• Languages usually offer two kinds of branching statements:
– If Statement to select between two paths based on a Boolean expression. ♠
– Case Statement to select a path based on an ordinala value.
• The Branch will have one entry point, and one exit point. This feature allows you to
combine statements together like building blocks. This idea comes from the princi-
ples of Structured Programming, where each component in the code should have
a single entry and exit point.
a Integers and Characters are ordinal values. Ordinal values have a defined sequence, so it is possible to say
which value comes next in the sequence. Integers are Ordinal as you can say that the number after 1 is 2. Real
numbers are not ordinal as you cannot say which value comes next in the sequence.
279
CHAPTER 5. CONTROL FLOW
If Statement
The if statement is the most frequently used branching statement. It allows you to selectively
run code based on the value of a Boolean expression (the condition). The if statement has an
optional else branch that is executed when the condition is false.
Is a kind of
Statement
Statement Condition is a
Boolean Expression
else
This path is taken
when the condition
is True
If there is no else
part the if statement
just skips the True
path when the condition
is False
Note
• An if statement is an action. It allows you to command the computer to select a
path based on a Boolean expression.
• The if statement has two branches, one that is taken when the condition is True, the
other when it is False.
• The False branch may optionally have instructions that are carried out when the
♠
condition is False.
• If there are no instructions you want performed when the condition is False you
do not need to include an else branch, and the if statement will just skip the True
branch when the condition is False.
• The if statement has one entry point, two paths, and then one exit point.
280
5.1. CONTROL FLOW CONCEPTS
Case Statement
The case statement is the second kind of branching statement. This allows you to create paths
that execute based on matching a value from an expression. This allows one case statement
to handle many alternative paths.
Is a kind of
Statement
Statement Expression selects the
path with the matching value
Case Statement
Expression
1 2 3
An alternate
path exists for
when the Expression
does not match
any path's value
Note
• The case statement is a kind of action. It allows you to command the computer to
select a path based upon the value of an expression.
• Each path within the Case Statement has a value. When the computer executes the
case statement the path values are used to determine which path will be taken. ♠
• In C and Pascal the Case Statement only works with Ordinal Values. This limits you
to using Character or Integer values within the Case Statement’s Expression.
• The Case Statement has one entry point, multiple paths, and then one exit point.
281
CHAPTER 5. CONTROL FLOW
5.1.3 Looping
There are two main ways of controlling the sequence of actions in a program. The first was
branching, the second is called looping, or repetition. The language’s looping statements
allow you to have actions repeated.
Each loop
runs some
instructions
Looping
Condition
Note
• Looping is a kind of action. You can command the computer to repeat the steps
within a path.
• A number of steps are performed each loop:
– The instructions within the loop are executed.
– The condition is checked, and the instructions are either run again or the loop
ends.
♠
• The condition may be checked before or after the instructions are executed, giving
two kinds of loops:
– Pre-Test Loop: Repeats instructions 0 or more times.
– Post-Test Loop: Repeats instructions 1 or more times.
• As with Branching, the Looping Statements have a single entry and a single exit in
keeping with the principles of Structured Programming.
282
5.1. CONTROL FLOW CONCEPTS
Pre-Test Loop
The Pre-Test Loop is a looping statement that allows code to be run 0 or times. The loop checks
the condition at the start, and if the condition is True the loop’s body is executed. At the end
of the loops body the computer jumps back to the condition, checking it again to determine
if the loop’s body should execute again. If the condition is False when it is checked the loop
jumps ends, and control jumps to the next statement in the code.
Pre-Test Loop
(While Loop)
Condition
Figure 5.8: The Pre-Test Loop checks the condition, then runs the loop’s body
Note
• A pre-test loop is an action, creating a loop in the code’s sequence of instructions.
• The standard pre-test loop is the while statement.
• A pre-test loop allows instructions to be run 0 or more times. ♠
• The condition is checked when the loop’s code is entered, and it is checked again at
the end of each loop.
283
CHAPTER 5. CONTROL FLOW
Post-Test Loop
The Post-Test Loop is a looping statement that allows code to be run 1 or times. The post-test
loop places the condition after the body of the loop. This means that the first time through
the body of the loop must execute before the condition is checked. When it gets to the end of
the body, the loop’s condition is checked and the computer either jumps back to the start of
the loop to repeat the body, or the loop ends and control flows on to the next statement in the
code.
There are two common variants for the post-test loop: and
. These
work in the same way, in that they test the condition after the loop body, but the conditions
they use will be different. The loop repeats the body of the loop when its condition
is true,
repeats the body of the loop when its condition is false. When imple-
menting a post-test loop you must make sure that the condition you use matches the kind of
loop supported by your language.
Post-Test Loop
(Do ..While or Repeat... Until)
Each loop
runs some
Condition is checked after instructions
the statements in the
loop run.
Condition
Figure 5.9: The Post-Test Loop runs the loops body, then checks the condition
Note
• A post-test loop is an action, creating a loop in the code’s sequence of instructions.
• A post-test loop allows instructions to be run 1 or more times.
♠
• The condition is checked after the loop’s body is executed, with control jumping back
to the start if needed.
C++
C includes support for the loop. ♢
Pascal
Pascal includes support for the
loop. ♡
284
5.1. CONTROL FLOW CONCEPTS
5.1.4 Jumping
The jump statements allow you to alter the sequence of instructions in the code, getting the
computer to jump to another instruction.
Jumping
Figure 5.10: Jump Statements cause control to jump to another location in the code
Note
• The jump statements are actions, they allow you to alter the standard sequence of
the instructions and have the computer jump to a another location in the instruc-
tions.
• Structured Programming was proposed as a means of providing order and struc-
ture to the control flow through the code. These jump statements complicate this
sequential flow, but in some cases they are able to simplify code. ♠
• Structured jump statements allow you to control the sequence of actions related
to a Looping statement, a Function, or a Procedure. These work the looping and
procedural structures used in structured programming.
• Unstructured jump statements allow you to jump to any instruction within the code.
You need to be aware that these statements exist, but they should not be used.
285
CHAPTER 5. CONTROL FLOW
Break
The break statement is used to jump out of the current loop, in effect terminating the loop
early. This is useful for ending the current loop, skipping all future cycles.
Break
Break
Condition
Figure 5.11: The Break Statement allows you to end a loop early
Note
• The break statement is an action, allowing you to jump to the end of the current
loop.
♠
• The break statement should be coded within an Branching statement that checks if
the loop should terminate early.
286
5.1. CONTROL FLOW CONCEPTS
Continue
The continue statement is used to jump to the condition of the current loop. This is useful
for skipping the processing of the current loop, but to allow the loop to continue for the next
cycle.
Continue
Condition Continue
Figure 5.12: The continue Statement allows you to jump to the condition, skipping the remainder of the
code in the loop but allowing the loop to continue
Note
• The continue statement is an action, allowing you to jump to the condition of the
current loop.
♠
• The continue statement should be coded within an Branching statement that checks
if the loop should skip processing of the current cycle.
287
CHAPTER 5. CONTROL FLOW
Exit
The exit statement, or the return in C, ends the current Function or Procedure. This is use-
ful for skipping the rest of the processing of the Function or Procedure, exiting it early and
returning to the calling code.
Return / Exit
Return / Exit is
performed within a loop Function or
Procedure
101
001
10100101 01
Variable
Parameter
10100101
Variable
101
10100101 001
Variable
01
Parameter
Note
• Exit is an action, allowing you to jump out of the current Function or Procedure,
and return to the calling code.
♠
• The Exit should be coded within a Branching statement that checks if the Function
or Procedure should end.
C++
C’s version of the exit statement is the Return Statement. The return statement also pro-
vides the value that will be returned when exiting from a Function. As this sets the value ♢
to be returned you must have a return statement as the last action within a Function.
288
5.1. CONTROL FLOW CONCEPTS
Goto
The last jump statement is the goto statement. This is an unstructured jump, allowing you
to jump anywhere in the code. Structured Programming principles called for the abolition of
the goto statement. This is a statement you need to be aware of, but not one that should be
used.
Note
• Goto is an action that allows you to jump to another instruction and continue from
there. ♠
• You need to be aware of the goto statement, but you should not use it.
289
CHAPTER 5. CONTROL FLOW
Branching and Looping statements need to be able to include a number of instructions within
their paths. Often languages will manage this by indicating that only a single statement can
be included in any of these paths, and then include the ability to code multiple statements in
a single compound statement.
Is a kind of
Statement
Statement
A Single Statement...
Compound
Statement Statement
Statement
That contains
multiple statements
Statement
Figure 5.15: A compound statement is a statement that can contain other statements
Note
• Compound Statement is a term used to describe a way of grouping actions, allowing
you to create a single statement that contains multiple statements.
♠
• Compound Statements are useful when combined with Branching and Looping state-
ments. Allowing you to put multiple statements within a path.
290
5.1. CONTROL FLOW CONCEPTS
Statements are the actions that we can get the computer to perform.
Program
Function
Instruction 1
Instruction 2
Result
Instruction
10100101 3
Variable
Instruction
10100101
4 Procedure
Instruction
Variable 5
Parameter
...
An instruction/command 10100101
Instruction Variable
1
to perform an action ... 10100101 Parameter Parameter
Variable
Each instruction is a
Instruction 1 Parameter
Instruction 2
Statement
Commands the computer to
Contain at least run the code in a
one other Statement
Kinds Simple
Structured Statements of
Statements
Procedure Call
Compound
Statement
Jump Continue
Statements Statement
Looping Do While / Repeat
Statements Loop
Break Statement Return / Exit
Statement
While Loop
Goto Statement Assignment
Statement
Branching
Statements If Statement Commands the computer to
Repeat a
Statement store a value in a
Note
• Statement is the term given to the instructions in code.
• Simple Statements that perform an action. The actions you can perform are:
– Procedure Call used to run the code in a Procedure.
– Assignment Statement used to calculate a value and store it in a Variable.
– Jump Statements allow you to affect which instruction will be performed next.
This includes:
∗ Break: to jump out of a Looping Statement.
∗ Continue: jumps to the condition in a Looping Statement.
∗ Exit: (return in C) to end the current Function or Procedure.
∗ Goto: the unstructured jumpa to an arbitrary location in the code. ♠
• Structured Statements contain statements and control the flow of execution:
– Looping Statements: that repeat a statement a number of times.
∗ Pre-Test Loop: Test condition before the body, repeating 0 to many times.
∗ Post-Test Loop: Test condition after the body, repeating 1 to many times.
– Branching Statement: that select from a number of optional statements.
∗ If Statement: Branch based on a Boolean Data Expression (2 paths).
∗ Case Statement: Branch based on an Ordinal Expression (n paths).
a Often resulting in death by Raptor.
291
CHAPTER 5. CONTROL FLOW
5.1.7 Summary
This section has introduced a number of new actions that you can use in your code to create
more dynamic programs.
Term
Ends a
Statement
Return / Exit
Statement Groups Compound
Select to Statement
Action run one of a Repeats, 0..n
number of or 1..n times Term
options
Do While / Repeat
Case Statement While Loop
Loop
Action Action
Continue
Controlled Break Statement Statement
by a
Action
Boolean
Note
• Artefacts are things you can create and use.
• Terms are things you need to understand. ♠
• Actions are things you can command the computer to perform.
292
5.2. USING THESE CONCEPTS
The Control Flow Statements enable you to alter the purely sequential order in which instruc-
tions are performed. Using these Statements you can have the computer select a path to follow,
or jump back and repeat statements a number of times. These capabilities make it possible to
create programs that react to the data they receive, giving more interactive results than were
possible before.
Table 5.5 contains a description of the next program we are going to design. This program
plays a small guessing game called Guess that Number. In this game the computer will think
of a target number between 1 and 100. The user then has 7 guesses to determine the target
number’s value. At each guess the computer outputs a message to indicate if the target number
is greater than, less than, or equal to the user’s guess.
Program Description
Name Guess that Number
As before, the process to design and implement this program will follow a number of steps:
1. Understand the problem, and get some ideas on the tasks that need to be performed.
2. Choose the artefacts we will create and use
3. Design the control flow for the procedural2 artefacts
4. Map these artefacts to code
5. Compile and run the program
The new step in this process will involve designing the flow of the instructions within the
program, and the Functions and Procedures that need to be created. Previously each artefact
had a sequential flow of instructions, the introduction of the control flow statements has made
it possible to add branches and loops to this sequence. The order of these actions needs to be
considered for each sequence of instructions in your code.
293
CHAPTER 5. CONTROL FLOW
Guess that Number is a relatively common game involving one player choosing a number, and
the other trying to guess it. Each guess is followed by an indication of whether the guess was
less than or larger than the target number. The game continues until the player guesses the
target number.
The data for this program will be relatively simple. The code will need to keep track of the
current target number which will be an integer. The player will be able to enter a guess,
also an integer. These two numbers represent the data model for the game. It is a game that
involves a target number and guess.
The actions within the program involve playing the game, and performing a guess. Playing
the game is the process of performing guesses until the player finally guesses the target num-
ber. This version of the game will only allow the player to have seven guesses, so this will need
to be a part of this code in the program. The process of performing a guess will involve getting
the user’s guess, and giving them feedback indicating if they guessed the target number, of if
they were larger than, or less than the target.
Software design is all about abstraction. This is the process of determining the essential
features of the problem and modelling that in the artefacts that you create in your code. When
designing the artefacts that will make up your code you need to think about problem, and try
to create artefacts in your code that represent the actions and data you imagine when thinking
about the problem.
Our understanding of the Guess that Number game indicates that there are two processes
that need to be performed within the program: play game and perform guess. These two
processes can be coded as either Functions or Procedures in the program’s code. The (
code can be implemented as a Procedure. It will be responsible for running the process of
the game, starting with telling the user it has ‘thought of a number’, through to coordinating
the guesses, ending only when the user gets the answer of runs out of guesses.
( , on the other hand, will need to be a Function as it must return back a Boolean
Data value indicating if the user has guessed the number. The code in ( will be
responsible for asking the user to enter a guess, and then giving them the feedback on their
guess. As this has the details of the guess, its result is needed to allow ( to determine
if the user has guessed the number.
The ( code will also need to accept parameters to tell it what the current
value is. This data will exist within the ( code, so it will need a mechanism to pass that
code to ( . A Parameter is needed in ( to accept will enable
this.
A nicety may be to allow tell the user which guess they are up to. Once again, this information
is stored in ( , so a second parameter can be added to allow ( to pass in the
along with the number.
In addition to these it has been decided to add a (
$
procedure to display a line of
‘-’ characters. This will be displayed at the end of the game before the user is asked if they
want to play again. A
parameter will enable the caller to indicate how many of these
characters are printed on the line.
The Structure Chart showing these artefacts is shown in Figure 5.18, and the Sequence Dia-
gram is shown in Figure 5.19. Notice that there is some relationship here between the artefacts
that we are creating and the steps in the game itself. The earlier it is to see the relationship
between these artefacts and the problem, the better job you have done abstracting your solu-
tion.
294
5.2. USING THESE CONCEPTS
Main
len
Play Game
num guess, Print Line
(Boolean)
target
got it
Perform Guess
Figure 5.18: Structure Chart for the Guess that Number Program
Main
Play Game
Until got it or
num guess >= 7
Perform Guess
( Guess Num, Target)
True / False
Print Line ( 50 )
Figure 5.19: Sequence Diagram for the Guess that Number Program
295
CHAPTER 5. CONTROL FLOW
Having chosen the artefacts to build, the next step is to design the control flow that will enable
these Functions and Procedures, and the program itself, to achieve their goals. Each has a
responsibility that it must meet in order for the overall solution to work.
This section will go through designing the logic for the ( Function. It will cover
the following points:
• Drawing control flow using a Flowchart
• Use Structured Programming Principles to guide the design of the flowchart
• The Structured Programming blocks used to build the logic
• Combining blocks for the Perform Guess
• Setting the result using an Expression
• The Pseudocode for (
Before examining the control flows within the Functions and Procedures of the Guess that
Number program, let us have a look at a means of visually representing flow of actions within
code. A common means of doing this is to use a flowchart. This is a diagram that depicts a
sequence of actions, and can be used to represent the sequence of action actions that occur
within your code.
The flowchart has four basic symbols as shown in Figure 5.20.
• Start/Stop: This represents the start and end of the process. Typically the start node
would have the name of the Function or Procedure within it.
• Flow: The arrows between nodes represent control flow, indicating which action is to be
performed next in the code.
• Process: This node represents a task being performed. In our case this will map to one,
or more, simple statements. The text in the Process node should indicate what is being
performed at this stage.
• Decision: This represents a point where the code needs to make a decision. This is used
for the conditions in the Branching and Looping statements. A decision must have more
than one flow coming out of it, and each flow should indicate the condition that triggers
that path.
Process
Decision Start/Stop
296
5.2. USING THESE CONCEPTS
Flowcharts can be used to represent any sequence of actions, but not all sequences of actions
will be easy to code. Figure 5.21 is an example of a flowchart, but not one that can be coded
using the structured statements covered in Chapter 5. Figure 5.22 shows a structured version
of this same algorithm. Notice that in this version there are identifiable blocks, each having a
single entry and a single exit. This structure could easily be converted to code using structured
statements.
Looking at these two flowcharts, the structured flowchart looks more complicated than the
unstructured version. This reflects the fact that in some cases the structured version may be
more complicated, but is also an indication that this process may be better broken down into
more functions and procedures. For example, the repeated loop looking for someone else to
blame could be placed in its own procedure. If you find it difficult to design the control flow
using structured blocks try to see if you can identify additional Functions and Procedures to
help you break the code down into smaller blocks.
The structured programming principles indicate that code within a Function or Procedure
should be organised into blocks. These blocks match to the structured statements in modern
programming languages: the Branching and Looping statements. Each of these blocks has a
single entry point and a single exit point, allowing them to combined together.
The addition of Jumping statements to the language allows the blocks to have multiple exit
points; one at the end of the block’s code, the other at a Break, Exit, or Return Statement.
These statements give you extra flexibility, but still work within the structured programming
principles.
Note
Prior to the Structured Programming, programs had two control flow mechanisms:
and Goto. Control flow was not easy to picture or understand. Programs written in this
♠
way are now know as spaghetti code, as understanding this code is much like trying to
untangle a bowl of spaghetti, though not nearly as tasty.
297
CHAPTER 5. CONTROL FLOW
Problem
Solving
No Yes
Is the thing
broken?
No
No Does No Yes
Will they
anyone
believe you?
know?
Yes
Hide it!
Not good...
No
Can you
blame
someone
else?
Yes
No Problems... End
298
5.2. USING THESE CONCEPTS
Problem
Solving
No Yes
Is the thing
broken?
Not your
smartest
moment...
No Yes
No Does Yes Will they
anyone believe you?
know?
No Problems...
End
299
CHAPTER 5. CONTROL FLOW
...
Other Block
...
Other Block Other Block Other Block Other Block Other Block Other Block
Other Block
False True
Condition
True
300
5.2. USING THESE CONCEPTS
With the basic theory at hand, we can now start to design the control flow for the Guess
that Number program. This process will involve, once again, the idea of abstraction. When
designing the flow for a program you first need to be able to perform the process yourself, even
if its just on paper, and then work out the steps that you undertook so that you can code these
within the program.
For the Guess that Number program we can start by designing the control flow within the
( function. The specification of this is shown in Table 5.6. Think about the steps
that need to be performed to achieve this. If you had been asked to do this what would you
need to do?
Function
(
Returns
True when the user has guessed the number, False
otherwise.
Parameter Description
& The number of the current guess, used in the prompt
asking for the user to enter their guess.
The first task the Function needs to perform is to get the guess from the user. This can be
performed in a sequence: display a prompt, read the value from the user. This first sequence
is shown in Figure 5.26.
Perform
Guess
301
CHAPTER 5. CONTROL FLOW
The next step in this sequence is to give the user feedback based upon their guess and the
target number. This code requires a the ability to select a given branch. The computer needs to
output different messages based upon the users guess. This can be achieved with a selection
block. Looking back at Figure 5.24 there are three possible alternatives for implementing this
selection. The with no is not a valid option as there are three paths we need to take.
The block is also not valid as we are not matching a value, but comparing values to each
other. The last option is the block, but this only has two branches. It is not going to
be possible to code all three options within one block, but it can be achieved using two
blocks.
The first block will check if the is greater than the user’s . If this is true
then the computer can take the first branch and output the message ‘The number is larger
than ’ and the value from the user’s guess. The flow chart for this part is shown in Figure 5.27.
This block is the third task in the sequence, this if block has a single entry, causes a branch
in the flow, and will have a single exit.
Perform
Guess
Yes Target is No
larger than
Guess
Note
• The conditions within the If Statement are Boolean Expressions.
• This condition is checking if .
♠
• There are now two paths through this code, one when is , and another
when it is not.
302
5.2. USING THESE CONCEPTS
Following the false path from the first decision, and we have a new location into which to insert
a block. At this point we know the target is not larger than the user’s guess. At this point you
can include another block to check if the target is less than the user’s guess. This is
shown in Figure 5.28.
Perform
Guess
Yes Target is No
larger than
Guess
Figure 5.28: Second branch tests if the Target is less than the guess
Note
• The newly added block is another If Statement.
• This is nested within the branch of the first If Statement.
♠
• This code checks if .
• There are now three paths through this code.
303
CHAPTER 5. CONTROL FLOW
Taking the false path again, and now we have a location at which the target value must be equal
to the user’s guess. The first condition checked if the was larger than the , which
it was not. The second condition checked if the was less than the , which it was
not. So the only way this can be the case if is the and the are equal. This path
can then be used to output the ‘Well done. . . ’ message. This is shown in Figure 5.29.
Perform
Guess
Yes Target is No
larger than
Guess
Figure 5.29: The ‘Well done. . . ’ message can be output on the third path
Note
• The newly added block is a sequence, outputting the ‘Well done. . . ’ message.
• On this third path the and must be equal.
♠
• Notice the single exit out of the second branch, when then flows to the single exit
out of the first branch.
304
5.2. USING THESE CONCEPTS
The last action in the code is to return a Boolean result indicating if the user’s guess is equal
to the target number.
Perform
Guess
Yes Target is No
larger than
Guess
End
Note
• The newly added block is a single action, defining the result to be returned.
♠
• This action returns the result True when the and the are equal.
305
CHAPTER 5. CONTROL FLOW
Figure 5.31 shows the flowchart with annotations highlighting the different blocks within the
code. The function starts off with a sequence that contains all of the code in the Function.
Within this there is the selection, that internally contains another selection.
Perform
Guess
Sequence
Selection
Yes Target is No
larger than
Guess
Selection
End
Note
• Notice that each block has a single path going into it, and a single path coming out. ♠
306
5.2. USING THESE CONCEPTS
Figure 5.32 shows the trick that is being performed at the end of ( ’s code. (
needs to return a result indicating if the user has guessed the number of not. This will
be a Boolean value, with True indicating they guessed the number. Initially it may seem that
you need a selection block to enable this, as shown on the right of Figure 5.32.
End End
Note
• In most cases it is better to have less code if possible, as long as this does not obscure
the purpose of the code.
♠
• This is an example of replacing actions with data. The more intelligence you can
build into the data in your programs the more flexible they will be.
C++
This is achieved in C using
♢
Pascal
This is achieved in Pascal using ♡
307
CHAPTER 5. CONTROL FLOW
Listing 5.1 contains the Pseudocode for the ( logic from the flowchart in Fig-
ure 5.30. Notice how the indentation in this mirrors the block structures in the flowchart. It
is good practice to indent your code in this way as it helps you, and any person who reads
your code, to see the structure of the logic. You will be able to avoid many errors by making
sure that you always indent your code so that it highlights the code’s structure.
Pseudocode
Note
• Code indentation makes it easier to read, and helps locate many common issues.
• Tab you code in within a structured statement.
– Indent the code in the branches of an If Statement and Case Statement.
– Indent the code within the body of the While Loop and the Do While or Repeat
Until loops.
• Make this a habit. When you code a Branching or Looping statement automatically
indent the next line of code. ♠
• Always keep you code neat, make it look good.
• The C code for ( is shown in Listing 5.2.
• The Pascal code for ( is shown in Listing 5.3.
• Notice how the two code samples are laid out in a similar way. The indentation
makes it easy to identify which statements are associated with each of the branches
through the Function.
308
5.2. USING THESE CONCEPTS
C++
,
4
♢
,
4
/
4
Pascal
309
CHAPTER 5. CONTROL FLOW
The ( Procedure is another artefact that will require some some thought to design
its logic. Table 5.7 contains the specification for this Procedure. It will be responsible for
coordinating the actions of the game, while ( coordinates the actions for a single
guess.
Procedure
(
The implementation of this Procedure will require us to store some data. The following Local
Variables will be needed to store data within this Procedure:
• % &: This will store the computer’s randomly chosen number.
• &: This will store the current guess the user is at, allowing the computer to
stop looping when the number of guesses is exceeds 7.
• !: A Boolean value to indicate if the user did guess the number, allowing the com-
puter to stop looping when the user guesses the number.
The flowchart for this is shown in Figure 5.33, and again in Figure 5.34 with its blocks high-
lighted. This code uses a repetition to ask the user to perform up to 7 guesses. The condition
on this loop occurs after the loop body as the user must have at least one guess.
There is also a selection after the loop to output the answer if the user ran out of guesses.
This is only done when the user has not guessed it themselves. This does not need to perform
any other actions when the user did guess the number, so the False branch has no additional
actions. In code this would be implemented with an If Statement without an else branch.
Note
• A loop may have its condition before or after its instructions.
• If the condition is after the loop, as it is with ( , then this gives a loop that
runs at least once.
• The else branch on the If Statement is optional. If you have no processing for this ♠
branch you leave the off in the code.
• The condition of the If Statement in ( check if the ! is False using the
logical operator.
310
5.2. USING THESE CONCEPTS
Play Game
Got It or Guess No
Number is larger
than or equal to 7
Yes
Yes
Not Got It
No
Output "You ran out of
guesses, the number
was ', and My Number
End
311
CHAPTER 5. CONTROL FLOW
Play Game
Sequence
Store a random value
between 1 and 100 into
My Number
Sequence
Got It or Guess No
Number is larger
than or equal to 7
Yes
Selection
Yes
Not Got It
No
Output "You ran out of
guesses, the number
was ', and My Number
End
312
5.2. USING THESE CONCEPTS
Listing 5.4 contains the Pseudocode for the ( Procedure. This uses Constants for
%0 &-%* and a %0 -+++, this will make it easier to change the range of the numbers and
the associated number of guesses.
The flowchart for ( includes a Post-Test Loop, which can be coded as either a
or a
loop. This two variations are shown in step 7 of Listing 5.4, with the while
version appearing as a comment on the following line. Both of these versions have the same
result, but do require different conditions. The two implementations of this are shown in List-
ing 5.5 and Listing 5.6. It is important to understand that the basic ideas of a post-test loop
is the same regardless of whether it is coded using or
.
Pseudocode
( (
$ .
% & & !
!
+
% & *
%07&-%*
&
' '!
'
%07&-%* ♣
*
!
&
! ( & % &
-
& %07-+++ !
/ & %07-+++
!
! & !
' '1
'
% &
Listing 5.4: Pseudocode for (
Note
• Notice the indentation make it easier to see which instructions are within the loop
and branches of this code.
• The C code for this is is Listing 5.5. ♠
• The Pascal code for this is in Listing 5.6.
• The C and Pascal libraries have different Functions for getting random numbers.
C++
In C there is a
function in the header file. This returns a random integer
value. To get this between 1 and MAX NUMBER you can use the modulo operator (%) that ♢
returns the remainder after division. The expression to use is
%07&-%*
Pascal
In Pascal there is a *
function in the System unit. This takes a single parameter
representing the number of random values to generate (0..n-1). The expression to use is ♡
*
%07&-%*
313
CHAPTER 5. CONTROL FLOW
C++
7
7
7
7
7
%07&-%*
7
#
!
4
4
%07&-%*
♢
7
7 7 7
7
7
%07-+++ 7
7
1
4
7
Listing 5.5: C code for (
Pascal
(
& & !
!
& *
%07&-%*
& #
♡
&
! ( & &
& %07-+++ !
!
/$
'1
' &
Listing 5.6: Pascal code for (
314
5.2. USING THESE CONCEPTS
(
$
is a short Procedure used to print a line of ‘-’ characters to the Terminal. The
flowchart for this Procedure is shown in Figure 5.35, and again with the blocks highlighted in
Figure 5.36.
Procedure
( $
Parameter Description
$
The number of characters to print. Represents the
length of the line.
Print Line
Set i to 0
Yes No
i less than
Length
Output a "-"
increase i by 1
End
315
CHAPTER 5. CONTROL FLOW
Print Line
Sequence
Set i to 0
Yes No
i less than
Length
Sequence
Output a "-"
increase i by 1
End
Pseudocode
( (
$
(
$
!
$ .
!
+ ♣
/ $
' ''
!
'
Listing 5.7: Pseudocode for (
$
Note
• This code includes a Local Variable .
• is used to count the number of times the loop has executed, allowing it to stop
when it has printed enough dashes.
♠
• This uses a Pre-Test Loop. This makes sure that no characters are printed if the
length is less than or equal to zero.
• Notice that a sequence can be placed within a loop.
316
5.2. USING THESE CONCEPTS
The last Procedure is %
. This is responsible for coordinating the actions of the program. It
will call ( in a loop that repeatedly plays the game until the user decides to quit. %
will have one local variable called
. This will store a character, and will be used to store
the value read from the user’s response to the ‘play again’ prompt.
Main
Play Game
Print Line
Yes
again equals 'y' or
again equals 'Y'
No
End
317
CHAPTER 5. CONTROL FLOW
Main
Sequence
Seed the Random
Number Generator
Sequence
Play Game
Print Line
Yes
again equals 'y' or
again equals 'Y'
No
End
Note
Computers cannot generate truly random numbers. Instead it uses a numeric sequence
that appears to be random. Seeding the generator with the current time ensures that this ♠
random sequence starts at a different value each time the program is run.
318
5.2. USING THESE CONCEPTS
Flowcharts and Pseudocode communicate the same ideas. They describe the actions that need
to be performed within your code. The following two sections, Section 5.3 Control Flow in C
and Section 5.4 Control Flow in Pascal, contain a description of the syntax needed to code
these control flow statements in the C and Pascal programming languages.
Note
Remember the basic process for reading the Syntax Diagrams is to:
1. Find the page with the Syntax rule you are interested in knowing about.
2. Have a quick look at the Syntax Diagram and the rules it contains. Read each rule,
and get a basic feel for how it is going to come together for your program.
3. Read the example to see one way of using the Rule. The Syntax Diagram can be
♠
used to create any number of variations of the rule, the example gives you at least
one way these rules can be coded.
4. Return to the diagram and make sure you can match each part of the example back
to the rule that created it.
5. Look up any related rules that are not explained on this rule’s page.
Once you have completed the code for this program you need to compile and run it. As this
uses random numbers you cannot generate standard test data in order to check the execution.
Instead you should perform a number of executions and test the different paths through the
program. The main condition you want to check are:
• Test failing to get the number in seven guesses.
• Test getting the number correct within seven guesses.
• Check the output messages when your guess is less than the number (you can enter a
guess below 0).
• Check the output message when your guess is larger than the number (you can enter a
guess larger than 100).
• Check that the random sequence is different each time, if its not make sure you have
seeded the random number generator.
319
CHAPTER 5. CONTROL FLOW
Section 5.2 of this Chapter introduced the ‘Guess that Number’ program. This program con-
tained a Function to ( and Procedures to (
$
and ( . Each of these
involved some control flow in their logic, as shown in the Flowcharts in Section 5.2. The full
C implementation of the Guess that Number program is shown in Listing 5.8.
(
,
,
!
%07&-%*
%07-+++
4
( *
7
7
320
5.3. CONTROL FLOW IN C
7
7
7
7
%07&-%*
7 #
!
4
4
%07&-%*
7
7 7
7 7
7 %07-+++ 7
7
1
4
7
*
7
4
7
3&5
''
'1'
Note
• is needed for the
function and the
procedure.
• is needed to get the current time used to seed the random number generator.
• gives access to the data type in C for Boolean Data.
♠
• In this code is laid out differently to that shown previously. This is
also an acceptable layout as it shows the different paths clearly. While it does not
show the structure as well, it is a clean and neat way of presenting this code.
321
CHAPTER 5. CONTROL FLOW
C has very flexible support for Boolean values. In C a value is considered to be false, and
any other value is true. Modern C compilers have now added support for an explicit Boolean
type, . This type requires the header file, which defines the type as well as
the values and .
Boolean Type
Name Size Values
1 byte/8 bits or
Description C
Equal Are the values the same?
Not Equal Are the values different?
Larger Than Is the left value larger than the right?
Less Than Is the left value smaller than the right?
Larger Or Equal Is the left value equal or larger than the right?
Less Or Equal Is the left value smaller or equal to the right?
Description C
And Are both values True?
Is at least one value True?
*
Or
Xor Is one value True, and the other False? 6
Not Is the value False?
Note
• To use the Boolean type in C you must include the header.
• In C false is the value , and true is any other value.
♠
• The header gives you access to two value, and . has the
value 1, has the value 0.
322
5.3. CONTROL FLOW IN C
C++
!
7 7
♢
*
7 7
7
4
Listing 5.9: C Boolean Test Code
323
CHAPTER 5. CONTROL FLOW
In addition to the Procedure Call and Assignment Statement, C Statements may be Branching,
Looping, or Jumping Statements.
assignment statement
compound statement
branching statement
looping statement
jump statement
case statement
do while loop
for loop
continue statement
return statement
Figure 5.39: C++ Syntax for a Statement (with branches and loops)
Note
• See the following diagrams for details on this syntax:
– C If Statement: for the syntax of an If Statement.
– C Case Statement: for the syntax of an Case Statement.
– C While Loop: for the syntax of an Pre-Test Loop. ♠
– C Do While Loop: for the syntax of an Post-Test Loop.
– C Jump Statements: for the Jumping Statements.
• These statements can be coded within Functions, Procedures, and programs.
324
5.3. CONTROL FLOW IN C
5.3.4 C If Statement
The if statement is a Branching statement. This can be used to optionally run a block of code,
providing two alternate paths controlled by a Boolean expression.
statement
C++
&
4
*
♢
1
,
,
Listing 5.10: C if test code
Note
• This is the C syntax for the If Statement.
• The parenthesis surround the expression. This enables the compiler to tell where
the expression ends.
• Notice that the branch is optional.
♠
• When the expression is (0 in C), the else branch is taken.
• For any other value the first path is taken.
• You only need to include if you want to use the type and the values
or .
325
CHAPTER 5. CONTROL FLOW
default case
statement
statement
Note
• This is the C syntax to declare a Case Statement.
• The constant expressions in each case must be ordinal values (integers or characters).
• The code in Listing 5.12 shows an example use for a case statement.
*
• The path is taken when none of the other paths match the expression.
• If the
is left off the end of a case then execution will continue into the next ♠
case. For example, in Listing 5.11 if the user enters ‘c’ the output will be ‘
’
• Each case can contain a number of Statements.
• Watch !.-2) for important details on the leg-
endary Knights of Ni.
C++
(
♢
' '
''
4
''
''
4
+
4
Listing 5.11: C case test code with a character
326
5.3. CONTROL FLOW IN C
C++
7
7
♢
7
7
/ & 4
*
4
'
4
(
Listing 5.12: C case test code with an integer
327
CHAPTER 5. CONTROL FLOW
Most of the C structured statements only allow single statements within each path. For exam-
ple, the paths in the two branches of an C If Statement can only contain a single statement.
The Compound Statement allows you to group together multiple statements within a single
compound statement.
compound statement { }
statement
C++
'' '1'
*
/ #
'& ' 4
♢
/
'& ' '(
'
'& ' 4
, #
/ + '& '
4
/
4
+ *
4
Listing 5.13: C compound statement test code
Note
• Figure 5.42 shows the syntax for a Compound Statement in C.
• The code in Listing 5.13 shows an if statement that includes two compound state-
ments within its branches.
• Compound statements in C are marked with curly brackets, ‘{’ for the start, and ‘}’
♠
for the end.
• The compound statement is a standard statement, and can be used anywhere a
statement can appear. Its practical use is for grouping statements within other
structured statements, and you are unlikely to find it used in any other way.
328
5.3. CONTROL FLOW IN C
The while loop is C’s Pre-Test Loop, allowing a block to be repeated zero or more times.
C++
*
♢
#
4
4/ #
'& '44
4! &
44
4& 44
77
Listing 5.14: C while loop test code
Note
• Figure 5.43 shows the syntax for a Pre-Test Loop in C.
• This loop runs 0 to many times, checking the condition before executing the body of
the loop.
• The parenthesis allow the compiler to determine where the condition ends, and the ♠
statement starts.
• The while loop repeats a single statement, you must use a Compound Statement to
have multiple statements repeated. See C Compound Statement.
329
CHAPTER 5. CONTROL FLOW
The do while loop is C’s Post-Test Loop, allowing a block to be repeated one or more times.
C++
*
♢
#
4
4/ #
'& '44
4! &
44
4& 44
77
Listing 5.15: C do while loop test code
Note
• Figure 5.44 shows the syntax for a Post-Test Loop in C.
• This loop runs 1 to many times, checking the condition after executing the body of
the loop.
♠
• The parenthesis allow the compiler to determine where the condition ends.
• The do while loop repeats a single statement, you must use a Compound Statement
to have multiple statements repeated. See C Compound Statement.
330
5.3. CONTROL FLOW IN C
continue statement
expression
C++
*
+
'' '1'
)
,
4
Listing 5.16: C code demonstrating the jump statements
Note
•
jumps to the end of the current loop.
•
jumps back to the condition in the current loop. ♠
•
ends the current Function or Procedure.
331
*
5.4. CONTROL FLOW IN PASCAL
Section 5.2 of this Chapter introduced the ‘Guess that Number’ program. This program con-
tained a function to ( and procedures to (
$
and ( . Each of these
involved some control flow in their logic, as shown in the flowcharts in Section 5.2. The full
Pascal implementation of the Guess that Number program is shown in Listing 5.17.
%07&-%*
%07-+++
( *
/ ''
/$
( *
(
!
!
/ ' '
' '
* $
333
CHAPTER 5. CONTROL FLOW
/$
! (
&
%07-+++ !
!
/$
'1
' &
(
/$
(
$
/$
'
31
5 '
* $
'
'
'&'
( *
%
Listing 5.17: Pascal code for the Guessing Game
334
5.4. CONTROL FLOW IN PASCAL
Boolean Type
Name Size Values
1 byte/8 bits , or
Description C
Equal Are the values the same?
Not Equal Are the values different?
Larger Than Is the left value larger than the right?
Less Than Is the left value smaller than the right?
Larger Or Equal Is the left value equal or larger than the right?
Less Or Equal Is the left value smaller or equal to the right?
Description Pascal
And Are both values True?
Or Is at least one value True?
Xor Is one value True, and the other False?
( *
Not Is the value False?
Note
The Pascal logical operators have precedence over the comparison operators, this means
you will need to use parenthesis to group comparisons when combining them using logical ♠
operators. For example, > < .
335
CHAPTER 5. CONTROL FLOW
Pascal
,
!
%
♡
!
/ '
'
* $
%
Listing 5.18: Pascal Boolean Test Code
336
5.4. CONTROL FLOW IN PASCAL
In addition to the Procedure Call and Assignment Statement, Pascal statements may be Branch-
ing, Looping, or Jumping statements.
assignment statement
compound statement
branching statement
looping statement
jump statement
case statement
for loop
( *
jump statement break statement
continue statement
return statement
Figure 5.46: Pascal Syntax for a statement (with branches and loops)
Note
• See the following diagrams for details on this syntax:
– Pascal If Statement: for the syntax of an If Statement.
– Pascal Case Statement: for the syntax of an Case Statement.
– Pascal While Loop: for the syntax of an Pre-Test Loop. ♠
– Pascal Repeat Loop: for the syntax of an Post-Test Loop.
– Pascal Jump Statements: for the Jumping statements.
• These statements can be coded within functions, procedures, and programs.
337
CHAPTER 5. CONTROL FLOW
The if statement is a Branching statement. This can be used to optionally run a block of code,
providing two alternate paths controlled by a Boolean expression.
statement
Pascal
,!
%
!
/ '
'
* $
/$
'&
'
( *
/$
',
'
/$
',
'
%
Listing 5.19: Pascal if test code
Note
• This is the Pascal syntax for the If Statement.
• The
keyword tells the compiler where the if’s condition ends.
• Notice that the branch is optional.
♠
• When the expression is , the first path is taken.
• When the expression is the else branch is taken.
• Notice that there is no semicolon (;) after the first statement before the else branch.
338
5.4. CONTROL FLOW IN PASCAL
default case
statement
Note
• This is the Pascal syntax to declare a Case Statement.
• The constant expressions in each case must be ordinal values (integers or characters).
( *
• By using
the case will match any value in this range, e.g. .
• The code in Listing 5.21 shows an example use for a case statement.
♠
• The path is taken when none of the other paths match the expression.
• Each case contain a single statement.
• Watch !.-2) for important details on the leg-
endary Knights of Ni.
Pascal
+
%
/ '
'
* $
' ' '' /$
' '
'' '' /$
' ' ♡
'' /$
''
'''' '' '2' /$
' 2'
/$
'+
'
%
Listing 5.20: Pascal case test code with a character
339
CHAPTER 5. CONTROL FLOW
Pascal
,
%
!
♡
* %
'
/$
'/ & '
/$
'
'
/$
'' '
/$
'
'
/$
'(
'
( *
%
Listing 5.21: Pascal case test code with an integer
340
5.4. CONTROL FLOW IN PASCAL
Most of the Pascal structured statements only allow a single statement within each path. For
example, the paths in the two branches of an Pascal If Statement can only contain a single
statement. The Compound Statement allows you to group together multiple statements within
a single compound statement.
Pascal
%
/ '
3&5 '
* $
( *
/$
'/ #
& ' ♡
/$
'/
'
/$
'& (
& '
/$
', #
/ + &
'
/$
'/
'
/$
'
+ *
'
Listing 5.22: Pascal compound statement test code
Note
• Figure 5.49 shows the syntax for a Compound Statement in Pascal.
• The code in Listing 5.22 shows an if statement that includes two compound state-
ments within its branches.
♠
• The compound statement is a standard statement, and can be used anywhere a
statement can appear. Its practical use is for grouping statements within other
structured statements, and you are unlikely to find it used in any other way.
341
CHAPTER 5. CONTROL FLOW
The while loop is Pascal’s Pre-Test Loop, allowing a block to be repeated zero or more times.
Pascal
,/
%
( *
%
/$
'& '
%
%
Listing 5.23: Pascal while loop test code
Note
• Figure 5.50 shows the syntax for a Pre-Test Loop in Pascal.
• This loop runs 0 to many times, checking the condition before executing the body of
the loop each time.
♠
• The keyword marks the end of the condition and the start of the statement.
• The while loop repeats a single statement, you must use a Compound Statement to
have multiple statements repeated. See Pascal Compound Statement.
342
5.4. CONTROL FLOW IN PASCAL
The repeat loop is Pascal’s Post-Test Loop, allowing a block to be repeated one or more times.
Pascal
,*
%
( *
/$
'
#
' ♡
/$
'/ #
''&'' '
/$
'! &
'
/$
'& '
%
%
Listing 5.24: Pascal repeat loop test code
Note
• Figure 5.51 shows the syntax for a Post-Test Loop in Pascal.
• This loop runs 1 to many times, checking the condition after executing the body of
the loop. ♠
• The repeat loop repeats multiple statements, so there is no need for a compound
statement.
343
CHAPTER 5. CONTROL FLOW
continue statement
Pascal
,"
%
!
( *
+
/$
',
'
%
Listing 5.25: Pascal code demonstrating the jump statements
Note
•
jumps to the end of the current loop.
•
jumps back to the condition in the current loop. ♠
• ends the current function or procedure.
344
5.5. UNDERSTANDING CONTROL FLOW
This Chapter has introduced new statements that can be used to control the sequence of
actions the computer performs. These statements allow you to add Branching and Looping
paths to your code. The flowcharts presented in Section 5.2 are a great way of visualising the
order in which the computer will execute the instructions. To help you fully understand these
concepts this section will look at how these statements work within the computer.
Figure 5.53 shows the flowchart for the ( that was developed in Section 5.2.4 on
Designing Control Flow for Perform Guess. The following sections show how the computer
executes these actions. These illustrations will start at the call into ( , skipping
the illustration of the steps that lead up to this call.
Perform
Guess
Yes Target is No
larger than
Guess
End
Figure 5.53: Logic for the ( Procedure from Figure 5.58
In the following illustrations ( will be called three times with the number
being in each case. The following three guesses will be performed, ensuring that all paths
through the flowchart are covered.
1. On the first guess the user enters a guess of 50, allowing for the left most branch of this
flowchart to be followed.
2. The second guess will be 25 to test the middle branch, taking the else branch of the first
decision and the true branch of the second decision.
3. Finally the third guess will be 37, testing the right most path through the code.
345
CHAPTER 5. CONTROL FLOW
In the Guess that Number program, the ( function is responsible for reading in the
user’s guess and giving them feedback. Figure 5.54 shows the ( code being called
for the first time, it is passed 1 to its
parameter and 37 to its parameter.
Note
• In Figure 5.54 the indicated areas show the following:
1. ( is called, with 1 being passed to
and 37 passed to
.
• At this point the previous code would have output ‘I am thinking of a number . . . ’ to ♠
the Terminal.
• The values in and have not been initialised, so they have whatever value
was in that memory location previously.
346
5.5. UNDERSTANDING CONTROL FLOW
Execution of ( occurs as normal, each instruction is run one after the other.
Note
• In Figure 5.55 the indicated areas show the following:
1. Execution proceeds one instruction at a time up to the If Statement at step 4.
• These steps output a prompt (step 1), and read in a response (step 2). ♠
• Step 2 reads a the user’s response into the variable.
• When the computer executes step 4 it evaluates the If Statement’s expression and
then selectively runs one of the two available paths.
347
CHAPTER 5. CONTROL FLOW
With the first guess the expression in the If Statement is , is less than . The
computer jumps into the true branch of the if statement.
Figure 5.56: The true branch is taken as is less than
Note
• In Figure 5.56 the indicated areas show the following:
1. is less than so the true branch is executed.
2. This means the code jumps to step 5. ♠
348
5.5. UNDERSTANDING CONTROL FLOW
Once step 5 finishes, control jumps to step 11, skipping the else branch of the if statement
from step 4.
2
Execution jumps to step 11
Figure 5.57: ( finishes for guess 1, returning the result
Note
• In Figure 5.57 the indicated areas show the following:
1. Steps 6 to 10 are skipped as the true branch was taken.
♠
2. The next instruction is therefore step 11.
3. This evaluates the expression equals , which is .
349
CHAPTER 5. CONTROL FLOW
( is called again, this time it is passed 2 for
and 37 for . This
executes the code in ( , one instruction at a time, eventually reaching step 4.
Figure 5.58: ( is run for guess 2 and advanced to step 4
Note
• In Figure 5.58 the indicated areas show the following:
1. The call to ( is passed 2 for the
parameter, and 37 for
the parameter.
2. The user enters 25 as their guess, this is read into the variable.
• The previous call ended and control returned to the caller. This is a now a new call ♠
to ( .
• Step 1 outputs a prompts for the user to enter ‘Guess 2: ’.
• Step 2 reads a the user’s response into the variable.
• When the computer executes step 4 it evaluates the If Statement’s expression and
then selectively runs one of the two available paths.
350
5.5. UNDERSTANDING CONTROL FLOW
With the second guess the expression in the If Statement is , is not less than
. The computer jumps into the else branch of the if statement.
Figure 5.59: Control jumps to step 7 as the target is not less than the guess
Note
• In Figure 5.59 the indicated areas show the following:
1. is not less than so the else branch is executed.
2. This means the code jumps to step 7, skipping the true branch. ♠
• Step 7 is another If Statement, it checks if is larger than . This expres-
sion is , so it will take the true branch next.
351
CHAPTER 5. CONTROL FLOW
The expression in step 7 is , so the if statement directs the computer into the true branch
at step 8.
Figure 5.60: Control continues into the true branch of the inner if statement
Note
• In Figure 5.60 the indicated areas show the following:
1. is larger than so the true branch is taken.
2. This means the code jumps to step 8. ♠
• Step 8 outputs the message ‘The number if larger than 25’ to the Terminal.
352
5.5. UNDERSTANDING CONTROL FLOW
Once step 8 finishes, control jumps to step 11, skipping the else branch of the if statement
from step 7 and also ending the if statement started at step 4.
2
Execution jumps to step 11
Note
• In Figure 5.61 the indicated areas show the following:
1. The else branch starting at step 9 is skipped as the true branch was taken.
2. The next instruction is therefore step 11, ending the if statements starts at steps
♠
7 and 4.
3. ( returns the result as the expression equals is
.
353
CHAPTER 5. CONTROL FLOW
( is called again, this time it is passed 3 for
and 37 for . This
executes the code in ( , one instruction at a time, eventually reaching step 4.
Figure 5.62: ( is run for guess 3 and advanced to step 4
Note
• In Figure 5.62 the indicated areas show the following:
1. The call to ( is passed 3 for the
parameter, and 37 for
the parameter.
2. The user enters 37 as their guess, this is read into the variable.
• The previous call ended and control returned to the caller. This is a now a new call
to ( . ♠
• Step 1 outputs a prompts for the user to enter ‘Guess 3: ’.
• Step 2 reads a the user’s response into the variable.
• When the computer executes step 4 it evaluates the If Statement’s expression and
then selectively runs one of the two available paths. In this case the expression is
as is not less than .
354
5.5. UNDERSTANDING CONTROL FLOW
The is not less than the user’s guess, so the else branch of the if statement at step 4
is taken, with the computer jumping to step 7.
Figure 5.63: The else branch is taken as is not less than for guess 3
Note
• In Figure 5.63 the indicated areas show the following:
1. is not less than so the else branch is executed.
2. This means the code jumps to step 7, skipping the true branch. ♠
• Step 7 is another If Statement, it checks if is larger than . This expres-
sion is also , is not larger than .
355
CHAPTER 5. CONTROL FLOW
The is not larger than the user’s guess, so the else branch of the if statement at step
7 is taken, with the computer jumping to step 10.
Figure 5.64: The is not larger than , so the else branch of the if statement at step 7 is taken.
Note
• In Figure 5.64 the indicated areas show the following:
1. is not larger than so the else branch is executed.
2. This means the code jumps to step 10, skipping the true branch. ♠
• Step 10 outputs ‘Well done. . . the number was 37’ to the Terminal.
356
5.5. UNDERSTANDING CONTROL FLOW
Once step 10 finishes, control jumps to step 11, ending the if statements from step 7 and
step 4.
1
Branches end,
execution jumps to step 11
Note
• In Figure 5.65 the indicated areas show the following:
1. The if statements at steps 7 and 4 end, with control jumping to step 11. ♠
2. The result returned will be , does equal .
357
CHAPTER 5. CONTROL FLOW
Figure 5.66 shows the flowchart for the ( procedure that was developed in Sec-
tion 5.2.5 on Designing Control Flow for Play Game. The following sections outline how these
actions are executed within the computer.
Play Game
Got It or Guess No
Number is larger
than or equal to 7
Yes
Yes
Not Got It
No
Output "You ran out of
guesses, the number
was ', and My Number
End
In the following illustrations ( will be called once, and will perform three guesses.
These three guesses match the calls illustrated in Section 5.5.1 Understanding Branching in
Perform Guess. In each case the details of the call into ( will not be recovered,
but you can refer back to the previous section if needed.
The illustrations will show how the loop in the flowchart is handled by the computer. As
this includes a /
loop, the explanations will present both boolean
expressions. Please ensure that you check the logic based on the implementation you will
use.
358
5.5. UNDERSTANDING CONTROL FLOW
( is called
At some point the ( procedure is called. This will be responsible for coordinating the
actions needed to play one game of Guess that Number. It will call ( to do the
work needed to perform each individual guess.
Figure 5.67: ( is called, it is allocated space on the Stack for its local variables
Note
• In Figure 5.67 the indicated areas show the following:
1. ( is allocated spaces on the stack for its local variables.
• Local variables are not initialised, so their values are whatever happened to be at
that location in memory before. ♠
• Step 1 generates a random number and stores this in
.
• Step 2 initialises the value of
with the value 0.
• Step 3 will output a message indicating the start of the game.
359
CHAPTER 5. CONTROL FLOW
Figure 5.68
Note
• In Figure 5.68 the indicated areas show the following:
1. Steps 1 to 3 are executed, and then control enters the repeated block.
• The repeated instructions will continue as normal. ♠
• If this were a Pre-Test Loop, the condition would be checked before the loop body
was executed. Other than that the two kinds of loops are the same.
C++
Remember that in C the Post-Test Loop is the C Do While Loop. This is similar to
♢
, differing only in the way the boolean condition is expressed.
Pascal
Remember that in Pascal the Post-Test Loop is
. This is similar to
♡
, differing only in the way the boolean condition is expressed.
360
5.5. UNDERSTANDING CONTROL FLOW
Perform Guess
2 returns false, so this
is stored in got it
I am think of a number ...
Guess 1: 50
The number is less than 50
Figure 5.69
Note
• In Figure 5.69 the indicated areas show the following:
1. This calls ( passing 1 to its
parameter, and 37 to its
parameter.
2. ( returns , indicating that the user did not guess the number.
• The following sections outline what occurred in ( : ♠
– Perform Guess is called for guess 1
– Execution reaches the if branch for guess 1
– If takes the True branch for guess 1
– Control jumps to the end of ( for guess 1
361
CHAPTER 5. CONTROL FLOW
Loop condition is checked at the end of guess 1, with the loop being repeated
At the end of the loop the condition is checked, in this case the loop will run again.
Figure 5.70: Condition indicates that the loop’s body should be executed again
Note
• In Figure 5.70 the indicated areas show the following:
1. The condition is checked, and the expression is .
• With
you can evaluate the expression by:
1. & %07-+++ is , this is false
2. , this is a variable, its value is false ♠
3. Or the above together, , this is false, repeating the loop.
• With you can evaluate the expression by:
1. & %07-+++ is , this is true
2. , this is a variable, its value is false, so , is
, is true
3. And together these results,
is true, repeating the loop.
C++
For C you will need to code this as a C Do While Loop. The code for this will be
♢
7
%07-+++ 7
Pascal
For Pascal you will need to code this as a Pascal Repeat Until Loop. The code for this will
♡
be
7
%07-+++ 7
362
5.5. UNDERSTANDING CONTROL FLOW
Figure 5.71: Control returns to step 5 to repeat the body of the loop
Note
• In Figure 5.71 the indicated areas show the following:
1. The loop’s body starts at step 5, so control jumps back to this point to repeat
the instructions in the loop. ♠
363
CHAPTER 5. CONTROL FLOW
In the body of the loop, step 5 increases the value in
to 2 then control continues to
step 6. This step calls ( , to allow the user to perform the second guess. This time
around it is passed 2 for the
, and 37 for the . When ( ends the
result is false again, which is stored in .
Perform Guess
2 returns false, so this
is stored in got it
I am think of a number ...
Guess 1: 50
The number is less than 50
Guess 2: 25
The number is larger than 25
Figure 5.72: ( is called again, it is passed 2 for its and for its parameter
Note
• In Figure 5.72 the indicated areas show the following:
1. This calls ( passing 2 to its
parameter, and 37 to its
parameter.
2. ( returns , indicating that the user did not guess the number.
• The following sections outline what occurred in this call to ( : ♠
1. ( is called again for guess 2
2. If takes the else branch for guess 2
3. The inner if’s true branch is taken in guess 2
4. Control jumps to the end of ( for guess 2
364
5.5. UNDERSTANDING CONTROL FLOW
Loop condition is checked at the end of guess 2, with the loop being repeated
The loop condition is checked again, and it indicates that the body needs to be repeated
again.
Figure 5.73
Note
• In Figure 5.73 the indicated areas show the following:
1. The condition indicates that the loop’s body needs to be repeated, allowing the
user to enter guess 3.
• The same logic can be applied as shown in Loop condition is checked at the end of
guess 1, with the loop being repeated.
• With
you can evaluate the expression by:
1. & %07-+++ is
, this is false ♠
2. , this is a variable, its value is false
3. Or the above together, , this is false, repeating the loop.
• With you can evaluate the expression by:
1. & %07-+++ is
, this is true
2. , this is a variable, its value is false, so , is
, is true
3. And together these results,
is true, repeating the loop.
365
CHAPTER 5. CONTROL FLOW
( is called a third time, and returns true for guess 3
Just as with guess 2, the body of the loop is repeated. Step 5 increases the value in
to 3 then control continues to step 6. This step calls ( , to allow the user to
perform the third guess. This time around it is passed 3 for the
, and 37 for the
. When ( ends the result is now true, which is stored in .
Perform Guess
2 returns true, so this
is stored in got it
I am think of a number ...
Guess 1: 50
The number is less than 50
Guess 2: 25
The number is larger than 25
Guess 3: 37
Well done... the number was 37
Figure 5.74: ( is called for the third time, this time the user guesses the number
Note
• In Figure 5.74 the indicated areas show the following:
1. This calls ( passing 3 to its
parameter, and 37 to its
parameter.
2. ( returns , indicating that the user has guessed the number.
We now want the loop to end, as the number has been guessed.
♠
• The following sections outline what occurred in this call to ( :
1. Perform Guess is called again for guess 3.
2. If takes the else branch for guess 3.
3. The inner if’s else branch is taken in guess 3.
4. Control jumps to the end of ( for guess 3.
366
5.5. UNDERSTANDING CONTROL FLOW
The loop condition is checked again, and this time it indicates that the loop should end.
Figure 5.75: Condition is checked, this time it indicates that the loop should end
Note
• In Figure 5.75 the indicated areas show the following:
1. The condition indicates that the loop should end.
• With
you can evaluate the expression by:
1. & %07-+++ is , this is false
2. , this is a variable, its value is true
3. Or the above together, , is true, ending the loop. ♠
• With you can evaluate the expression by:
1. & %07-+++ is , this is true
2. , this is a variable, its value is true, so , is
, is false
3. And together these results,
is false, ending the loop.
• Notice how the boolean is used to stop the loop when the user gets the answer.
This is the purpose of this variable.
367
CHAPTER 5. CONTROL FLOW
The branch after the loop’s body outputs the number if the user did not guess it.
Figure 5.76: Branch after the loop outputs the answer if the users did not guess the number
Note
• In Figure 5.76 the indicated areas show the following:
1. The If Statement checks if the user guessed the number ( ).
2. If they did not guess the number then the number is output.
♠
• In this case the condition is false, so the true branch is skipped. This ends the if
statement, and the procedure allowing control to return to the calling code.
• This needed to use , as the user may guess the number on the last guess.
368
5.5. UNDERSTANDING CONTROL FLOW
Figure 5.77 shows the flowchart for the (
$
procedure that was developed in Sec-
tion 5.2.6 on Designing Control Flow for Print Line. The following sections outline how these
actions are executed within the computer.
Print Line
Set i to 0
Yes No
i less than
Length
Output a "-"
increase i by 1
End
Figure 5.77: Logic for the ( $ Procedure from Figure 5.35
The illustrations will show a single execution of the (
$
procedure, with 3 being passed
to its
parameter. This call will output a three line of dash characters, demonstrating
how the Pre-Test Loop differs from the Post-Test Loop.
369
CHAPTER 5. CONTROL FLOW
The illustration starts with the call to (
$
. It is called to print a line of three dash (-)
characters to the Terminal.
Note
• In Figure 5.78 the indicated areas show the following:
1. At some stage in the program (
$
is called, and its loaded onto the stack.
2. The
parameter is passed the number of dash characters to be printed in
the line. In this case that is 3. ♠
• The local variable is uninitialised, and has the value that was last at that location
in memory.
370
5.5. UNDERSTANDING CONTROL FLOW
The first instructions are executed as normal, initialising the value of the variable. At the
loop the computer checks the condition and determines that the loop should execute.
This means that the next instruction will be taken from Step 3 of the code.
Step 1 initialised i,
1
setting its value to 0
Note
• In Figure 5.79 the indicated areas show the following:
1. Step 1 assigns the value 0 to .
2. Step 2 checks the condition to determine which path to take.
3. As is less than
control will flow to Step 3.
• The loop only checks the condition at the start of the loop. It is at this point ♠
that it decides if the code should enter the loop, or if it should end the loop by
skipping the loop’s body.
• In this case the condition indicate the loop should enter, so control enters the body
of the loop.
371
CHAPTER 5. CONTROL FLOW
The body of the loop is entered, and the first instruction (Step 3) outputs a dash to the Termi-
nal.
Step 3 outputs a - to
the Terminal
2
Procedure: Print Line
Print Line
----------------------------
length: 3 Parameters:
1: Length (Integer)
i: 0 Local Variables:
* i (Integer)
Instruction: Step 3 Steps:
1: Assign i, the value 0
2: While i < Length
... 3: Output '-'
4: Increase i by 1
Instruction: ... 5: Output a new line
Note
• In Figure 5.80 the indicated areas show the following:
1. The loop body starts at Step 3.
2. This step outputs a dash to the Terminal. ♠
• You could use this kind of loop to perform any action a number of times. The body
of the loop is then performed once each time the loop executes.
372
5.5. UNDERSTANDING CONTROL FLOW
After outputting the dash, the next instruction (Step 4) increments the value of . In this code
is counting the number of times the loop has been performed. This is the end of the first
loop, so now has the value 1.
Figure 5.81: is keeping track of the number of times the loop has been performed
Note
• In Figure 5.81 the indicated areas show the following:
1. Step 4 increments the value of , allowing it to keep track of the number of times
the loop has executed.
2. Control has reached the end of the loop, but will now return back to the condi-
tion. ♠
• The compiler adds jump code to the end of each Pre-Test Loop. This returns control
to the loop’s condition, thereby making the loop.
•
373
CHAPTER 5. CONTROL FLOW
The while loop checks the condition to determine if the body should be executed again, or if
the loop should end. In this case is still less than
so the body of the loop is executed
again.
Figure 5.82: Loop condition is checked to determine if the loop should run again
Note
• In Figure 5.82 the indicated areas show the following:
1. The condition is checked again, to determine if the body is run or skipped.
2. In this case the loop body is run again as is less than
. ♠
• The Pre-Test Loop is controlled by the condition at the start of the loop.
374
5.5. UNDERSTANDING CONTROL FLOW
The loop body is run again with its first instruction (Step 3) outputting another dash to the
Terminal.
--
Figure 5.83: The loop body is run again, and a second dash is output
Note
• In Figure 5.83 the indicated areas show the following:
1. As before, the loop body starts at Step 3.
2. This step outputs a second dash to the Terminal. ♠
• All the instructions in this sequence will be executed each time the loop is repeated.
375
CHAPTER 5. CONTROL FLOW
The last instruction in this sequence increments the value of , indicating that the loop has
run twice. Once again, control returns jumps back to the condition. It is the condition that
will determine when the loop ends, the end of the loop just indicates that control will return
back to the condition.
--
Figure 5.84: is incremented, and then control returns back to the loop’s condition
Note
• In Figure 5.84 the indicated areas show the following:
1. Step 4 increments the value of . This is keeping track of the number of times
through the loop, indicating that the loop has run twice.
2. Control has reached the end of the loop and now jumps back to the condition. ♠
• The Post-Test Loop will always be performed in this way. The body of the loop runs,
and then control jumps back to the condition.
376
5.5. UNDERSTANDING CONTROL FLOW
When the condition is checked it determines if the loop body runs, or is skipped. In this case
is still less than
so the body is run a third time.
--
Figure 5.85: While determines that the loop should run again
Note
• In Figure 5.85 the indicated areas show the following:
1. The condition is checked again, to determine if the body is run or skipped.
2. In this case the loop body is run again, as is less than
.
♠
• It is important to notice that this is only checked once each time the loop runs. It
is checked when the condition is checked upon entry, and then again each time the
loop jumps back to this step.
377
CHAPTER 5. CONTROL FLOW
The loop body is entered a third time, and its sequence of instructions is executed. This
outputs a third dash to the Terminal.
---
Note
• In Figure 5.86 the indicated areas show the following:
1. As before, the loop body starts at Step 3.
2. This step outputs a second dash to the Terminal. ♠
378
5.5. UNDERSTANDING CONTROL FLOW
is incremented again, indicating the loop has been performed three times
When Step 4 is executed is incremented again, and now has the value 3. As this is the end
of the loop, control will jump back to condition.
---
Figure 5.87: is incremented again, and then control jumps back to the condition
Note
• In Figure 5.87 the indicated areas show the following:
1. Step 4 increments the value of . This is keeping track of the number of times
through the loop, indicating that the loop has run twice.
2. Control has reached the end of the loop and now jumps back to the condition. ♠
• The loop is controlled by the condition at the start, so it does not end at this point
but it will end when the condition is next checked.
379
CHAPTER 5. CONTROL FLOW
The condition is checked again, and this time is not less than
and so the loop body is
not run again. Instead the computer jumps to the first instruction after the loop, Step 5.
---
Figure 5.88: The condition is now false, and so the computer jumps past the loop body to Step 5
Note
• In Figure 5.88 the indicated areas show the following:
1. After the loop body completes, control always returns back to the start of the
loop. It is this check that is controlling the loop, and it is only performed at this
point.
2. At this point is not less than
, and therefore the body of the loop must ♠
be skipped.
• The next instruction will be Step 5, the first instruction past the end of the loop.
This is the single exit point from the loop.
380
5.5. UNDERSTANDING CONTROL FLOW
Having completed the loop, the next instruction outputs a new line
Now that the loop has finished, control continues running the sequence from the Proce-
dure.
---
Note
• In Figure 5.89 the indicated areas show the following:
1. The condition indicates that the loop has ended, and so the next instruction
is Step 5. This step outputs a new line, ending the line being printed to the
Terminal.
♠
• Notice how the condition controlled the behaviour of the loop. Each time it is checked
it determines if the body is run again, or if it is skipped.
• The condition is only checked once each loop: once at the start, and then once after
each time through the loop body.
381
CHAPTER 5. CONTROL FLOW
This program prints out the times table for a number entered by the user, displaying from 1 x
n to 10 x n. The description of the program is in Table 5.15, the pseudocode in Listing 5.26,
the C code in Listing 5.27, and the Pascal code in Listing 5.28.
Program Description
Name Times Table
Pseudocode
( , ,
.
!
!
+
' ', , ' ,
' '
' ,
♣
*
' '' ,
/
' ' '
' '
,
' '' ,
Listing 5.26: Pseudocode for Times Table program.
Note
This is an updated version of the Seven Times Table Program. See Section 4.6.1 Times
♠
Table.
382
5.6. CONTROL FLOW EXAMPLES
C++
( 7
, ,
4
4
Listing 5.27: C Times Table
383
CHAPTER 5. CONTROL FLOW
Pascal
( ,,
, ,
,,
%
!
!
/$
', , '
/$ '' ♡
/$
' ' ' '
' '
/$
''
%
Listing 5.28: Pascal Times Table
384
5.6. CONTROL FLOW EXAMPLES
This program prints out the area of a circle. The description of the program is in Table 5.16,
the pseudocode in Listing 5.29, the C code in Listing 5.30, and the Pascal code in Listing
5.31.
Program Description
Name Circle Areas
Description Displays the Circle Areas for circles with radius from 1.0 to
5.0 with increments of 0.1.
Pseudocode
(
(!
+,*,7*!-+
&7*!-+
*!-+7!&
.
+
' ' ' ,
' '' ,
+,*,7*!-+
/ &7*!-+
' ' * ' ' ' ,
*!-+7!&
' '' ,
Listing 5.29: Pseudocode for Circle Areas program.
Note
This is an updated version of the Circle Areas Program. See Section 4.6.2 Circle Area. ♠
385
CHAPTER 5. CONTROL FLOW
C++
( 7
(!
+,*,7*!-+
&7*!-+
*!-+7!&
♢
+,*,7*!-+
Listing 5.30: C Circle Areas
386
5.6. CONTROL FLOW EXAMPLES
Pascal
( 7
(!
+,*,7*!-+
&7*!-+
*!-+7!&
%
♡
/$
' '
/$
''
+,*,7*!-+
%
Listing 5.31: Pascal Circle Areas
387
CHAPTER 5. CONTROL FLOW
This example SwinGame code will move a rectangle back and forth across the screen.
Program Description
Name Moving Rectangle
388
5.6. CONTROL FLOW EXAMPLES
C++
*,7/!,
*,7 ! ,
%'.70
*,7/!,
7
7 *,7/!,
7
Listing 5.32: C++ Moving Rect SwinGame code
389
CHAPTER 5. CONTROL FLOW
Pascal
*,7/!,
*,7 ! ,
%'.70
*,7/!, +
/
+
/ *,7/!,
(
%
Listing 5.33: Pascal Moving Rect SwinGame code
390
5.6. CONTROL FLOW EXAMPLES
This example SwinGame code draws a rectangle that the user can ‘click’.
Program Description
Name Button Click
Description Displays a rectangle the user can ‘click’. Having the mouse
held down over the rectangle changes it to a filled rectangle.
Clicking the rectangle shows the text ‘Clicked’ in the top left
corner.
391
CHAPTER 5. CONTROL FLOW
C++
,&70
,&71
,&7/
,&7
7
7
7
7
$,7-,,'& 7
7
,&70 ,&71 ,&7/ ,&7
7 $!#
7
7 7
Listing 5.34: C++ Simple Button using SwinGame code
392
5.6. CONTROL FLOW EXAMPLES
Pascal
!
, ,
,&70 ,&71
,&7/
,&7
!
%
$
%'
,&70 ,&71 ,&7/ ,&7
, '$!# '
%
Listing 5.35: Pascal Button Click code
393
CHAPTER 5. CONTROL FLOW
Read over the concepts in this chapter and answer the following questions:
1. What values can a Boolean expression have?
2. What are the values of the following expressions?
C++
The following table shows the C syntax for these boolean expressions.
Question Expression
(a)
(b)
(c)
(d)
(e)
(f) ♢
(g)
(h)
(i)
(j) 6
(k)
(l)
(m)
394
5.7. CONTROL FLOW EXERCISES
395
CHAPTER 5. CONTROL FLOW
Use what you have learnt to read and understand the following code samples, and answer the
associated questions.
1. Read the C code in Listing 5.36, or the Pascal code in Listing 5.37, and then answer the
following questions:
(a) What are 0 +(, , , , and ? How are they similar/different? What
purpose does each of these play? What values are they assigned?
(b) What does the loop in this code do?
(c) Briefly explain what this code does, and suggest a name for the procedure.
(d) Provide an example of how you could call this procedure.
C++
07+(
7
Listing 5.36: What does this C code do?
2. Read the C code in Listing 5.38, or the Pascal code in Listing 5.39, and then answer the
following questions:
(a) What will be drawn to the screen when the user is not holding down any key?
(b) When the user is holding down the G key what will be drawn?
(c) When the user is holding down the R and B keys what will be drawn?
(d) What condition causes the loop to end? How can a user end this loop?
(e) Draw a flow chart to illustrate the possible paths through this code.
396
5.7. CONTROL FLOW EXERCISES
Pascal
07+(
*+
Listing 5.37: What does this Pascal code do?
C++
7
.#7* 7
*
♢
7
.#7 7
7
.#7 7
7
7 .#7+(
Listing 5.38: What does this C code do?
397
CHAPTER 5. CONTROL FLOW
Pascal
#
7*
*
*
#
7
*
♡
#
7
*
*+
#,
7+(
Listing 5.39: What does this Pascal code do?
398
5.7. CONTROL FLOW EXERCISES
3. Read the C code in Listing 5.40, or the Pascal code in Listing 5.41, and then answer the
following questions:
(a) What do the local variables and parameter keep track of?
(b) How many times will the loop execute?
(c) What is the purpose of the if statement within the loop?
(d) What will be drawn to the screen when this procedure is called?
C++
7
7
7
7
7
♢
7
/ 7
7
7
7
7
7
Listing 5.40: What does this C code do?
Pascal
/
♡
*
/ / +
*
/ +
*+
Listing 5.41: What does this Pascal code do?
399
CHAPTER 5. CONTROL FLOW
4. Read the C code in Listing 5.42, or the Pascal code in Listing 5.43, and then answer the
following questions:
(a) What will be drawn to the screen when the user is not holding down any key?
(b) When the user is holding down the G key what will be drawn?
(c) When the user is holding down the R and B keys what will be drawn?
(d) What condition causes the loop to end? How can a user end this loop?
(e) Draw a flow chart to illustrate the possible paths through this code.
C++
7
.#7* 7
*
7
.#7 7
♢
7
.#7 7
7
7
7 .#7+(
77
Listing 5.42: What does this C code do?
Pascal
#
7*
*
*
#
7
*
♡
#
7
*
*
*+
#,
7+( /
*
Listing 5.43: What does this Pascal code do?
400
5.7. CONTROL FLOW EXERCISES
5. Read the C code in Listing 5.44, or the Pascal code in Listing 5.45, and then answer the
following questions:
(a) What value is stored in the variable each time through the loop?
(b) Explain what will be drawn on the screen when this code is executed. How does this
code respond to user actions?
(c) Do the circles appear on top of, or below the frame rate? Explain.
(d) How frequently are the actions in the loop performed?
(e) How would putting a call to inside this loop effect the running of this program?
C++
$*7*!-+
+%$$7*!-+
7
7 7
7
7 7
7 7
7
/ ♢
7
7
7 7 $*7*!-+
7
$,7-,,'&
7
7 7 +%$$7*!-+
7
7 7 +%$$7*!-+
7
7
Listing 5.44: What does this C code do?
401
CHAPTER 5. CONTROL FLOW
Pascal
$*7*!-+
+%$$7*!-+
0 1 +
%
0 %0
1 %1
♡
+
/
0 1 $*7*!-+
*+
+%
Listing 5.45: What does this Pascal code do?
402
5.7. CONTROL FLOW EXERCISES
6. Read the C code in Listing 5.46, or the Pascal code in Listing 5.47, and then answer the
following questions:
(a) What is the purpose of the if statement in this code? What is it testing?
(b) When will the color of the rectangle change? What are the conditions that must be
met?
(c) If the user clicks the left button on their mouse will the color of the rectangle change?
discuss
(d) What would need to be added to keep a score of the number of times the user changed
the color? explain
403
CHAPTER 5. CONTROL FLOW
C++
7
7
'
7
7
$,7-,,'&
7
7 7 7
7
♢
7
/
7
7
7 .#7+(
77
Listing 5.46: What does this C code do?
Pascal
(
+
+
*
*
'
7
%
$,7-,,'&
(
!
* %0 %1
♡
*
*
+
/
*
*+
#,
7+( /
*
Listing 5.47: What does this Pascal code do?
404
5.7. CONTROL FLOW EXERCISES
7. Read the C code in Listing 5.48, or the Pascal code in Listing 5.49, and then answer the
following questions:
(a) What would be better names for the and variables?
(b) How many rectangles are drawn to the screen when this procedure is called?
(c) What does this code draw to the screen when it is called?
(d) How would you need to change the code to ensure that the rectangles were always
square?
C++
7
7
7
7
7
7
7
7
7
♢
7
7
/ 7 7
7
7 7
7
Listing 5.48: What does this C code do?
405
CHAPTER 5. CONTROL FLOW
Pascal
*
♡
/
7
/ /
7
/
*+
Listing 5.49: What does this Pascal code do?
406
5.7. CONTROL FLOW EXERCISES
C++
You can use
to read in the value entered into a vari-
able, and to check if it was a numbera , and you can use
36∖
5 to flush the
input when you get something other than a number. ♢
a The
function returns the number of values successfully read. See C Terminal Input.
8. Use your * !
function to read two values from the user, and then output the
larger of the two values.
9. Use your * !
function to read in a number, and then print out a custom message
for different values. For example, the value
could have the message ‘The meaning of
life...’, the value could have the message ‘The best number, according to Dr. Sheldon
Cooper’, etc. Have at least five custom messages, and a default message when the user
does not enter one of the selected values.
10. Update your custom message program, and have it ask the user if they want to quit at
the end, allowing them to print multiple message values.
407
CHAPTER 5. CONTROL FLOW
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. Implement a Number Guesser program that will guess numbers between 1 and 100. See
the program description in Table 5.19
Program Description
Name Number Guesser
Description This program will work to guess a number that the player
is thinking of between 1 and 100. This will prompt the
user to think of a number, and it will then guess using the
following algorithm. The first guess will be 50 (the point
half way between 1 and 100). The user will then enter a
character to tell the computer how that value relates to the
target value: ‘E’ for equal, ‘L’ for your guess is less than the
target, and ‘G’ for your guess is greater than the target.
When the guess is less than the target the computer will
take another guess that is half way between the guess and
the pervious upper value (e.g. 1-100 = 50, 50-100 = 75,
75-100 = 87, 25-50 = 37, etc).
When the guess is larger than the target the computer will
take another guess that is half way between the guess and
the pervious lower value (e.g. 1-100 = 50, 1-50 = 25, 1-25
= 12, 50-75 = 62, etc).
2. Create a SwinGame project called Key Test. See the description in Table 5.20.
Program Description
Name Key Test
Description This SwinGame will draw a filled red rectangle in the center
of the screen when the user holds down the r key.
3. Extend the Key Test program to draw other shapes when different keys are held down.
For example, draw a filled circle when the user holds down the c key.
C++
You can call
.# * to test if the ‘r’ key is held down, then only draw the rectangle
♢
if this key is held down.
408
5.7. CONTROL FLOW EXERCISES
4. Color can be represented as consisting of three components: hue, saturation, and bright-
ness. The hue component represents the color, the saturation is how much of this color
is added to the white point, and the white point is controlled by the brightness and moves
from black through grey to white. An illustration of this is shown in Figure 5.93.
SwinGame includes a ( procedure that allows you to draw a single pixel on the
screen. We can use this to draw a color banding across the screen by calculating the
color for each pixel using SwinGame’s + function.
The structure of this program can be broken into three blocks: a function, a %
+
procedure and a %
procedure. This structure is shown in Figure 5.94.
Main
offset
MyClearScreen
x, y, offset color
ColorAt
409
CHAPTER 5. CONTROL FLOW
The function will be used to calculate the color for each pixel on the screen.
This will be passed the and coordinates of the pixel (Integers) and an 4 (a
Double value). This function will call SwinGame’s + function, passing in a hue
calculated using the equation shown below, with saturation and brightness set to 0.9
and 0.8 respectively, and it will return the resulting color.
𝑥+𝑦
(𝑂𝑓 𝑓 𝑠𝑒𝑡 + )
𝑆𝑐𝑟𝑒𝑒𝑛𝑊 𝑖𝑑𝑡ℎ + 𝑆𝑐𝑟𝑒𝑒𝑛𝐻𝑒𝑖𝑔ℎ𝑡
ℎ𝑢𝑒 = 5.1
2
The equation will cycle the hue value between 0 and 1, covering the full spectrum of color.
The component will alter the color of the pixel based on its position on the screen,
while the offset allows the program to change the color of the first pixel as time passes.
The % +
procedure will loop through all of the pixels across the screen (with
x going from 0 up to (but not including) ScreenWidth()). This loop will select a single
column of pixels on the screen, the pixels at the given x position. As this column has
ScreenHeight() pixels you need an inner loop that loops from 0 to ScreenHeight(). Inside
the inner loop the values give you the coordinates of an individual pixel. You can now
use the ( procedure to draw this pixel, using the function you wrote
to determine its color.
Lastly the %
procedure will contain the standard game loop provided in the SwinGame
project template. Replace the code within the loop so that it calls % +
then
* +
and lastly (
. Within %
you need to maintain an offset
value that you increment by a fixed value each loop5 , always ensuring the value is between
0 and 1. This offset is then passed to % +
when it is called.
See if you can use this information, and program design to create a small screensaver
program. Experiment with different values and loops to see what effects you can create.
4 Offset must have a value between 0 and 1 as the value for Hue must be between 0 and 1.
5 Trial this with different value ¡ 1
410
Managing Multiple Values
6
rue magic has the power to affect not just one, but many targets. The
secrets you will learn today will make it possible for your magic to be
applied to many targets. The key is to. . .
Previous chapters have introduced a number programming artefacts for you to create within
your code. However, when it comes to working with data in your programs you have been
limited in the way you deal with multiple values. This chapter introduces the concepts and
practices that make it easier to work with multiple values in your code.
When you have understood the material in this chapter you will be able to work with multiple
values more easily, allowing your programs to work with many data values.
Contents
6.1 Concepts Related to Managing Multiple Values . . . . . . . . . . . . . . . . . . 413
6.1.1 Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
6.1.2 Assignment Statement (with Arrays) . . . . . . . . . . . . . . . . . . . . . . 416
6.1.3 Expressions (with Arrays) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
6.1.4 Pass by Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
6.1.5 For Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
6.1.6 String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
6.1.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
6.2 Using these Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
6.2.1 Designing Statistics Calculator . . . . . . . . . . . . . . . . . . . . . . . . . 423
6.2.2 Understanding the Statistics Calculator . . . . . . . . . . . . . . . . . . . . 423
6.2.3 Choosing Artefacts for Statistics Calculator . . . . . . . . . . . . . . . . . . 429
6.2.4 Writing the Code for Statistics Calculator . . . . . . . . . . . . . . . . . . . 434
6.2.5 Compiling and Running Statistics Calculator . . . . . . . . . . . . . . . . . 435
6.3 Managing Multiple Values in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
6.3.1 Implementing Statistics Calculator in C . . . . . . . . . . . . . . . . . . . . 436
6.3.2 C Array Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
6.3.3 C Array Copying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
6.3.4 C For Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
6.3.5 C String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
6.3.6 C Function (with Array Parameters) . . . . . . . . . . . . . . . . . . . . . . 445
6.4 Managing Multiple Values in Pascal . . . . . . . . . . . . . . . . . . . . . . . . . 447
6.4.1 Implementing Statistics Calculator in Pascal . . . . . . . . . . . . . . . . . 447
6.4.2 Pascal Array Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
6.4.3 Pascal For Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
6.4.4 Pascal Array Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
411
CHAPTER 6. MANAGING MULTIPLE VALUES
412
6.1. CONCEPTS RELATED TO MANAGING MULTIPLE VALUES
Data is an important part of any program. Earlier chapters have shown how to store and work
with data. These chapters covered both the Types of data you can work with, and means of
storing and exchanging data using Variables. So far each Variable has stored only a single
value, making it difficult to work with multiple values. This chapter introduces the concepts
needed start working more effectively with multiple values.
The chapter introduces the following artefacts:
• Array: A kind of variable that is used to store multiple values. The individual values in
the array are called elements.
• String: An existing Type that stores textual data.
The following actions are then needed to work with Arrays:
• For Loop: A Pre-Test Loop that can be used to easily repeat a block of code for each
element of an array.
• Expressions (with Arrays): Expressions can read the value from the element of an array.
• Assignment Statement (with Arrays): The assignment statement can be used to assign a
value to an element in an array.
413
CHAPTER 6. MANAGING MULTIPLE VALUES
6.1.1 Array
An array is a special kind of Variable, one that stores multiple values instead of a single value.
The values within an array, called elements, are all of the same Type.
10100101
You use an index Variable Type
to access each value in
the array
The Type determines the
Is a kind of size of each value in the
Variable used to array and how these values
store multiple values are interpreted
10
10
Stores multiple 01
values 01 10100101 11111101 00000000
Array
Note
• An array is an artefact, a kind of variable that you can create in your code.
• Each array has a number of elements.
• The elements of an array are accessed via an index. The first element has the index 0,
the second has the index 1, etc. See Arrays in Memory.
• Individual elements of an array are much like a standard variable. ♠
• You can store a value in an element of an array using an Assignment Statement (with
Arrays).
• You can use a the value from an element of an array using Expressions (with Arrays).
• The For Loop can be used to perform an action for each element of an array.
414
6.1. CONCEPTS RELATED TO MANAGING MULTIPLE VALUES
Arrays in Memory
Arrays store multiple values, with an index that provides access to the individual elements
within the array. Conceptually this can be viewed as a Variable that contains multiple slots
(the elements) into which the values are stored.
Many languages have 0 as the index of the first element. This reflects how the values are
actually stored in memory. Figure 6.3 shows how an array (named in this Figure) is stored
in memory. The array is a contiguous area in memory, with the elements being next to each
other. You can think of the array as starting at the first element, so you need to skip 0 elements
to access the first element. The second element is accessed by skipping 1 element, so it has
index 1. The third element is accessed by skipping 2 elements, so it has the index 2, etc.
The size of each of the elements of the array can then be used to quickly locate each element,
given its index. If you have an array of !
values then these are each 32 bits (4 bytes),
so the element at index 3 is 3 × 32𝑏𝑖𝑡𝑠 (96 bits) past the start of the array.
The great thing is that you do not need to think about these details, but knowing this should
you remember that the first1 element of an array is at index 0.
arr[0] is at
arr + 0 * element size
arr[0] arr[1] is at
arr[1] arr + 1 * element size
arr[2] arr[2] is at
arr + 2 * element size
1010010110100101 00000000
10010011 10100101 10100101 00000000 11011100
Array (arr)
Figure 6.3: Arrays occupy a contiguous area of memory, with elements next to each other in memory
Note
• Arrays are allocated a contiguous area of memory, with the elements next to each
other.
• The array index is used to determine how many elements (values) are skipped to
access the element you require. ♠
• The index of the first element of an array is 0.
• The last index of the array is therefore n - 1, where n is the number of elements in
the array.
1 Some languages allow you to start at other values, but many use 0 based arrays which map more closely to how
415
CHAPTER 6. MANAGING MULTIPLE VALUES
The assignment statement allows you to store a value in a variable. This can now be extended
to allow you to store a value in an element of an array. To achieve this you indicate the array
you want to store the value in, as well as the index at which the value is to be stored.
Value is Expression
In this array [ at index 1 ]
Calculated
and stored
The Value is
in an element in
11 an Expression
11 the array
11
11
10100101 00000000
Array (Data)
stored in 127.5 * 2
Data[1]
When storing a value in an
The right hand side of the
array, you specify both the
Assignment is an Expression,
array and the index you
the value that is to be stored
want the value stored at
Note
• The assignment statement is an action, storing a value in a variable or array.
• When working with arrays you specify the array, and index at which to store the
value.
• This stores a value into an element of an array. ♠
• The two snippets below indicate how this is coded in C and Pascal. In each case
is the name of the array variable, and 1 is the index of the second element. The code
in the snippet stores a 255 in the second element of the array.
C++
In C you can achieve this using: 3 5
. ♢
Pascal
In Pascal you can achieve this using: 3 5
. ♡
416
6.1. CONCEPTS RELATED TO MANAGING MULTIPLE VALUES
Many languages also allow you to copy the entire contents of an array into another array. In
these cases each of the elements of one array are copied into the elements of the destination
array (left hand side of the assignment).
Data Other
You can copy all of the data The right hand side of the
from one array into Assignment is an Expression,
another array the value that is to be stored
Figure 6.5: All of the elements of an array can be copied across in the assignment statement
Note
• The size of the two arrays should match.
• The value from each of the elements of the array on the right hand side will be copied ♠
into the matching element in the array on the left hand side.
C++
This cannot be done in C with an assignment statement, rather it is achieved using the
function. The code for this is as follows, with being the number of elements to ♢
copy. 7
Pascal
In Pascal you can achieve this using: . ♡
417
CHAPTER 6. MANAGING MULTIPLE VALUES
Expressions allow you to read values from the elements of an array. To get an elements value
you must supply the name of the array, and the index of the element you want to read.
Is a value.
1010010110100101 00000000
00
10
00
00
01
00
01
3 * Data[0] + Data[i+1]
The array index is
an Expression Array index values can be calculated.
If the value in i is 1, then this has the value
2, indicating the 3rd element of the array
Figure 6.6: You can read the values back from an array
Note
• Expression is the term given to the code that calculates values within your State-
ments.
• You can read the values of elements of an array in an expression.
• The index values used to access the individual elements of an array are expressions
♠
themselves.
• Arrays are similar to variables in expressions, the expression reads the value from
the element of the array.
• The index you supply determine which value is read.
418
6.1. CONCEPTS RELATED TO MANAGING MULTIPLE VALUES
As with other Variables, you can pass an array to Functions and Procedures. The only real
difference is that the array can potentially store significantly more data than other variables.
When the array is passed by value each of its elements must be passed to the Parameter.
Passing the parameter in this way means that there will be two copies of the data in memory,
which takes more time and more memory.
You should avoid passing arrays by value, and instead pass them by reference. When passed
by reference the array itself is passed across. This gives the called Function or Procedure
access to the data, but does not require that the values be copied across.
One issue with always using pass by reference is that it allows the called code to change the
data in array you are passing across. This can be useful, but at other times you want to pass
the data across without allowing it to be changed by the called code. Both C and Pascal allow
you to indicate that the data you are passing should be passed by reference, but that it cannot
be changed in the called code.
10100101 10 10
10
00
00 1010010110100101 00000000
10
Variable 01 01 00
01 01 00 Array
10100101 Parameter
Variable (by Value)
10100101
Variable
Instruction 1 1010010100000000
10100101 The Array itself
Instruction 2 Array is passed to the
Instruction 3 Parameter
Parameter
... (by Reference)
1010010110100101 00000000
Array
With pass by reference,
The instructions within the
Function or Procedure can
interact with the Array!
Note
• Pass by Reference and Pass by Value are terms that explain how data is passed to
a Parameter.
• With arrays you should always use Pass by Reference. This will be faster and take
♠
less memory.
• The const keyword can be used to indicate that the parameter should not be able to
be changed by the called code.
C++
In C you cannot pass an array by value, instead all arrays are passed by reference auto-
♢
matically by the language.
419
CHAPTER 6. MANAGING MULTIPLE VALUES
As has been shown in previous chapters, Computers can only perform simple actions. They
cannot perform an action on all of the elements in our arrays. For example, a computer cannot
sum all of the values in an array. What you need to do is think of these tasks so that they
can be performed for each value in the array. So the sum would become, for each of the
numbers in the array, add the number to a running total. When this has been performed for
each element in the array you have the sum of all of the elements.
The for loop is a Pre-Test Loop that repeats a block of code a number of times. You can think
of it like a counting loop, with it counting from a start value to an end value. The for loop has
a control variable that has the number of the current loop as its value.
Can be thought of
as a counting loop,
For Loop looping over a range
(Pre-Test Loop) of value (eg. 0 to 2) Iterates over a
range of values
For each
element 0 1 2
The loop value can be
used to apply the action
Each loop to an elements of
runs some an array
instructions
1010010110100101 00000000
Array
Figure 6.8: The for loop can be used to loop through the elements of an array
Note
• A for loop is an action, a kind of statement you can use to command the computer
to perform an action.
• The key is to think about processing each element in an array, rather than thinking
about all elements of an array.
• The for loop can then provide the infrastructure to repeat this code for each element
♠
in the array.
• The for loop is designed to work well with the array. The values in the control variable
can be used to access the individual elements of the array.
• When processing the elements of an array you have it loop from the lowest index
value (0) to the highest index value (n - 1).
420
6.1. CONCEPTS RELATED TO MANAGING MULTIPLE VALUES
6.1.6 String
Is a kind of data...
a Type
Type
String
A String is text data,
a sequence (string) of characters
F r e d S m i t h
10100101
10100101 00000000 Array
Array
10100101
10100101 00000000
Array
Function
10100101 Result Procedure
Variable
Instruction 1
10100101
Parameter
A Functions result may Instruction 2 Parameter
Variable
be a String value Instruction 3
Instruction 1 Parameter Instruction 4
Parameter
... Instruction 5
...
Note
• Boolean is an existing artefact, it is a Type that has been defined to represent text
values.
• A string is an array of characters.
♠
• Both C and Pascal have additional overhead in the string data. In C the overhead is
used to store a single terminating character that indicates the end of the string, in
Pascal this stores the number of characters.
C++
C does not have a native String type, instead you use an array of characters. As a result,
♢
C has very limited support for string data. For details see C String.
421
CHAPTER 6. MANAGING MULTIPLE VALUES
6.1.7 Summary
This Chapter introduced a number of concepts related to working with multiple values in
code.
Term
Statement
Is a kind of
Action
Array
Artefact
Is an array of Is a kind of
Characters Variable with Variable
multiple values
String Artefact
Existing Artefact
Is a Type
Artefact
Note
• The central concept of this chapter is the Array. An array is a variable that can store
multiple values.
• When you work with arrays make any logic you want to apply to all elements will be ♠
coded using for each element and the For Loop.
• Strings are arrays of characters, and can be used to store textual data in your code.
422
6.2. USING THESE CONCEPTS
Arrays make it easier to work with multiple values, allowing you to have a single variable
that stores multiple values. With arrays you can start to create programs that process larger
quantities of data.
Table 6.1 contains a description of a small statistics programs. This program reads a number
of values from the user, and then outputs some statistics calculated from these values. This
program will make use of arrays to store the values entered, and then calculate the required
statistics.
Program Description
Name Statistics Calculator
Description Reads values from the user and calculates a range of statis-
tics that are output to the Terminal. Statistics output in-
clude mean, maximum, sum, and variance.
As before, the process to design and implement this program will follow a number of steps:
1. Understand the problem, and get some ideas on the tasks that need to be performed.
2. Choose the artefacts we will create and use
3. Design the control flow for the procedural2 artefacts
4. Map these artefacts to code
5. Compile and run the program
Most of the ideas around the Statistics Calculator should be fairly straight forward. The main
thing to be checked if the equation needed to calculate the different statistics, and then to
convert these into steps for the computer.
Calculating Sum
The sum is the simplest of the Statistics to calculate. This involves adding together all of
the numbers in the array. The main issue here is that the computer cannot add all of these
values together, and we must rethink our logic to express it in terms of processing for each
element.
Think about the way you would sum a list of numbers, this is now the task you need to code
for the Computer. What is it that you do with each number? To think this through write a
list of random numbers down, and then calculate the sum. Do it slowly, and think about the
tasks that you are performing for each number.
You should have noticed that you are keeping a running total, and that you add the value of
each number from the list to that. When you have done this for each number in the list you
have the total. The Pseudocode for this is shown in Listing 6.1.
2 The program, and any Functions and Procedures.
423
CHAPTER 6. MANAGING MULTIPLE VALUES
Pseudocode
+
*
,
(
!
$ .
!
♣
+
*
Listing 6.1: Pseudocode for Sum
C++
Listing 6.2: C code for Sum Function. You can read the for loop as ‘i starts at 0; while i is less than
size; increment i at the end of the loop’
Pascal
Listing 6.3: Pascal code for Sum Function
There are three key things to notice about the Pseudocode in Listing 6.1. Firstly the For Loop
424
6.2. USING THESE CONCEPTS
is used to repeat the loop once for each element in the array. Second, the variable moves
through the valid indexes for the array. Finally, the total is used to keep the running total
throughout the code.
The for loop in For Loop will repeat its body once for each value in the array. The variable
will be updated to have the current index value each time the loop is repeated. Within the loop
the 𝑖𝑡ℎ value from the array is accessed. This is how the for loop processes each of the values
from the array.
The value keeps track of the current running total. Before the loop its value is set to 0,
ensuring that it is appropriately initialised. In the body of the loop the current (𝑖𝑡ℎ ) value of the
array is added to the , and the result stored back into . This means that by the end
of the loop the variable is now storing the sum of all of the elements of the array.
C and Pascal differ in the amount of support they have for working with arrays. C has very
limited support, meaning that you need to do some extra work. Pascal has more build in
support for arrays, making some common tasks easier to achieve. The main difference is that
C does not keep track of the length of an array. This means that you need to pass the number
of elements in the array along with the array to functions and procedures that will work with
this data. Pascal, on the other hand, does keep track of the length of arrays and gives you
three functions you can use to manage this: $ returns the first index of the array,
returns the last index of the array, $
returns the number of elements in the array.
C++
The C code for the + function is in Listing 6.2. Notice how the parameter is being
used to represent the number of elements in the array. This loop is the standard pattern ♢
used to code For Loops that loop over elements in an array in C.
Pascal
The Pascal code for the + function is in Listing 6.3. Notice how it is using the $ and
functions to get the range of valid array indexes. This loop is the standard pattern ♡
used to code For Loops that loop over elements in an array in Pascal.
425
CHAPTER 6. MANAGING MULTIPLE VALUES
Calculating Mean
The mean of a list of values is the sum of those values divided by the number of values. In the
case of the Statistics Calculator program there is already a + function, so the %
function
does not need to recalculate the sum, it can just call the + and use the result returned.
The length of the array can be calculated in Pascal using its $
function, where as C can
use the parameter to determine the number of elements in the array. In both cases the
basic logic is the same, you use the + function to calculate the sum and then divide this by
the number of elements in the array.
Pseudocode
%
*
,
(
♣
!
+
*
+
Listing 6.4: Pseudocode for Mean
C++
Pascal
426
6.2. USING THESE CONCEPTS
Calculating Maximum
Calculating the largest value in the array, the maximum, will require the logic be adjusted
to use the for each style. How do you calculate the largest value in a list of numbers? With
a small list you are likely to just quickly scan it and see the largest value. Think about the
tasks you need to perform, and maybe think about how you would do it for a very long list of
numbers, one that spans across many pages.
The algorithm needed to find the maximum value in an array needs to perform an action for
each element of the array. It needs to process each value in isolation, ignoring the other values
from the list.
The key is similar to the logic from the + function. You need to keep a running maximum.
This will store the current maximum from the array as you loop through each element of the
array. Like the sum this value can be updated within the loop.
The Pseudocode for this is in Listing 6.7. Notice that its basic layout if the same as the +
function in Listing 6.1. It initialises the value and then loops through the array performing
an action for each value. In this case the action is to check if the 𝑖𝑡ℎ value of the array is larger
than the running maximum in the variable. When this is the case a new maximum has
been found and is stored in the variable.
One of the important differences between % and + is the initialisation of the value.
In % this cannot be initialised to 0 as this would fail to find the maximum if all values
were negative. The maximum must be a value from the array, so it is initialised to the first
value in the array. The for loop will then start looping from the 2𝑛𝑑 element, as the 1𝑠𝑡 has
already been processed.
Pseudocode
%
*
,
(
!
$ .
!
♣
+
*
Listing 6.7: Pseudocode for Maximum
427
CHAPTER 6. MANAGING MULTIPLE VALUES
Calculating Variance
The last statistic to calculate is the Variance. The processing for this will be very similar to the
+ and % functions, though the actual calculation is a little more complex. Equation 6.1
shows how the Variance of a sample is calculated.
𝑛
∑︁
(𝑥𝑖 − 𝑥)2
𝑖=1
𝑣𝑎𝑟(𝑥) = 6.1
𝑛−1
In Equation 6.1 𝑥 is the array being processed, 𝑥 is the mean of 𝑥, 𝑥𝑖 is the value of the 𝑖𝑡ℎ
element of 𝑥, and 𝑛 is the number of elements in the array. The Sigma indicates that 𝑥𝑖 − 𝑥
needs to be summed for each element of 𝑥.
The steps to calculate the Variance are therefore:
1. Determine the value of the mean (𝑥).
2. Calculate (𝑥𝑖 − 𝑥)2 for each element, and store these in a running sum (called ).
3. Divide the value (from ) by the number of elements in the array minus one.
The matching Pseudocode for this is shown in Listing 6.8. In this case 𝑥 is the array. In
Step 1 the mean (𝑥) is calculated once and stored in . The loop starts at Step 3, and runs
for each element of the array. The value (𝑥𝑖 − 𝑥)2 is calculated for each element in Step 4, and
added to the running total stored in . The final result is then calculated and the result
returned in Step 5.
Pseudocode
.
*
, .
(
!
$ .
!
♣
+
%
*
Listing 6.8: Pseudocode for Variance
428
6.2. USING THESE CONCEPTS
In understanding these concepts we have uncovered some Functions that will be included in
the program’s design.
With the calculations thought through the design seems to be coming together. So far we have
thought through the steps needed to calculate the output, but we have not thought about how
these values will be read into the program.
Programs can be thought of as transforming data, taking inputs and generating outputs, as
shown in Figure 6.11. So far we have examined the processing needed to create the outputs,
but we still need to consider how the data gets into the program, the inputs.
Program
Input Output
(Processing)
At the start of the program the user will need to enter the values that will be stored in the
array. This task can be coded in a ( procedure. This will get the user to enter
all of the values into the array. In other words it will allow the user to enter each value in the
array.
The logic for populating the array can be split into a ( procedure that calls a *
function. The * function will be very useful across a number of different
programs, so this may be able to be used elsewhere.
Figure 6.12 shows the flowchart for the process of reading a double value from the user. This
includes a Pre-Test Loop that repeatedly asks the user to enter a number if they value they
enter is not a number. This demonstrates a standard validation loop, in which you read a
value, and check that it is valid in a loop.
The C and Pascal code for this are both slightly different to the flowchart due to different way
they handle input and the features they offer to for converting the value read to a number.
Details of these are shown alongside Listing 6.9 and Listing 6.10.
429
CHAPTER 6. MANAGING MULTIPLE VALUES
Read Double
Output prompt
Read value
from user
Yes No
Value was a
number
Output prompt
Read value
from user
End
430
6.2. USING THESE CONCEPTS
C++
The C version of * , shown in Listing 6.9, uses
(see C Terminal Input)
to read and format the number in the one action. The
Function returns a value
indicating the number of conversions that were successful. This can be checked in the
loop, and the loop is repeated while
did not convert one value.
In the loop itself the
is used to read past the value that is not a number, as
does not proceed when it finds an error. The format string in
indicates that
it should read everything up to the end of the line.
7
Listing 6.9: C code for *
Pascal
The Pascal version of * , shown in Listing 6.10, reads the input as a string and
then try to convert it to a double. The ,+, Function attempts to convert the
text read into a number, storing the value in the result variable.
*
+
+
/
* $
*
/
* $
Listing 6.10: Pascal code for *
431
CHAPTER 6. MANAGING MULTIPLE VALUES
With the logic for * in place the next step is to determine the steps needed in the
( procedure. This procedure will loop and read a value from the user for each
element of the array. This can use the * function to get the value from the user,
and then store this in the array’s elements.
A flowchart illustrating the steps in ( is shown in Figure 6.13. The decision node
is being used to show the control mechanism of the for loop, counting from the lowest index of
the array to the highest index. Within the body of the loop the two instructions build a prompt
string, and then use this in the call to * . The result returned from * is
stored in the current (𝑖𝑡ℎ ) element of the array.
Once again the C and Pascal code differ in how this is implemented, centred on how the prompt
is built within the loop. Pascal has built in support for Strings, so its code is much simpler.
The C code for this requires you to coordinate the steps needed to build the text for the prompt.
The details for these are shown in the text accompanying Listing 6.11 and Listing 6.12.
Populate
Array
Build prompt
'Enter Value i:'
End
The last question to remain is where will the data be stored. The array is a kind of variable,
and therefore the array could be a Local Variable or a Global Variable. As Global Variables
should be avoided where possible, this will be coded as a Local Variable within the program’s
%
procedure. It can then be passed from there to the other Functions and Procedures in
the code.
432
6.2. USING THESE CONCEPTS
C++
The C version of ( is shown in Listing 6.11. This uses the following functions
from
. As C does not know the length of the string each of these functions takes
a number (
) that indicates the maximum number of characters to copy.
•
: String Copy (n characters). The first parameter is the destination, the sec-
ond the source, the third is the number of characters.
•
: Same as
(see C Terminal Output), except that the output is stored
in a c-string. In this case the ensures that only 2 characters (plus the
terminator) are written into the string. See Section 6.3.5 C String.
•
: String Concatenate (n characters). Adds the text in parameter 2 to the end
of the string in parameter 1.
7 35
3 5
35
♢
Pascal
The Pascal version of ( is shown in Listing 6.12. This uses Pascal’s !
,+
function to convert the value from Integer to String.
(
!
+
$ ♡
'
' !
,+ ' '
35 *
Listing 6.12: Pascal code for (
433
CHAPTER 6. MANAGING MULTIPLE VALUES
That completes the logic needed to implement the Statistics Calculator Program. The final
structure is shown in Figure 6.14 as a Structure Chart. Notice the double headed arrow on
in the call from %
to ( . This indicates that the data parameter is passing
the values into, and getting values out of the ( procedure. Also see how the
value is passed out of %
to the functions that calculate the statistics.
data(, siz
Main e)
Variance
varianc
e
e)
da
iz
ta
(s
)
ize
(
,s
,s
ize
m
ta
n
(
da
ta
ea
ea
)
da
n
m
data(, size)
e)
si z
sum Mean
a(,
dat
Populate Array )
siz
e
,
ta(
double value
m
da
su
prompt
Max
Sum
Read Double
Figure 6.14: Structure Chart showing the structure of the + program
Note
• Remember anytime you need to do something with all of the elements in an array
you need to work out how you can achieve this for each element in the array.
• Notice that the processing of individual value from the arrays are always similar. ♠
• Make sure you can see how the for loop is able to perform these values for each
element of the array.
The flowcharts and Pseudocode shown communicate the logic that needs to be coded into the
Functions and Procedures of this program. The following two sections, Section 6.3 Managing
Multiple Values in C and Section 6.4 Managing Multiple Values in Pascal, contain a description
of the syntax needed to code arrays in the C and Pascal programming languages. This infor-
mation can be used to write the code for the Statistics Calculator, and other programs.
434
6.2. USING THESE CONCEPTS
When the code is finished you can compile and run the program. It is a good idea to implement
the solution a little bit at a time, compiling and running it frequently as you progress. Try im-
plementing the solution using the following smaller steps, and the tests shown for each.
1. Start by getting * to work. In %
just read a single value and output it to the
Terminal. Tests:
• Check that a number can be read correctly.
• Try entering text, and check the error message is shown and that you can enter a
number the next time.
• Try entering multiple text values on a single line.
• Try entering multiple text values, one after the other.
2. Implement ( . Include an array in %
, and have its values read in by
( . Print the values back to the Terminal so that you can check this code is
working. Tests:
• Enter each of the values and check they are printed out correctly.
• Try entering text, this should be handled by * but check it is working
correctly with ( .
3. Implement the + Function. Tests:
• Test that it works with some basic values.
• Try all negative values.
• Try a mix of positive and negative values.
4. Implement the %
Function. Same tests as +.
5. Implement the .
Function. Same tests as +.
6. Finish by implementing the % Function. Same tests as +.
By building the code a little at a time, and running tests as you go, you will have less code to
search when you do find an issue. This makes it easier to fix those little errors that are likely
to slip into the code from time to time.
When this iterative process is complete you should have a solution for the Statistics Calculator.
You should be able to easily change this so that it can read in ten, a hundred, or even a
thousand values from the user. This is something that would not have been possible without
using arrays.
Note
• Get your code running as soon as you can.
• Build a little and test a little as you go.
• When you find a bug start looking for it in the code you just added (or changed).
• You can perform this as a design, implement, compile, test cycle. This enables
you to build the program a small piece at a time. Before you start this it is likely to ♠
be a good idea to have at least a sketched out plan for the design.
• As you develop your design skills you will be able to create larger designs before you
code. While you are learning to program it is ok to design and code at the same time
as this lets you to quickly test if your design will work.
435
CHAPTER 6. MANAGING MULTIPLE VALUES
Section 6.2 of this Chapter introduced the Statistics Calculator. A partial implementation of
this program is shown in Listing 6.13, with the logic in the and
functions still to
be implemented. This program reads a number of values from the user into an array, and then
calculates and outputs the sum, mean, variance, and maximum value from this data.
,7+!2
436
6.3. MANAGING MULTIPLE VALUES IN C
*
3 ,7+!2 5
+
4
,7+!2
%
4
,7+!2
.
4
,7+!2
%
4
,7+!2
Listing 6.13: C code for the Statistics Calculator
Note
•
is included to give access to the various functions needed to manipulate
string values. See the comments associated with Listing 6.11.
• is included to give access to the function that will be needed in the im-
plementation of the
function.
• Arrays in C are always passed by reference. ♠
• C does not keep track of the size of an array, the parameter in each function
call carries this data along with the array.
• The , +!2 constant stores the number of values that will be stored in the array.
This can easily be changed to allow the program to read a different number of values.
437
CHAPTER 6. MANAGING MULTIPLE VALUES
C allows you to declare variables that are arrays. This is done using the 3 5 to denote the
number of elements in the array (n). Indexes will then be 0 to n-1.
expr list
constant expression
{ expression list }
*
Figure 6.15: C++ Syntax for Array Variable and Type Declarations
C++
3
5
7 3
5
35
♢
35 4
35
35 4
35
Listing 6.14: C code demonstrating array declaration
Note
• This is the C syntax to declare a Array.
• Arrays in C do not remember their length, you must keep track of this yourself.
• You can initialise an array when it is declared using a list of values in braces ({. . . }). ♠
This can only be done to initialise arrays, and is not valid elsewhere.
• The size of the array must be able to be determined at compile time.
438
6.3. MANAGING MULTIPLE VALUES IN C
In C you cannot use simple assignment to copy all of the elements of an array into another
array. Instead you can use the (memory copy) function to perform this task for you. It
copies a chunk of memory from one location to another.
Function Prototype
Returns
Destination is returned, can be ignored.
Parameter Description
The location where the data is copied to.
The function needs to be told the number of bytes to copy. The operator can be
used to get this information for a type or variable. The details of this operator are shown in
Figure 6.16.
*
Figure 6.16: C++ Syntax for The operator lets you get the size, in bytes, of a type or variable.
C++
35
7 35
7 35 ♢
Listing 6.15: C code demonstrating array copying
Note
• The type is a whole number used to store the size of types.
• To get the size of a variable or type using the operator.
• You can think of the operator as being a function that returns the size of a ♠
type or variable.
• The expression in must be a variable or type name.
439
CHAPTER 6. MANAGING MULTIPLE VALUES
The For Loop in C can do much more than just counting, but that is its primary purpose. You
can use this to implement the logic to process each element of an array.
The for loop itself is controlled by three aspects. The first is an initialiser, it sets the first value
for the control variable (usually if you are using it to index an array). The second part is the
condition, the body will run while this is true just like a C While Loop. The third part is a post
loop increment, you use this to move the index to the next value.
The standard for loop is: . This can be read as ‘for starts
at 0, while is less than , do the following then increment ’. If is three then this
counts 0, 1, 2. Repeating the body of the loop three times.
control expression
C++
*
7 /
7
Listing 6.16: Code illustrating the for loop in C
Note
• This is the C syntax for implementing a For Loop.
• The initialiser of the for loop is used to set the initial values before the loop body is
first executed.
• The control is a condition, the loop executes while a this is true. ♠
• The increment is a post loop action, used to move to the next index.
a Inthe same way a while loop does, checking the condition to determine if the body should execute or be
skipped when the condition is checked.
440
6.3. MANAGING MULTIPLE VALUES IN C
6.3.5 C String
C was designed to build for use with the Unix operating system. When the language was
designed string manipulation was not a high priority, and therefore C does not have built in
capabilities to perform tasks like concatenating strings, and copying strings (i.e. assigning a
string a value after it has been declared).
Working with c-strings requires that you think about how the text is represented in the com-
puter. Table 6.3 shows the characters used to store the text value ‘Fred’.
As C does not keep the length of the array there needs to be a means of determining how long
the string is. The method that C choose was to place a sentinel value at the end of the string.
This marks the position in the array where the string ends. The sentinel is the
character,
the one with value the .
Characters: F r e d ∖
Bytes Valuesa :
Table 6.3: The characters and byte values for the c-string containing the text ‘Fred’
a Byte values are shown as decimal.
Space characters are distinct from the
character. Table 6.4 shows the characters involved
in storing the text ‘Fred Smith’. The space character is the value 32, and the sentinel value
only appears at the end of the c-string. To store ‘Fred Smith’ you need an array that can store
at least 11 characters. Ten for the characters in the name, and one for the sentinel.
Characters: F r e d S m i t h ∖
*
Bytes Valuesa :
Table 6.4: Characters for ‘Fred Smith’, the space has the character value 32.
a Byte values are shown as decimal.
It is possible for an array to have more characters that are needed. Table 6.5 shows an array
with 11 characters that is storing the c-string ‘Fred’. The
character at index 4 (the 5𝑡ℎ
character) ends the c-string and the remainder of the data in the array will be ignored by the
c-string functions.
Characters: F r e d ∖ S m i t h ∖
Bytes Valuesa :
Table 6.5: This would only print ‘Fred’, as the 0 character indicates the end of the c-string
a Byte values are shown as decimal.
The code in Listing 6.17 shows some examples of the main operations you may want to perform
on strings. This includes the following actions:
• Initialisation: Creating and initialising a string.
• Input: Reading words, and lines, from the Terminal.
• Comparison: Checking if two strings are equal. Notice that you also need to check the
value.
Other common string operations are found in Listing 6.11. These included:
• Copy: Assigning one string to another, as you cannot use the assignment statement to
achieve this in C.
• Concatenate: Adding one string to the end of another.
441
CHAPTER 6. MANAGING MULTIPLE VALUES
C++
7 /
3
5
3 5
Listing 6.17: Code illustrating working with Strings in C
*
Note
• In C a String is an array of characters. There is little built in support beyond this in
the C language itself. The Standard C libraries include functions that can be used
to work with String data, in
.
• Remember to ask for enough space to store the text and the sentinel value when
declaring a c-string. If you want to store 4 characters then you need to ask for an
array with space for 5, the 4 characters + and 1 sentinel value.
♠
• The c-string functions will look for the null character. If the null character is missing
from the end of the c-string then these functions will not work as you want. The
problem is that they may appear to be working, though in reality they are interacting
with memory that is not associated with the c-string you are working on.
• Take care when working with c-strings! Many security issues in software relate
to incorrect handling of c-strings.
442
6.3. MANAGING MULTIPLE VALUES IN C
The header also provides version of
and
that are used to write values
to, and read values from strings. The
function writes data into a
string,
whereas the
function reads data out of a source
. Table 6.6 shows the details for
the
function, Table 6.7 shows the details for
.
Function Prototype
Returns
The number of characters written to the
by
.
Parameter Description
The string to write the output into. Warning: You are
responsible for ensuring there is enough space.
*
Table 6.6: Parameters that must be passed to
Function Prototype
Returns
The number of values read by
.
Parameter Description
The string from which the input is read.
The variables into which the values will be read. There
must be at least as many variables as format tags in the
format specifier.
Note
• These functions are useful for converting data to and from string values.
• You can use
to convert numeric values and store them in a string. Though
care must be taken to ensure that there is sufficient space for these values in the
♠
destination string.
•
can be used to read values out of a string. For example, you could read a
numeric value out of a string value entered by the user.
443
CHAPTER 6. MANAGING MULTIPLE VALUES
The Statistics Calculator requires some string manipulation to generate the prompt that will
be shown to the user. The prompt is created from the text ‘
’, the value of , and
the text ‘ ’. The four function calls needed to achieve this are shown in Figure 6.18.
prompt: prompt:
Enter value ☐ 2;0J E nter value ☐ 2;0J
sprintf(buffer, "%d", (i + 1) % 100);
buffer: buffer:
#dZ 1 ☐ Z
prompt: prompt:
Enter value ☐ 2;0J Enter value 1 ;0J
☐
prompt: prompt:
Enter value 1 ;0J
☐ Enter value 1: ☐ J
strncat(prompt, ": ", 2);
buffer: buffer:
1 ☐ Z 1 ☐ Z
Figure 6.18: Example usage of c-string functions from the Statistics Calculator
Note
• The steps shown in Figure 6.18 perform the following actions:
1. The first instruction uses
to copy the characters in ‘
’ into the
. The
character must also be copied so that
knows where
the string currently ends.
2. Step 2 uses
to print the decimal value of into the .
This uses so that only two charactersa and the terminal are ever written
into the . This assumes that the value of is 0, so is .
3. Next
is used to concatenate and . This copies the text in
to the end of , and makes sure that there is a
character at the
end. So the
in this case indicate the maximum number of actual characters ♠
to add to the destination, as the
is effectively moved in this function.
4. The operation is completed by concatenating the final ‘ ’ to the end of the
string.
• Notice that there is one additional character left in this at the end, this gives
space for two digit values, e.g. ‘
’.
a is the remainder of the value i incremented by one after dividing by 100. This ensures that
it is always between 0 and 99. For example, when is 106, is 107, and is 7, the remainder of
dividing 107 by 100.
444
6.3. MANAGING MULTIPLE VALUES IN C
In C you can only use Pass by Reference to pass an array to a Function or Procedure. There
are two ways of passing arrays by reference in C: one uses the bracket notation (
3
5), the other an asterisks notation (
). The asterisks notation is more general pass
by reference, and will be covered in a later chapter in more details. The brackets notation
accomplishes the same task, and indicates that the passed data will be an array.3
The optional
operator allows you to indicate that the passed in value will not be changed
in the Function or Procedure. This is important with strings, as if you want to pass a string
literal to a parameter it must be a
, as the literal cannot be changed.
parameter list
parameter declaration
3 5
*
parameter name identifier
Note
• This syntax shows you how to code Pass by Reference into your Functions and Pro-
cedures in C.
• See Listing 6.18 for examples of the different ways of declaring pass by reference
parameters in C.
• Notice that in the call you do not need to get the address of arrays, as you would do
♠
with other types that are passed by reference. This is because C does this for you in
the background. Remember arrays are always passed by reference in C.
• When using the 3 5 syntax you do not specify the size of the array. This allows arrays
of varying size to be passed into the Function or Procedure. The parameter is
then used by convention to carry across the size of the array.
445
CHAPTER 6. MANAGING MULTIPLE VALUES
C++
3 5 3 5
♢
7 35
7 35
Listing 6.18: Code illustrating array passing in C
446
6.4. MANAGING MULTIPLE VALUES IN PASCAL
Section 6.2 of this Chapter introduced the Statistics Calculator. A partial implementation of
this program is shown in Listing 6.19, with the logic in the and
functions still to
be implemented. This program reads a number of values from the user into an array, and then
calculates and outputs the sum, mean, variance, and maximum value from this data.
,7+!2
( *
447
CHAPTER 6. MANAGING MULTIPLE VALUES
%
Listing 6.19: Pascal code for the Statistics Calculator
Note
• +- is used to give access to the ,+, function. This tries to convert a
string to a double, and returns a boolean to indicate if it succeeded.
• The arrays in this program are passed by reference using const (for in only) or var
(for in and out). ♠
• The $ function gives you the first index of the array, gives you
the last index of the array, and $
tells you the number of elements in the
array.
448
6.4. MANAGING MULTIPLE VALUES IN PASCAL
expression
array spec.
3 ordinal type 5
Figure 6.20: Pascal Syntax for Array Variable and Parameter Declarations
Pascal
,
( *
%
3
5 !
3
5 !
!
35
♡
/$
' 3' '5 ' 35
/$
' 3' '5 ' 35
%
Listing 6.20: Pascal code demonstrating array declaration
Note
• This is the Pascal syntax to declare an Array.
• You can initialise an array when it is declared using a list of values in parenthesis
({. . . }). This can only be done to initialise arrays, and is not valid elsewhere. ♠
• You can use an assignment statement to copy the contents from one array over
another of the same size.
449
CHAPTER 6. MANAGING MULTIPLE VALUES
The For Loop in Pascal can be used to implement the logic to process each element of an array.
With the for loop you specify a control variable, and the range of values it will loop over. When
the loop is started the control variable is assigned the initial value, at the end of each loop
this value is incremented (for ) or decremented (for
) until it has processed all values
in the indicated range.
statement
Pascal
,
!
/ ''
/$
(
' / '
(
$
(
' '
Listing 6.21: Code illustrating the for loop in Pascal
Note
• This is the Pascal syntax for implementing a For Loop.
• The first expression is the initial value given to the variable.
• If you use the variable’s value is increased by one at the end of each loop, ending
♠
the loop when the variable’s value is larger than the second expression.
• Alternatively
decreased the variable’s value by one at the end of each loop,
ending when the variable’s value is less than the second expression.
450
6.4. MANAGING MULTIPLE VALUES IN PASCAL
Pascal includes a number of functions to help you work with arrays. These allow you to
determine the length of the array, and its range of indexes. These functions are typically used
in conjuncture with the for loop.
Function Prototypes
Returns
!
The number of elements in the array.
Parameter Description
The array you want to get the length of.
Returns
!
The lowest index in the array.
Parameter Description
The array you want to get the lowest index of.
( *
Returns
!
The last index in the array.
Parameter Description
The array you want to get the last index of.
Table 6.8: Parameters that must be passed to $ , , and $
Pascal
%
!
$ 3
5 !
3
5 !
/$
'$ ' $
$ '
'
/$
'!
' $ $ ' ' $
/$
' $ $ $ '
%
451
CHAPTER 6. MANAGING MULTIPLE VALUES
Pascal allows arrays to be passed as parameters to functions and procedures. Like other
parameters these can be passed by value or by reference.
Note
• This syntax shows you how to code Pass by Reference into your functions and pro-
cedures in Pascal.
• See Listing 6.22 for example code. ♠
• When declaring array parameters you do not specify the size, this allows the param-
eter to accept arrays of any size.
( *
452
6.4. MANAGING MULTIPLE VALUES IN PASCAL
Pascal
( *
,( !
'* !
/$
'
'
35 35
♡
3 5 3 5
%
3
5 !
3 5 !
,( !
.
,( !
*
%
Listing 6.22: Code illustrating array passing in Pascal
453
CHAPTER 6. MANAGING MULTIPLE VALUES
Pascal has built in support for strings. Behind the scenes Pascal uses an array of characters
to store the text for each string. The first element of this array stores an integer that indicates
the size of the string, and this is followed by the text characters.
Characters: F r e d
Bytes Valuesa :
Table 6.9: The characters and byte values for the string containing the text ‘Fred’ in Pascal
a Byte values are shown as decimal.
Pascal
,+
%
,
+
+
35
, ' / '
* $
/$
'1
'
♡
/$
'
'
* $
/$
'/ '
%
Listing 6.23: Code illustrating working with strings in Pascal
Note
• You can access individual characters in a string using array notation, the first text
character is at index 1. ♠
• Pascal strings can be concatenated used , for example ‘Hello’ + ‘ World’.
454
6.5. UNDERSTANDING ARRAYS
Arrays offer a means of storing and working with a list of values in your code. Each array
has a number of elements, each of which has a value, and can be accessed using an index.
Together with the For Loop, arrays provide a means of managing multiple values in your code.
The following illustrations show how these work in the computer, and should help you better
understand how arrays can be used within your code.
Section 6.2.1 Designing Statistics Calculator outlined the pseudocode and flowcharts for a
small statistics programs. This included a number of functions and procedures that helped
divide the program’s code into smaller units of work. One of these procedures was (
, discussed in Section 6.2.3 Populating the Array. This procedure is responsible for read-
ing values from the user and using these to populate the program’s array, and the flowchart
for this logic is shown in Figure 6.23.
Populate
Array
Build prompt
'Enter Value i:'
End
Figure 6.23: Flowchart showing the process for ( , from Figure 6.13
The following illustrations will show this code running to populate an array that contains
three values. This will show how the array is passed by reference, and how the for loop works
together with the array to populate all elements.
455
CHAPTER 6. MANAGING MULTIPLE VALUES
All local variables are allocated space on the Stack when the function or procedure they are
declared in is called. In this example the %
procedure is executed and space is allocated for
its variable. This variable is an Array that is used to store three values. When
%
is loaded onto the Stack there is space allocated for three values associated with
the variable.
Figure 6.24: When the program starts % allocates space for its local variables, including the array
Note
• In Figure 6.24 the indicated areas show the following:
1. The program starts and %
is loaded onto the stack, allocating space for its
local variables.
2. The array is allocated space to store its values. ♠
• Notice that the three values in the array are allocated next to each other.
• The indexes can be used to access the array’s elements. The index value determines
the number of elements that must be skipped to find where the value is stored.
456
6.5. UNDERSTANDING ARRAYS
( is called as the first step in %
. This is passed the variable (pass by
reference), rather than being passed the values from within that variable. This gives the
parameter access to the memory where is stored.
prompt is a string,
3 an array of characters
data gets the address of
2 my_data, as it is passed
by reference.
Figure 6.25: Populate array is called, and a reference to the array is pass to its parameter
Note
• In Figure 6.25 the indicated areas show the following:
1. When ( is called it is loaded onto the Stack. Its parameter
receives the address of from %
. In C the value 3 would also be passed
to the parameter, as C does not keep track of the length of the array for
you. At the same time space for ( ’s local variables and
are allocated on the Stack.
2. Notice that in ( the parameter only stores the address of the
array, as it is passed by reference. This saves time and space, and is needed in ♠
this case as the procedure wants to store data into the variable passed to this
parameter.
3. The local variable is also an array. It is allocated spaces on the stack as
is done for all local variables.
• Arrays are allocated a contiguous area of memory to store its elements.
• A String is an array of characters.
457
CHAPTER 6. MANAGING MULTIPLE VALUES
Step 1 of ( initialises the for loop’s control variable ( in this case). This variable
keeps track of the times the loop body has executed, and can be used to get the current value
from the array.
Figure 6.26: Step 1 of ( is called, and the for loop sets i to the lowest index of the
array
Note
• In Figure 6.26 the indicated areas show the following:
1. Step 1 of ( is a for loop. The first action of the for loop is to
initialise the value of to the lowest index value of the array. The lowest
index is 0, so is assigned the value 0.
2. Next the loop checks its condition, it is loop from 0 to 2, and has not passed 2
so the body of the loop will be executed. This will be checked again when the ♠
for loop ends.
• The first action of a for loop is to initialise the value of the control variable.
• When processing each element of an array the for loop should initialise the control
variable to 0, the first index of the array.
458
6.5. UNDERSTANDING ARRAYS
The user needs to be told what to enter. The is a string that will contain this message
so that it can be passed to * . The value for the prompt will use the loop’s control
variable (the counter) so that the user known which value they are up to.
Figure 6.27: Step 2 builds the prompt which will be shown to the user
Note
• In Figure 6.27 the indicated areas show the following:
1. Step 2 of ( builds the prompt by concatenating ‘
. ’ with
and ‘ ’.
2. To achieve this must be converted from an Integer to a String.
3. The result is stored in the variable.
♠
• This action will be performed each time the loop executes. In this case the value
stored in will be ‘
’.
• The small square shown at the end of the represents the overhead. In C this
is the sentinel value, in Pascal it is the lengtha of the array.
a Pascal actually stores the length at the start of the string, but the idea is the same.
459
CHAPTER 6. MANAGING MULTIPLE VALUES
Step 3 reads a value from the user and stores it in the array at index 0
The next step calls the * function. This is responsible for reading a value from the
user, and returning it to the caller. The value returned is then stored in an element of the
array. The variable is read to determine the position where this value should be stored. This
means that you can think of as referring to the current element of the array.
Figure 6.28: Step 3 reads a value from the user and stores it in 35
Note
• In Figure 6.28 the indicated areas show the following:
1. Step 3 of ( calls * , passing across the prompt to be
shown to the user.
2. Within * the value is read from the Terminal. This includes some
validation to make sure that the value entered is a number.
3. To determine where the value is stored the computer needs to evaluate the ex- ♠
pression used to index the array. In this case that is the value of the variable.
4. The reference is followed, and elements skipped, to find the location where
the data should be stored.
• Notice that this has stored the value in , as is passed by reference.
460
6.5. UNDERSTANDING ARRAYS
At the end of the loop body the for loop performs two actions. It has finished the first pass
through the loop, so its control variable (the counter) needs to be incremented to 1. Then it
needs to jump back to check its condition. This will determine if the loop’s body is executed
again or skipped. In this case is still in the defined range so the loop’s body is run again.
The loop checks its condition to This is the end of the loop body, so
see if it is still in range (0 .. 2), i is incremented, and
and the loop body is repeated control jumps back to step 1
2 1
Figure 6.29: At the end of the loop body i is incremented and control jumps back to check the loop’s
condition
Note
• In Figure 6.29 the indicated areas show the following:
1. The end of the loop body indicates that two things needs to occur. Firstly the
value of needs to be incremented, and then control needs to jump back to
check the condition of the loop (step 1). ♠
2. The loop’s condition checks if is still in range ( is in the range
, coded as
in C). As it is still in range the loop’s body will execute again.
461
CHAPTER 6. MANAGING MULTIPLE VALUES
Back at step 2 again, the prompt needs to be recreated. This time its message will be ‘
’. The process to create this is the same, with the value of being converted to
a String, and the three parts concatenated together and stored in . This overrides the
details in the existing array, reusing the same memory to store these values.
Note
• In Figure 6.30 the indicated areas show the following:
1. Step 2 of ( builds the prompt by concatenating ‘
. ’ with
and ‘ ’.
2. To achieve this must be converted from an Integer to a String.
3. The result is stored in the variable.
♠
• Notice that this is using the same location to store its data.
• The small square shown at the end of the represents the overhead. In C this
is the sentinel value, in Pascal it is the lengtha of the array.
a Pascal actually stores the length at the start of the string, but the idea is the same.
462
6.5. UNDERSTANDING ARRAYS
Step 3 uses * again to get the value to store in the second element of the array. To
find where this should be stored the computer calculates the value of the index, reading this
from the variable. The value returned from * is then stored in the array referred
to by , at index .
Note
• In Figure 6.31 the indicated areas show the following:
1. Step 3 of ( calls * , passing across the prompt to be
shown to the user.
2. Within * the value is read from the Terminal. This includes some
validation to make sure that the value entered is a number. ♠
3. The value of the index is now , as read from variable .
4. The reference is followed, and element is skipped, to find the location
where the data should be stored.
463
CHAPTER 6. MANAGING MULTIPLE VALUES
is incremented again, and control returns to Step 1 to determine if loop runs again
The end of the for loop’s body has been reached again, so it performs two actions: it increments
its control variable ( in this case) and jumps back to check its condition (step 1). The condition
then determines if the loop’s body is to be executed again or skipped. In this case is still in
the defined range so the loop’s body is run a third time.
The loop checks its condition to This is the end of the loop body, so
see if it is still in range (0 .. 2), i is incremented to 2, and
and the loop body is repeated control jumps back to step 1
2 1
Figure 6.32: At the end of the loop body i is incremented and control jumps back to check the loop’s
condition
Note
• In Figure 6.32 the indicated areas show the following:
1. The end of the loop body indicates that two things needs to occur: the value of
is incremented, and control jump back to check the condition of the loop.
2. The loop’s condition checks if is still in range ( is in the range
, coded as ♠
in C). As it is still in range the loop’s body is execute again.
• These same actions always occur at the end of the for loop. It increments its control
variable, and jumps back to check its condition.
C++
The C for loop can be used for more than just counting. At the end of the loop the
♢
instructions from the C For Loop’s increment occur, typically something like .
464
6.5. UNDERSTANDING ARRAYS
Back at step 2 for the third time. This step recreates the prompt, this time with the message
‘
’. The process to create this is the same as before, with the value of
being converted to a String, and the three parts concatenated together and stored in .
Remember that this overrides the data currently in the array.
Figure 6.33: Step 2 builds the prompt which will be shown to the user
Note
• In Figure 6.33 the indicated areas show the following:
1. Step 2 of ( builds the prompt by concatenating ‘
. ’ with
and ‘ ’. ♠
2. To achieve this must be converted from an Integer to a String.
3. The result is stored in the variable.
465
CHAPTER 6. MANAGING MULTIPLE VALUES
Once again, step 3 uses * get the value to store in the array. In this case indicates
that this should be stored in the element at index 2 (skipping 2 elements, so storing the value
in the third).
Note
• In Figure 6.34 the indicated areas show the following:
1. Step 3 of ( calls * again.
2. Within * the value is read from the Terminal.
3. The value of the index is now
, as read from variable .
4. The reference is followed, and
elements are skipped to find the location
where the data should be stored. ♠
• Notice how over these three loops has been used to determine which element is the
current element. The loop’s processing is the same, but changing means that this
action is applied to each element in the array one at a time.
• The loop’s body determines the action to apply to the 𝑖𝑡ℎ element of the array.
• The for loop then updates so that the body is applied to each element of the array.
466
6.5. UNDERSTANDING ARRAYS
is incremented again, and control jumps back to check the condition a fourth time
The end of the for loop’s body has been reached again, so it performs two actions: it increments
its control variable ( in this case) and jumps back to check its condition (step 1). This time
the value of is outside the range of the indexes for (
, it is no longer less than 3).
This means that the loop’s body should not be run again, and control will jump past the body
to the next step. As there are no more steps in ( it will end.
The loop checks its condition to This is the end of the loop body, so
see if it is still in range (0 .. 2), i is incremented to 3, and
as it is not the loop's body is skipped control jumps back to step 1
2 1
Figure 6.35: At the end of the loop body i is incremented and control jumps back to check the loop’s
condition
Note
• In Figure 6.35 the indicated areas show the following:
1. The end of the loop body causes the value of to be incremented, and control
jump back to check the condition of the loop.
2. The loop’s condition checks if is still in range ( is in the range
, coded as
in C).
3. is not in the range
, so the loop body is skipped. As there are no more ♠
steps in this procedure it ends.
• The condition in the for loop is responsible for determining if the loop runs again.
This time the condition indicates that the loop is not to be run again, so control will
jump past the end of the loop.
• The for loop works like a while loop, with additional logic to keep a counter.
467
CHAPTER 6. MANAGING MULTIPLE VALUES
When ( ends its space on the stack is released so that it can be used again, and
control returns to %
. ( was responsible for reading values from the user and
storing these in the array passed to it, and if you look at Figure 6.36 you can see that this has
been achieved.
The instructions in ( commanded the computer to read a value from the user
and store it in the current element (the 𝑖𝑡ℎ element) of the array. These actions were then
repeated by the For Loop for each index of the array. Together the for loop and its body allow
you to define actions that must be performed on all elements in an array.
Figure 6.36: Control returns to % , and its array has been populated
Note
• In Figure 6.36 the indicated areas show the following:
1. The last step in ( has been completed, so it ends and control re-
turns to %
.
2. The values in have been updated. Passing this array by reference to
( allowed it to make changes to this array’s values. ♠
• Notice that the data associated with the ( procedure has been released,
including the data used for the array.
• ( is responsible for filling the array passed to it with values from the
user, and that is what it has done.
468
6.5. UNDERSTANDING ARRAYS
6.5.2 Understanding +
Figure 6.37 shows the flowchart of the + function from the Statistics Calculator program.
This algorithm was developed in the Section 6.2.2, and its Pseudocode is shown in Listing 6.1.
The + function is responsible for calculating the sum of all of the values in the array passed
to it. This is achieved by having a variable that is initialised to 0, and then has the value
of each element from the array added to it.
Sum
End
The following code will show how this function is executed on an array with three values in
it. This will continue the execution from Section 6.5.1 Understanding ( , though
the same process would occur for any array values.
Note
The most important thing to pay attention to in this illustration is the interactions between
the For Loop and the Array. Make sure you can see how this combination allows you to
♠
specify the actions to be performed on an element (in the loop’s body), and then to have
this run for each element of the array (controlled by the loop condition).
469
CHAPTER 6. MANAGING MULTIPLE VALUES
When + is called it is passed the array to read its values from. This is passed in the same
way as was done in ( . The difference here is that this is passed using a
reference, to indicate that + is not allowed to change the data in the array. This means that
+ will not compile if you update values in this array, and provide a guarantee to the caller
that their data will not change when given to the + function.
Sum is called,
data is passed the address of my_data
(in C size is passed 3)
and space is allocated for i, and total
Function: Sum
3 ----------------------------
Returns: Double - The sum of the numbers from the data array
Parameters:
Sum 1: data (by const ref, array of Double) - values to sum
2: size (Integer) - the number of elements in data (C only)
data[]: bfff1 Local Variables:
size: 3 *: i (Integer) - index of the current element in the array
*: total (Double) - running total
i: 5092 Steps:
total: 829.092 1: total is assigned 0
2: For i, starts at 0 and loops to the highest index of data
result: 92 3: total is assigned total + data[i]
Instruction: Step 1 4: Return the result, total
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 ) 2
3: ...
Figure 6.38: + is called, and it is passed the array to get its values from
Note
• In Figure 6.38 the indicated areas show the following:
1. Step 1 of %
has populated the array with values.
2. Step 2 calls the + function, passing in the array.
3. When sum starts it is allocated space on the heap. Its parameter is passed
the address of . In C the parameter will be passed the value 3, this
isn’t needed in Pascal as the language takes care of these details for you. Space ♠
is also allocated for the local variables and .
• Passing by reference means that sum gets a reference that points to the start
of the array.
• + is responsible for calculating the sum value of the values in the array.
470
6.5. UNDERSTANDING ARRAYS
is initialised to 0
The first action in + is to set the value of to 0. will be used to store the running
total of the array, and it must start at 0. Remember that the space on the stack was used
before, and therefore these variables get seemingly random values initially. It is important to
remember to always initialise the variables you are using.
Function: Sum
----------------------------
Returns: Double - The sum of the numbers from the data array
Parameters:
Sum 1: data (by const ref, array of Double) - values to sum
2: size (Integer) - the number of elements in data (C only)
data[]: bfff1 Local Variables:
size: 3 *: i (Integer) - index of the current element in the array
*: total (Double) - running total
i: 5092 Steps:
total: 0 1: total is assigned 0
2: For i, starts at 0 and loops to the highest index of data
result: 92 3: total is assigned total + data[i]
Instruction: Step 1 4: Return the result, total
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
Note
• In Figure 6.39 the indicated areas show the following:
1. The variable is assigned the value 0.
• Local variables do not get a default value when the Function or Procedure starts. You ♠
need to make sure you initialise these to appropriate values before you use them.
• will keep a running total of the elements in the array, it must start at the value
0.
471
CHAPTER 6. MANAGING MULTIPLE VALUES
Step 2 of + starts the for loop that will iterate over the elements of the array. The for
loop’s control variable, , is set to the first index of the array and the condition checks if the
loop’s body should run. As is in the range
, it is less than 3, control will jump into the
loop’s body making step 3 the next instruction.
Function: Sum
1 ----------------------------
Returns: Double - The sum of the numbers from the data array
Parameters:
Sum 1: data (by const ref, array of Double) - values to sum
2: size (Integer) - the number of elements in data (C only)
data[]: bfff1 Local Variables:
size: 3 *: i (Integer) - index of the current element in the array
*: total (Double) - running total
i: 0 Steps:
total: 0 1: total is assigned 0
2: For i, starts at 0 and loops to the highest index of data
result: 92 3: total is assigned total + data[i]
Instruction: Step 2 4: Return the result, total
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
Figure 6.40: is initialised by the for loop, and control jumps to the loop’s body
Note
• In Figure 6.40 the indicated areas show the following:
1. The for loop initialises its control variable , assigning it the value 0.
2. The condition of the loop is checked to see if the body should execute. As is
still in the range
, it is less than 3, the loop’s body will execute. ♠
• The first action of a for loop is always to initialise its control variable. After this it
checks if the body of the loop should run.
472
6.5. UNDERSTANDING ARRAYS
The body of the for loop reads the current value from the array, 35. As is currently
0 this reads the first element of the array. This reads the value 10.0, which is added to the
current , 0. The resulting value is then stored back into the variable, giving it the
value 10.0, calculated from the expression 35, which is .
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
Note
• In Figure 6.41 the indicated areas show the following:
1. The value of 35 must be read in this expression. At this point is 0, so
35 must be read.
2. 35 is found in the array referred to by , after skipping elements. This
reads the value of the first array element.
3. The expression evaluates a 35, giving 35, which is
♠
, with the final value being .
4. The value 10.0, calculated above, is then stored in .
• The body of the for loop provides the instructions that are run for each element of
the array.
a Remember that at this point has not been changed, so it has the value as shown in Figure 6.40.
473
CHAPTER 6. MANAGING MULTIPLE VALUES
For loop increases the value of i and runs the loop body a second time
At the end of the for loop it increments the value of its control variable, assigning the value
1, and then jumps back to check its condition. As is still in the range 0..2 the loop body will
be run again, making step 3 the next action.
The end of the for loop's body triggers i is still in the range 0..2
the increment of its control variable i, so it runs the body again
so it now has the value 1
3
Function: Sum
2 ----------------------------
Returns: Double - The sum of the numbers from the data array
Parameters:
Sum 1: data (by const ref, array of Double) - values to sum
2: size (Integer) - the number of elements in data (C only)
data[]: bfff1 Local Variables:
size: 3 *: i (Integer) - index of the current element in the array
*: total (Double) - running total
i: 1 Steps:
total: 10 1: total is assigned 0
2: For i, starts at 0 and loops to the highest index of data
result: 92 3: total is assigned total + data[i]
Instruction: Step 2 4: Return the result, total
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
1
Figure 6.42: At the end of the loop body is incremented, and control jumps back to check the condition
Note
• In Figure 6.42 the indicated areas show the following:
1. The end of the loop has been reached. The for loop increments its control vari-
able, and jumps back to check its condition.
2. In this case is the control variable, so its value is increased to 1.
3. The condition of the loop is checked to see if the body should execute. As is ♠
still in the range
(it is less than 3) the loop’s body will execute, making step
3 the next action.
• The end of each for loop always performs these steps. Increasing the value of its
control variable, and jumping back to check its condition.
C++
Remember C can do more than just counting in the for loop, though this is its main use. ♢
474
6.5. UNDERSTANDING ARRAYS
The body of the for loop reads the current value from the array, 35. Now has the
value 1 it reads the second element of the array. This reads the value -5, which is added to
the current , 10.0. The resulting value is then stored back into the variable, giving
it the value 5.0, calculated from the expression 3 5, which is
.
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
Note
• In Figure 6.43 the indicated areas show the following:
1. The value of 35 must be read in this expression. At this point is 1, so
3 5 must be read.
2. 3 5 is found in the array referred to by , after skipping element. This
reads the value of the second array element.
3. The expression evaluates a 35, giving 3 5, which is
♠
, with the final value being
.
4. The value 5.0, calculated above, is then stored in .
• Notice that this is performing the same task, just using the next element from the
array.
a As before, has not been changed at this point, so it has the value as shown in Figure 6.42.
475
CHAPTER 6. MANAGING MULTIPLE VALUES
For loop increases the value of i and runs the loop body a third time
The end of the for loop has been reached again, so it increments the value of its control variable,
assigning the value 2, and then jumps back to check its condition. As is still in the range
0..2 the loop body will run a third time, making step 3 the next action.
The end of the for loop's body triggers i is still in the range 0..2
the increment of its control variable i, so it runs the body again
so it now has the value 2
3
Function: Sum
2 ----------------------------
Returns: Double - The sum of the numbers from the data array
Parameters:
Sum 1: data (by const ref, array of Double) - values to sum
2: size (Integer) - the number of elements in data (C only)
data[]: bfff1 Local Variables:
size: 3 *: i (Integer) - index of the current element in the array
*: total (Double) - running total
i: 2 Steps:
total: 5 1: total is assigned 0
2: For i, starts at 0 and loops to the highest index of data
result: 92 3: total is assigned total + data[i]
Instruction: Step 2 4: Return the result, total
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
1
Figure 6.44: At the end of the loop body is incremented, and control jumps back to check the condition
Note
• In Figure 6.44 the indicated areas show the following:
1. The end of the loop has been reached. The for loop increments its control vari-
able, and jumps back to check its condition.
2. In this case is the control variable, so its value is increased to 2.
3. The condition of the loop is checked to see if the body should execute. As is ♠
still in the range
(it is less than 3) the loop’s body will execute, making step
3 the next action.
• The end of each for loop always performs these steps. Increasing the value of its
control variable, and jumping back to check its condition.
476
6.5. UNDERSTANDING ARRAYS
The body of the for loop reads the current value from the array, 35. Now has the
value 2 it reads the second element of the array. This reads the value 17.21, which is added to
the current , 5.0. The resulting value is then stored back into the variable, giving it
the value 22.21, calculated from the expression 3
5, which is
.
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
Note
• In Figure 6.45 the indicated areas show the following:
1. The value of 35 must be read in this expression. At this point is 2, so
3
5 must be read.
2. 3
5 is found in the array referred to by , after skipping
elements. This
reads the value of the third array element.
3. The expression evaluates a 35, giving 3
5, which is
♠
, with the final value being
.
4. The value 5.0, calculated above, is then stored in .
• Notice that this is performing the same task, just using the next element from the
array.
a As before, has not been changed at this point, so it has the value
as shown in Figure 6.44.
477
CHAPTER 6. MANAGING MULTIPLE VALUES
For loop increases the value of , and this time the loop finishes
The end of the for loop has been reached again, so it increments the value of its control variable,
assigning the value 3, and then jumps back to check its condition. This time is no longer
in the range 0..2 (it is not less than 3), so the loop body will now be skipped, making step 4
the next action.
The end of the for loop's body triggers i is now out of range
the increment of its control variable i, so the body will now be skipped
so it now has the value 3
3
Function: Sum
2 ----------------------------
Returns: Double - The sum of the numbers from the data array
Parameters:
Sum 1: data (by const ref, array of Double) - values to sum
2: size (Integer) - the number of elements in data (C only)
data[]: bfff1 Local Variables:
size: 3 *: i (Integer) - index of the current element in the array
*: total (Double) - running total
i: 3 Steps:
total: 22.21 1: total is assigned 0
2: For i, starts at 0 and loops to the highest index of data
result: 92 3: total is assigned total + data[i]
Instruction: Step 2 4: Return the result, total
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
1
Figure 6.46: At the end of the loop body is incremented, and control jumps back to check the condition
Note
• In Figure 6.46 the indicated areas show the following:
1. The end of the loop has been reached. The for loop increments its control vari-
able, and jumps back to check its condition.
2. In this case is the control variable, so its value is increased to 3.
3. The condition of the loop is checked to see if the body should execute. is no ♠
longer in the range
(it is not less than 3), so the loop’s body will be skipped,
making step 4 the next action.
• The for works just like a while loop, checking its condition each loop and skipping
the body when the condition is not met (when it is false).
478
6.5. UNDERSTANDING ARRAYS
The end of the for loop has been reached again, so it increments the value of its control variable,
assigning the value 3, and then jumps back to check its condition. This time is no longer
in the range 0..2 (it is not less than 3), so the loop body will now be skipped, making step 4
the next action.
With the value returned, the The result is returned to the expression
function ends where the function was called
3
2
Function: Sum
----------------------------
Returns: Double - The sum of the numbers from the data array
Parameters:
Sum 1: data (by const ref, array of Double) - values to sum
2: size (Integer) - the number of elements in data (C only)
data[]: bfff1 Local Variables:
size: 3 *: i (Integer) - index of the current element in the array
*: total (Double) - running total
i: 3 Steps:
total: 22.21 1: total is assigned 0
2: For i, starts at 0 and loops to the highest index of data
result: 22.21 3: total is assigned total + data[i]
Instruction: Step 2 4: Return the result, total
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
1
Note
• In Figure 6.47 the indicated areas show the following:
1. Step 4 indicates that the value in the variable should be returned to the
caller.
2. The result returned by the + function is used in the expression in %
.
3. As this is the end of the function its space on the stack is released, allowing ♠
control to return to %
.
• The for works just like a while loop, checking its condition each loop and skipping
the body when the condition is not met (when it is false).
479
CHAPTER 6. MANAGING MULTIPLE VALUES
+ returns its value to be used in step 2 of %
. This step outputs the value returned to the
Terminal. So by the end of Step 2 in %
the sum has been calculated, and written to the
Terminal.
Procedure: Main
Main ----------------------------
my_data[]: 10.0 Local Variables:
*: my_data (array containing 3 Double values) - data array
-5
Steps:
17.21 1: Call Populate Array ( my_data, 3 )
Instruction: Step 2 2: Output 'Sum is ', and Sum ( my_data, 3 )
3: ...
1
Note
• In Figure 6.48 the indicated areas show the following:
1. Back in %
, the sum is output to the Terminal. ♠
2. The value that is output is the value returned from the + function.
480
6.6. ARRAY EXAMPLES
The bubble game has ten floating bubbles for the user to ‘pop’. Each bubble is a sprite,
which gives it a location on the screen and a movement vector. When the program run the
bubbles move in random directions, reappearing at a new random location if they go off the
screen.
481
CHAPTER 6. MANAGING MULTIPLE VALUES
C++
+
-$7'-&,
$
7
7 7
482
6.6. ARRAY EXAMPLES
C++
7
35
*
*
3 -$7'-&, 5
♢
7
7 7
(
7 7
7
7 -$7'-&, $
-
7
7 -$7'-&,
7
7
7 -$7'-&,
7
77
7
7 7
Listing 6.25: Starting code for a Bubble Game in C++ (continued)
483
CHAPTER 6. MANAGING MULTIPLE VALUES
Pascal
, !
* - ,
+ !
-$7'-&,
$
$ *
$ & ' ' '
'
484
6.6. ARRAY EXAMPLES
Pascal
+
$
+ 35
* '
'
*
%
3 -$7'-&, 5 +
'
'
/
' ( '
$ *
( $
♡
-
(
-
+
*+
/
*
* *
%
Listing 6.27: Starting code for a Bubble Game in Pascal (continued)
485
CHAPTER 6. MANAGING MULTIPLE VALUES
Read over the concepts in this chapter and answer the following questions:
1. How is an array different to a standard variable?
2. How do arrays make it easier to work with multiple values?
3. Why is 0 the index of the first element in an array?
4. How many bytes in memory would an array of 10 integers require?
5. Draw a picture to show how the 10 integer values are stored in memory. Indicate how
these values relate to the array.
6. How can you access an element from an array?
7. How can you copy the contents of one array into another array?
8. Why should you pass an array to a parameter by reference, rather than by value?
9. Can you perform an action on all elements of an array?
10. How should you rethink actions that needs to be performed on all elements in an array?
11. How does the for loop work together with an array to perform an action on each element
in an array?
12. Why is a string an array? What values are stored in the elements of a string?
13. Strings in C and Pascal have a single byte overhead. What is this overhead for? Why is it
needed?
14. Can you read/write past the end of an array (i.e. reading/writing to the 11th element
when the array only contains 10 elements)? What can happen if you do this?
C++
1. In C you need to pass an additional size parameter for any arrays passed in a func-
♢
tion/procedure call. Explain why this is needed.
486
6.7. ARRAY EXERCISES
Use what you have learnt to read and understand the following code samples.
1. Read the C code in Listing 6.28, or the Pascal code in Listing 6.29, and answer the
following questions:
(a) What is returned by the function if it is passed ...
C++
Listing 6.28: What does this C function do?
Pascal
487
CHAPTER 6. MANAGING MULTIPLE VALUES
2. Read the C code in Listing 6.30, or the Pascal code in Listing 6.31, and answer the
following questions:
(a) What does the code do?
(b) What would be a good name for this function?
(c) What is returned by the function if it is passed ...
C++
Listing 6.30: What does this C function do?
Pascal
488
6.7. ARRAY EXERCISES
3. The following code is designed to find the median (middle value) of a array of numbers,
but does it work? Read the C code in Listing 6.32, or the Pascal code in Listing 6.33, and
answer the following questions:
(a) Assume that data contains the values 3
5, execute this code by hand
and show the steps involved. Explain any shortcuts you take.
(b) What value is returned when the function ends?
(c) You should have noticed that there is a bug in this program. How can it be fixed?
(d) What does this program assume about the data in the array?
(e) Can you think of a simpler solution? Explain your solution.
C++
7
7
7
7
3 7 5
3 7 5 3
7 5
Listing 6.32: A median function written using C
Pascal
489
CHAPTER 6. MANAGING MULTIPLE VALUES
4. Read the C code in Listing 6.34, or the Pascal code in Listing 6.35, and answer the
following questions:
(a) This procedure alters the array passed to it. Hand execute the procedure for the
values shown in the following table. Record your workings as well as the final answer.
(b) What does the code do?
(c) What would be a good name for this procedure?
(d) What would be good names for and ?
C++
35 3 5 ♢
3 5
Listing 6.34: What does this C function do?
Pascal
3 5
Listing 6.35: What does this Pascal function do?
490
6.7. ARRAY EXERCISES
Program Description
Name Hello User
Description Asks the user to enter their name, and then outputs ‘Hello ’ and their
name to the Terminal.
2. Create a program that reads in the user’s name and then determines if the name is a
silly name. For example, if the user enters the name ‘Fred’ the program could output,
‘Fred is an awesome name!’, but if the user enters any other name they get a message
like ‘Andrew is a silly name!’. Customise the message for your friends and tutor. See
Table 6.11.
Program Description
Name Silly Name Test
Description Asks the user to enter their name, and then outputs a message based
on the name entered.
491
CHAPTER 6. MANAGING MULTIPLE VALUES
3. Complete the implementation of the Statistics Calculator. Then add the following addi-
tional functionality:
(a) Add a Print All procedure to print all of the values stored in the array to the Terminal.
C++
7
35
. . . ♢
Pascal
(
!
. . . ♡
(b) Add a Frequency function that calculates the frequency of a value in the array.
C++
35
. . . ♢
Pascal
!
!
!
. . . ♡
C++
35
. . . ♢
Pascal
+
!
!
. . . ♡
C++
35
. . . ♢
Pascal
%
!
!
. . . ♡
492
6.7. ARRAY EXERCISES
4. Implement the Bubble Game from Section 6.6.1 Bubble Game (start). You will need to do
the following:
(a) Download the appropriate SwinGame template.
(b) Extract the template into a folder called ‘Bubbles’
(c) Find a picture of a bubble that is about 30 pixels wide and high.
(d) Place the bubble image in the * folder in your SwinGame project.
(e) Implement the code from Section 6.6.1.
(f) Run the game and you should something similar to Figure 6.50.
493
CHAPTER 6. MANAGING MULTIPLE VALUES
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. Write the code to sort the values in your statistic calculator.
2. Write a function that calculates the Mode, the most frequent value.
3. Get your bubbles to bounce off each other. Hint: have a look at SwinGame physics
Collide Circles procedure.
494
Custom Data Types
7
ou are progressing well! You have learnt to structure your spells,
guide the flow of magic, and apply it to many targets. Now it is
time to see how you can also structure the components that go into
your spells. Fet the snake and dragon scale, now turn your thoughts to their
structure. Take your wand and. . .
Chapter 6 introduced the array, allowing you to store multiple values of the same type in a
single variable. This greatly expanded the ways in which you can work with data in your code,
but there are more tools you can use to model data in your programs.
This chapter will show you how to create your own data types, allowing you to model the
entities1 related to your program. This means that your code can work with more meaningful
values, making it easier to create larger and more complicated programs.
When you have understood the material in this chapter you will be able to define your own
data types to model the entities you want to work with in your program.
Contents
7.1 Custom Data Type Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
7.1.1 Type (recap) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
7.1.2 Program (with Type Declarations) . . . . . . . . . . . . . . . . . . . . . . . . 499
7.1.3 Type Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
7.1.4 Declaring Variables (with custom types) . . . . . . . . . . . . . . . . . . . . 504
7.1.5 Assignment Statement (with Fields and Elements) . . . . . . . . . . . . . . 505
7.1.6 Expression (with custom types) . . . . . . . . . . . . . . . . . . . . . . . . . 508
7.2 Using Custom Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
7.2.1 Designing Small DB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
7.2.2 Understanding Small DB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
7.2.3 Choosing Artefacts for Small DB . . . . . . . . . . . . . . . . . . . . . . . . 513
7.2.4 Writing the Code for Small DB . . . . . . . . . . . . . . . . . . . . . . . . . 518
7.2.5 Compiling and Running Small DB . . . . . . . . . . . . . . . . . . . . . . . 519
7.3 Custom Data Types in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
7.3.1 Implementing Small DB in C . . . . . . . . . . . . . . . . . . . . . . . . . . 521
7.3.2 C Type Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
7.3.3 C Record/Structure Declaration . . . . . . . . . . . . . . . . . . . . . . . . 528
7.3.4 C Enumeration Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
7.3.5 C Union Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
1A fancy way of saying the ‘things’ associated with your program.
495
CHAPTER 7. CUSTOM DATA TYPES
496
7.1. CUSTOM DATA TYPE CONCEPTS
To this point, data has been about single values that are either numbers, text, or Boolean
values. These values can be used in Expressions and stored in Variables and Array elements.
Now as we move to creating larger and more complicated programs you need a more effective
means of modelling the data in your code. This chapter introduces concepts that you can use
to more accurately model the data and entities associated with your program.
This chapter introduces the following artefacts:
• Enumeration: a kind of type used to store one of a list of available options.
• Record: a kind of type used to store multiple fields in a single composite value.
• Union: a kind of type used to store one value of different possible types.
497
CHAPTER 7. CUSTOM DATA TYPES
This chapter is all about types, so its is important to have a good understanding of what a type
is. A type is a specification for a class of data, describing how it is stored and interpreted.
Expressions calculate
Values exist in many a value
In the computer
values are binary 10100101
sequences
A Type is a blueprint
Types give meaning Type describing how data is
La
st
chec bit is
k bit a stored and interpreted
to values
Will be used
11
store data to
th ts
about ...
...
re 3 bi
001
e
sto rst
Fi
10100101 is
Ñ - if its a Character
A Type is a specification
Figure 7.2: Type defines the size and interpretation if values in your code
Note
• A Type is a kind of , describing the format and interpretation of values.
• Types specify the following:
– The size (number of bits) needed to store values of this type.
– How the bits of the type are interpreted.
– The operations that can be performed on values of this type. ♠
• You can think of a Type as a blueprint, specifying data layout.
• The interpretation of a value depends on its Type, for example is Ñ if the
value is a Character type, but the same value would be
if it is an Integer type.
• You can create your own types...
498
7.1. CUSTOM DATA TYPE CONCEPTS
The Program is the overarching artefact, containing the code that defines the other artefacts
that we have been creating. When you want to declare your own types, you do so in your
program’s code. This makes it possible to model the data, in the same way as you model the
actions in your code.
Program Identifier
10100...
ck a
bit
Will be used
111
store data to
th s
about ...
Parameter
e bit
...
e
or 3
100
st
10100101
Fir
Instruction
Variable 1
Las
st
t
che bit is
11
ck a
bit
Will be used
Parameter 11
The
store
stodata se to
th s
Parameter
e bit
...
001
the
e
or 3
the tim
st
If the first
Instruction 2
... e
Fir
larger thanpart is
Instruction
... 1 Parameter
Las
111
st
1
The
store
sto se to
11
data
th s
the
e
or 3
the tim
100
st
larger thanpart is
Instruction
... 1
st
11
must havepart
...
Parameter
The
sto se
re bits
the
the tim
If the first
...
... e
larger thanpart is
...
the second 4 then
must havepart
...
Note
• A program is an artefact, it is the container within which you code other artefacts
such as your functions, procedures, constants, and now types.
• The types you declare in your program will be available for use within the program’s
code, and your functions and procedures. ♠
• You will be able to create Variables (including Arrays) of the types you create. They
will store the values in the format you specified. This includes Parameters and Local
Variables.
499
CHAPTER 7. CUSTOM DATA TYPES
Type declarations allow you to define your own types. Programming Languages offer a range
of different code structures you can use to build your own types.
Value contains a
Value stores one of number of fields
a list of options Type
La
st
chec bit is
k bit a
Will be used
11
store data to
e bits
about ...
...
001
e
or 3
th
st rst
Fi
111 If the first
larger thanpart is
Th
stor ese
e the bits
the tim
... e
Enum La
st
chec bit is
k bit a Record/Struct Will be used
La
st
chec bit is
k bit a
11
Will be used store data to
e bits
to about ...
...
store data
011 001
e bits
e
about ...
or 3
...
th
st rst
e
or 3
th
Fi
st rst
0 111
Fi
111
Th
stor ese
Th e the bits
stor ese
e the bits If the first
the tim
... e
the tim larger thanpart is
If the first ... e
larger thanpart is the secon 4 then
the secon 4 then d
must havepart
d
must havepart ...
...
Union / La
st
chec bit is
La
st
chec bit is
Others...
k bit a k bit a
Will be used Will be used
11 11
store data to store data to
e bits
e bits
about ... about ...
...
...
001 001
e
e
or 3
or 3
Variant Record
th
th
st rst
st rst
Fi
Fi
111If the first
larger thanpart is
Th
stor ese
e the bits
the tim
... e
111 If the first
larger thanpart is
Th
stor ese
e the bits
the tim
... e
Note
• A type declaration is the term given for declaring your own type artefact in code.
• Programming Languages offer a range of different kinds of types that you can create.
• Each kind of type declaration allows you to create a type for different kinds of values:
– Enum: An enumeration is creates a type where the value will be one of a list of
available options.
– Record or Struct: A structured record, where each value of this type is made
up of a number of fields.
♠
– Union or Variant Record: Makes it possible to create a type where the value
could be one of a number of other types.
– Languages may also offer other kinds of type you can declare.
• You use these different kind of types to design the structure for the values you will
work with in your code.
• There is no data associated with a type declaration, you are declaring a new format,
not another value.
500
7.1. CUSTOM DATA TYPE CONCEPTS
Record
11
store data to
th ts
about ...
...
re 3 bi
001
e
sto rst
Fi
111If the first
larger thanpart is
Th
stor ese
e th bits
the e tim
... e
Note
• A Record/Structure is a kind of artefact you can declare.
• You can create your own Record/Structure types, these can then be used to define
the data stored in Variables in your code.
♠
• Remember that this is declaring a new data format, it is not declaring a new data
value: for that you need to declare a Variable.
• The size of a record is based on the sum of the sizes of its fields.
501
CHAPTER 7. CUSTOM DATA TYPES
Enumeration
An Enumeration allows you to create a type where the value is one of a list of available options.
When you declare an enumeration you are listing the values that are available for data of
this type. The example in Figure 7.6 declares a type that can have the value '!&+ or
*%'. '!&+.
11
th ts
about ...
...
re 3 bi
001
e
sto rst
Fi
111If the first
larger thanpart is
Th
stor ese
e th bits
the e tim
... e
DBL_DATA
10010011 00000001 11011100
Data Kind
The first option get 0,
the second 1, the third 2,
and so on...
Conceptually In Memory
Note
• An Enumeration is a kind of artefact that you can declare.
• Using an enumeration you can declare a kind of value that must come from a list of
available options.
• When you declare the enumeration you list the values that it may have.
• This is like a list of constants, where values of this type will match one of these
constants.
• Internally the compiler will map your values to numeric values. The first option is ♠
represented by the value , the second is represented by the value , and so on.
• You can specify the values for each option in the enumeration, this can be useful if
you want to be able to combine options in a single value. In these cases you give
each option a bit unique value (first at , then
, , , , etc).
• The size of an enumeration is based on the size of the integer type used to represent
its values.
502
7.1. CUSTOM DATA TYPE CONCEPTS
Union
A Union (Variant Record in Pascal) allows you to declare a type where the values may be one
of a range of alternative types. In effect, you can declare a type where the value may be one
of a number of different types. This is useful if you want to store different types of values at a
location in your program.
A Union often works best by accompanying it with a tag value. This value then records the
kind of data currently being stored at the location in memory. A good option is to use an
Enumeration for the tag’s type, giving you a range of value, that describe the range of types
stored.
11
store data to
th ts
about ...
...
re 3 bi
001
e
Variant Record
sto rst
Fi
111If the first
larger thanpart is
Th
stor ese
e th bits
the e tim
... e
intValue 165
10010011 00000000 00000000 00000000 10100101
My Data (value) 00110010 00110000 01100011 00000000 11011100
Figure 7.7: A Union is one type that can store one of a range of other types
Note
• A Union is a kind of that you can declare.
• The Union allows you to use one location in memory to store one of a number of
types of value.
• At any one time this data can be used to store one of these values.
• It is the developers responsibility to ensure they access the right kind of value when
it is being used. ♠
• A tag value can be used to store a marker that indicates the type of data being stored
in the union.
• The size of a union is the size of its largest option. For example a union of a
(1 byte), a !
(4 bytes), and a (4 bytes) is 4 bytes, the size of the largest
kind of value it needs to store.
503
CHAPTER 7. CUSTOM DATA TYPES
The custom types allow you to specify a data format. To make use of this format you must
declare variables that use this type. The type can be used to declare Local Variables and
Parameters, allowing you to store values in this format and pass the around between your
functions and procedures.
Elements of an array
can be values of a union, allowing
Values can be records the one array to store
like a Point record with integer, double, and text data in
X and Y coordinates different elements
x=
int
tx
24
db
y=
Va r D
Us
tV
lVa r D
Us
Us
73
al ' Da
l=
e
l=
Po
e
=
e
3.
Fr
int
73 a
r
at
14
ed
at
t
'
Array
a
a
Variable
(Mouse Pos)
(Data)
Procedure
(Print Data) Da 4
er .1
ta
Us al =3
10100101
lV
db
Variable
10100101 Parameter
Variable (data)
10100101 A
Variable D AT d
n
L_ Ki
DB t a
Instruction 1 D
a
... Parameter
(kind)
Figure 7.8: Some examples of how you can use your types to declare the kind of data stored in variables
Note
• Variables declaration is the term given to the code that creates Variables.
• The Variables you create store data as described in your custom type definitions.
• In Figure 7.8 there are the following examples:
– % (: A Variable that stores (
Record data.
– : Array that stores - values which are either integer, double, or text
♠
values using a Union.
–
: Parameter that passes in an Enumeration value from the #
type.
This value can then be used by
• You can combine these types in a huge variety of ways. The best idea is to try and
model the entities related to your program.
504
7.1. CUSTOM DATA TYPE CONCEPTS
The Assignment Statement allows you to store a value in a Variable or Array. The righthand
side of the assignment is an expression that calculates the value to be stored. The lefthand side
is a variable or array element, a place into which the value can be stored. With the addition
of the custom types you can now also store values in fields of a record or union.
x=
24
y=
73
Poin
t
Variable
(Mouse)
DB t a K
Da
L_
DA ind
Expression
TA
stored in
Variable
(kind)
db
Assignment is an Expression,
l=
e
3.
Variable
(Value)
Note
• The Assignment Statement is an action, you can command the computer to store a
value in a variable, array element, record’s field, or union’s field.
• Enumeration values are stored in a single variable, so they work in the same way as
shown in Section 4.1.8 Assignment Statement.
♠
• With a record you can assign values to its fields individually, or you can assign it all
of the values from another matching record.
• A union can have its value set via its fields, or you can copy the value from another
matching union.
505
CHAPTER 7. CUSTOM DATA TYPES
Record Assignment
The assignment statement can be used to assign a value to a record’s fields, or to copy an
existing record’s values.
24
x= ...
y= 73
24
Point
Variable
(Mouse) stored in
mouse.x
x
=
y
= 24 x= 24
P o 73 y= 73
in Point
t
Variable
(other) stored in
mouse
other
52
x=
y=
Point
x=
x=
y=
y=
...
37
Point
Point
52
45
91
12
86
Array stored in
(Points)
points[2].x
x=
y=
x= 24
Poin
73
x=
x=
y=
y=
y=
24
73
Point
Point
Point
t
45
91
12
86
mouse
Array stored in
(Points)
points[2]
Figure 7.10: You can assign an individual field or the entire record in one assignment statement
Note
• The four examples from 7.10 show the following:
1. You can assign a value to a field of a record. In this case 24 is assigned to
.
2. A (
expression can be assigned to a (
variable. This copies the entire
record into the Variable.
♠
3. It doesn’t matter if the record is in an array, you can still assign a value to an
record’s fields.
4. You can also assign an entire record into an element of an array.
• If the language allows arrays to be copied then you can also copy an entire array of
records to a destination.
506
7.1. CUSTOM DATA TYPE CONCEPTS
Union Assignment
The Union is similar to a Record in that you can assign values to a union via its fields or by
copying another union value into the variable or array element. The difference with the Union
is that it has only a single value, with the different fields giving you different interpretations
of that data.
intVal =
User Data
73
...
Variable
(result) stored in 73
result.intVal
int
Va
Us l=
er 73 73
intVal =
Da
ta User Data
Variable
(other) stored in
result
other
intVal = ...
User Data
52
txtVal 'Fred'
dblVal 3.1415
User Data
User Data
=
Array
(Points)
stored in 52
points[2].x
intV
Us e
txtVal 'Fred'
dblVal =3.141
al =
User Data
User Data
73
intVal =
rD
User Data
73
=
ata
other
Array stored in
(Points)
points[2]
Figure 7.11: You can assign an individual field or the entire union in one assignment statement
Note
• The four examples from 7.11 show the following:
1. You can assign a value to the fields of a Union. This overrides any value currently
stored in the Variable.
2. It is possible to copy an entire Union value in the assignment.
3. This works in the same way with arrays, you can write a value to an Union. ♠
4. You can also copy an existing union value into an element.
• When accessing the data in a Union you are responsible for ensuring you read back
the value you stored as it does not remember the kind of value you stored in the
union.
507
CHAPTER 7. CUSTOM DATA TYPES
The types you define allow you to specify how data values can be formatted, allowing you to
declare variables that contain data in this new format. You can then read data back from your
variables in expressions.
Expression
txtVal 'Fred'
intVal = 73
dblVal = 3.14
User Data
User Data
User Data
=
x= 24
y= 73
Point
Variable Array
(mouse) (Data)
1000
0001 01001001
mouse.x data[2].intVal
Read value
DBL_DATA of a Enumeration
01
Variable
00
Data Kind
Parameter
kind
00
(kind)
00
Figure 7.12: An expression can read the value of a record’s field, a union’s field, and from an enumeration
Note
• Expression is the term given to the code that calculates values within your State-
ments.
• Within an expression you can read the value from. . .
– a field of a record.
♠
– a field of a union.
– an enumeration.
• The dot () notation is used to indicate which field you want to access from a record
or union.
508
7.1. CUSTOM DATA TYPE CONCEPTS
Record Expressions
A Record is a type that contains a number of fields. When using a record value you can use
either an individual fields from the record, or the record in its entirety.
x= 24 mouse.x
y= 73
Is an Integer, it can be used
Point anywhere an Integer is required
Variable
(Mouse)
mouse
Is a Point, it can be used
anywhere a Point is required
points[2]
x=
x=
x=
y=
y=
y=
Poin
Poin
86
52
45
12
37
t
Array
(Points) points[2].x
Is an Integer, it can be used
anywhere an Integer is required
points
Is an Array of 3 Points, it can
be used anywhere an array of
Points is required
Figure 7.13: A field of a record can be used, or the record can be used in its entirety
Note
• Figure 7.13 shows some examples of expressions on an record variable and array.
• The (
record in the illustration has an field that stores an integer value.
• You can access a field of the record from its variable using the dot notation. So
reads the value form the record stored in the variable. This value
is then an Integer, and can be used anywhere an Integer is allowed. For example,
you could have this in an equation where the value was subsequently stored in an
Integer variable or passed to an integer parameter.
♠
• You can access the entire record using just . This expression has the (
type. It can be used anywhere a Point can be used. For example, it could be stored
in another (
variable, or passed to a (
parameter.
• In an array of records, each element has the records type. In Figure 7.13 the
array is storing 3 (
values. This means the
is an expression to access
the entire array,
3
5 accesses the 3𝑟𝑑 element and therefore has a (
type,
and
3
5 accessed the value of the 3𝑟𝑑 element of the
array.
509
CHAPTER 7. CUSTOM DATA TYPES
Union Expressions
A Union has multiple fields that all give access to the same piece of memory. In effect, the
union stores only one of the values from its available fields. This allows you to create a type
that can be used to store one of a selection of available values.
Us
db
lVa r D
value.dblVal
l=
e
3. Is a Double, it can be used
14
at
value
Is a UserData value, it can be used
anywhere a UserData value is allowed
data[2]
int
tx
db
Va r D
Us
tV
lVa r D
Us
Us
l = 7 at
e
l=
e
=
e
3
r
14
ed
at
a
t
'
Array
a
data[2].intVal
a
(Data)
data
Is an Array of 3 UserData values,
it can be used anywhere an array of
UserData values is allowed
Figure 7.14: A field of a union can be used, or the union can be used in its entirety
Note
• A Union is very similar to a Record, the only difference is that the union only stores
one of the field values.
• Figure 7.14 shows an example of a union variable and array.
• The expression gives access to the union stored in the variable. This has a
- type an can be used anywhere a - value can be accepted.
• The expression . is a value, and can be used anywhere a
is allowed.
• Accessing a union value from an array is similar to accessing a record value. In Fig- ♠
ure 7.14 you can access the array in its entirety using , you can access the first
- value using 35, and you can access its text value using 35. .
• When accessing the data in a Union you are responsible for ensuring you read it
using the correct field. For example, it is possible to read the data stored in
using
. . This will not cause any errors during compiling or running, but
the value read will be the Integer interpretation of the Double value stored in the
variable.
510
7.1. CUSTOM DATA TYPE CONCEPTS
Enumeration Expression
The Enumeration is the simplest of the custom types to make use of. It defines a list of
available options for values of this type. This means that enumerations are just like standard
values.
DB t a K
kind
Da
L_
DA ind
TA
Variable
Is a DataKind value, it can be used
(kind)
anywhere a DataKind value is allowed
kinds[2]
IN t a
DB t a K
TX t a K
T_ K
Da
Da
Da
DA ind
TA
TA
TA
Array
(kinds)
kinds
Is an Array of 3 DataKind values,
it can be used anywhere an array of
DataKind values is allowed
Figure 7.15: You interact with an Enumeration just like other simple data types (Integers, and Doubles
for example)
Note
• Accessing an value of an Enumeration type is just like accessing an Integer or Double
value.
• In Figure 7.14 the
variable is storing a #
value. This value can be read
from the variable using the variable’s name (its Identifier). ♠
• The
variable is an array of #
values. The expression
is an array
of #
values and can be used anywhere the array would be accepted.
35
is a #
value and can be used anywhere a #
value can be used.
511
CHAPTER 7. CUSTOM DATA TYPES
Designing your own data types means that your code can work with more meaningful values.
You can design the data that is stored in the program so that it is organised in ways that will
help make the processing simpler.
Table 7.1 contains a description of the Small DB program that will be explored in this chapter.
This is a small program that will read, store, and output values entered by the user.
Program Description
Name Small DB
As before, the process to design and implement this program will follow a number of steps:
1. Understand the problem, and get some ideas on the tasks that need to be performed.
2. Choose the artefacts we will create and use
3. Design the control flow for the procedural2 artefacts
4. Map these artefacts to code
5. Compile and run the program
This program does not perform any complex functionality, so it does not require much analysis
to understand the tasks that need to be performed.
Data identified:
• Row: has a unique identifier, and a value.
• Column Value: each value in a row is either an integer, a double, or a text value.
Tasks to be performed:
• Read Row: The program needs to be able to read a row from the user.
• Print Row: After reading the value the program need to output the value to the Terminal.
512
7.2. USING CUSTOM TYPES
The process of choosing the artefacts for a program involves determining both the structure of
the data, as well as the structure of the functions and procedures. In many cases the structure
of the data is more important than the structure of the functionality, as getting the data right
will make the processing easier. Therefore, the first task is to consider how the data can be
structured.
The three main tools that you have for designing the structure of the data in your program are
records, unions, and enumerations. A record allows you to create a composite data type that
is made up of a number of fields. The union allows you to create a type that stores one kind of
data, or another. Finally the enumeration allows you to create a list of available options.
The most common of these is the record, a struct in C. This type allows you to create a single
composite value that is composed of a number of related field values. This can be used to
model the entities in your program. When designing with records you think about the things
you want to model, and the data associated with these things.
In the case of the Small DB program there appears to be one kind of record: the . The
program needs to store row values, where each row has a unique id (an integer), and a data
value. These two values together make up a row.
This data type will also work nicely with the planned functionality for the program. The code
needs to be able to read and print values. This means that this code can accept/return
values. The (
* procedure will take in a parameter, and print out its details to
the ,
. The * * function can read values from the user and return a value to
the caller.
The union3 is going to be less common than records, but they can offer some useful flexibility
when designing your code. The union gives you the ability to have a type that stores one of
a selection of types. If your program requires the ability to store different types at the one
location then a union is a useful way of modelling this.
Reading the description of the Small DB program there does appear to be the need for a union.
Each needs to be able to store either a Integer, a Double, or a text value. Using a union it
will be possible to create a type to model this. This can be called the
. type, and
will be the union of these three values.
The great thing about a union is that it stores only one value, the one that you assign to it.
This means that it takes only the size needed to store the largest kind of value. In our case the
. will need space to store an Integer (4 bytes), a Double (8 bytes), or 7 Characters
(8 bytes, 7 + 1 overhead). This will only need 8 bytes of space, as at any one time it can only
have one of these values.
The last type to look for is the enumeration. This can be used to code a list of available options.
Reading through the description of the program there is no really obvious list of options, but
on further analysis there may be.
Remember that the Union does not know which value you stored in it. So you would be able to
store a value in a Row, but then you would not know which value to read back from the union.
3 Variant record in Pascal
513
CHAPTER 7. CUSTOM DATA TYPES
This is where an enumeration can come in handy. You can create an enumeration that gives
options for each of the kinds of values that the union can store. In this case the options can
be !&, .$, $ .$, and ,0, .$, and can be called #
.
The #
enumeration allows you to declare variables that will have one of the available
options as its value. This value will need to be stored for each * in the program, so a field
needs to be added to the * type. This
field can then store a marker that indicates the
kind if value that is stored in the record.
This is a common pattern you will find for working with unions. It is called a tagged union.
The enumeration value is the tag and stores an indicator of the kind of value stored in the
union. This is the model behind the implementation of unions in Pascal, but must be manually
coded in C.
Table 7.2 shows the structures chosen for the data Small DB program. These provide the data
model that will be used by the code to implement the program’s logic. Having planned out the
structure for the data of this program, the next step will be to design its logic.
Data Details
Reading a Row
The first piece of functionality to implement can be the * * function. This function will
be responsible for reading a value from the user, and determining if that value is an integer,
double, or string and then storing it in the row with the correct tag value.
To implement this will require the ability to check if the value in a string is an integer or
a double. These two tasks can be coded into functions ! !
and ! . Other
than this the remaining code just needs to copy values into the fields of the * that will be
returned.
* * will need to accept a single parameter, & !. This will be the value assigned to the
field of the *, and will be passed in as this data will be managed elsewhere. At the end
of the function, * * will return a single * value. As this is a record, it will contain ,
, and values.
Figure 7.16 shows the flowchart for the steps in the * * function. Notice that all three
fields of the * are assigned values. The is assigned in the first statement, whereas the
514
7.2. USING CUSTOM TYPES
Read Row
Assign result.data.int
val the integer value
from line
Assign result.data.dbl
Assign result.data.txt
val the double value from
val the value from line
line
Return result
End
515
CHAPTER 7. CUSTOM DATA TYPES
and
fields are assigned values in the branches of the if statements. All of this data
is then returned when the result value is returned.
The union is being used when the field is assigned a value. When the integer branch is
taken the union is assigned a value via its
field. When the double branch is taken the
union is assigned a value via its field. When neither of these branches is taken, the
text value is assigned to the union via its field.
Finally, one of the options from the enumeration is stored in the
field of the record
alongside the union’s value. This means that the !&, .$ value is stored in the
field when
the integer branch is taken, and the $ .$ value is stored when the double branch is taken,
and the ,0, .$ value is stored when the text path is taken.
Figure 7.17 shows three examples of the kinds of values that could be the of this
function when it returns. In each case there are three field values in the row. These are
defined in the * record, and include the , the
, and the .
id: 0 id: 1
kind: INT_VAL kind: DBL_VAL
data: data:
Int Val: 165 Dbl Val: 3.1415
Row (result)
Figure 7.17: Examples of data that could be read into a * value in * *
516
7.2. USING CUSTOM TYPES
Printing a Row
Having read data into a * it is now possible to output that to the Terminal. The steps
required to do this can be coded into a (
* procedure. The required steps are shown in
the flowchart in Figure 7.18.
The (
* procedure will take a single * parameter. This parameter will contain the data
related of the row that is to be output to the Terminal. The procedure will output the value
and the values from the *, using the
value to determine which field to access from
the
. union.
The ’s can be output straight away as it is an Integer value. The actual data that needs
to be output depends on the kind of value that is stored in the *. A Case Statement can be
used to select a path based upon the value stored in the row’s
field. The four paths here
cater for the three options from the #
enumeration, plus an additional path in case
the value in , (
’s
field does not match4 one of these. This path would indicate a bug
in the software, but should be included just to be safe.
Print Row
To Print's
Kind
INT_VAL DBL_VAL TXT_VAL
Output "has integer " Output "has double " and Output "has text " and
Output "has an unknown
and the Int Val of To the Dbl Val of To Print's the Txt Val of To Print's
value"
Print's data data data
End
Figure 7.18: Flowchart of the steps needed to print a * to the Terminal
4A enumeration is stored as an Integer value, meaning it is possible to store other values in here.
517
CHAPTER 7. CUSTOM DATA TYPES
Figure 7.19 shows the structure chart for the design of the Small DB program. The function-
ality is split between the * * function and the (
* procedure, with ! !
and
! providing useful utility functions to test the data read from the user.
Main
Ro
Id
w
w
xt
Ro
Show Intro Ne
Read Row Print Row
Tru
e
g
/F
rin
e
ls
Str
St
als
Fa
ing
e
e/
u
Tr
Is Integer Is Double
Figure 7.19: Structure chart showing the overview of the Small DB program
The %
procedure will be responsible for storing the data read from the user in an Array of
* values. The logic in %
will then loop over this array once to read in a value for each
element of the array, using * * to get this value. %
with then loop over the array a
second time, this time calling (
* for each element in the array. This will allow %
to
read in, and then print out, all of the rows.
A + !
procedure has also been added to this design to house the code to show the
startup message to the user. This moves this code out of the
procedure allowing it to
focus on coordinating the tasks involved in working with the array of * values.
The flowcharts and Pseudocode shown communicate the logic that needs to be coded into the
Functions and Procedures of this Program. The following two sections, Section 7.3 Custom
Data Types in C and Section 7.4 Custom Data Types in Pascal, contain a description of the
syntax needed to code your own types in the C and Pascal programming languages. This
information can be used to write the code for the Small DB program, and others.
518
7.2. USING CUSTOM TYPES
Remember to code and run this one small piece after the other. For this you could start by
writing the (
* procedure, and pass it values that you hard code in the program. This
will allow you to experiment with storing different values in the fields of the record and union
without having to deal with the user input and testing functions. You can test this by checking
that the output matches what you expect based on the values in the *.
Once this is complete the next task would be to work on the * * function, and its helpers.
These have a bit more logic and will require that you test it more carefully. Think about the
kind of test data that you can use to check each of the paths through these functions, and
use this to check your code as you progress.
Figure 7.20 shows the program in operation.
Figure 7.20: Small DB run from the Terminal, repeated from Figure 7.1
519
7.3. CUSTOM DATA TYPES IN C
Section 7.2 of this Chapter introduced the Small DB program. A partial implementation of
this program is shown in Listing 7.1. The type definitions, and code are missing the details
needed to store and display double values. This program reads a number of rows of data from
the user (determined by the +!2 constant). Each row stores a single value, being either a
double value, an integer value, or a text value.
(
*
7 35
7
%
521
CHAPTER 7. CUSTOM DATA TYPES
7
35 ' ' 35 '4 '
7
7
&
7
7
7
7 7
*
3 5 35
3 5 '4 '
522
7.3. CUSTOM DATA TYPES IN C
*
*
,
7
7
7
3 5 3
5
-.$
7
*
364
5 34
5
!
7
*
7
7
!&,7.$
523
CHAPTER 7. CUSTOM DATA TYPES
7
7
,0,7.$
7
!&,7.$
4
7
7
*
,0,7.$
' '4
7
7
4
7 3 7+!2 5
7
524
7.3. CUSTOM DATA TYPES IN C
Listing 7.1: C code for the Small DB program
Note
• is a function from the header. This converts the input to a integer,
and updates to point to the character the conversion got to before ending. Check-
ing that this matches the end of string terminator ( '4' ) indicates that the input
matches the entire string.
• is a similar function that converts text to a double. As with , this
updates to refer to the character it got in the conversion. If this refers to the end
of the text then the data does contain a double.
• The function removes spaces from the start and the end of the input, ensuring
that numbers with leading or trailing spaces are still detected as numbers.
• The type definitions must appear before they are used, as a result they commonly
appear at the start of the code after the includes.
• gives access to the constants !&, %0 and !&, %!&, these can be used to ♠
check if the integer read is in the range of an integer value.
•
gives access to the
global variable that contains an error number when
the integer is outside of the range of a long.
• The code in * * includes code that skips any unwanted input on the current
line. This requires two
calls: the first reading in any characters other than
a newline, and the next reading in the newline. This method of skipping unwanted
data in input is safe and works across multiple platforms.
*
• A number of online resources refer to using to skip processing input between
reads. This should not be used. The function is used to ensure that output
is written to the underlying hardware. The behaviour of this function is not defined
for input streams. As a result it will not work as expected on all platforms.
525
CHAPTER 7. CUSTOM DATA TYPES
In C you can declare your own record/structure, union, and enumeration types using the
declaration. It is also possible to create an alias type declaration, in which you assign
a new name to an existing type.
struct declaration
union declaration
alias type declaration
const
3 5
constant expression
*
Note
• This syntax allows you to declare your own data types.
• The following sections contain the details of declaring different kinds of custom
types:
– Records/structures are shown in C Record/Structure Declaration.
– Enumerations are shown in C Enumeration Declaration.
– Unions are shown in C Union Declaration.
• Listing 7.2 shows how to declare alias types. An alias type give a new name to an
existing type. Included in this are examples of the following:
♠
–
is an alias for
.
–
is an alias for an array of five
values.
–
is an alias for a string of 256 characters.
–
is an alias for a variable length string.
–
is an alias for a read-only c-string.
• Notice that these new types can be used to declare variables, arrays, and parameter.
•
is an array that contains
in each element. Each element of this
array is an array of five integer values.
526
7.3. CUSTOM DATA TYPES IN C
C++
*
4
3 5
♢
7
7
3
5
7
4
Listing 7.2: Testing the alias declarations in C
527
CHAPTER 7. CUSTOM DATA TYPES
A record is a type that allows you to store multiple field values. In C this is implemented using
a . The struct defines a list of fields and their types. The field declarations are similar to
other variable declarations, with you specifying the type and then the name of the field.
struct name
3 expression 5
Note
• This is the syntax for declaring your own custom record.
• The declaration starts with , which indicates that this is a declaration for a
custom type, then indicating the declaration of a structured record.
• Next comes an option struct name. This identifier can be used to refer to the structa
but requires the keyword before it. For example, the declaration in Listing 7.3
declares a
, or a
, depending on if you use the struct name
or the typedef name.
• Following this is a list of fields between braces (i.e. {}). Each field has its own
type that may be of any type, including other structures, arrays, standard types,
enumerations, and unions. ♠
• Finally the typedef ends with the name of the type you are declaring.
• Listing 7.3 shows an example of a record in C. The
record contains an array
of fifty characters called
, and an integer called .
• Remember that the type declaration is creating a new type. After declaring the
you can now create variables of the
type.
• Additional fields could be added to the record, and these will be added to all variables
declared from this type.
a This enables you to declare a struct outside of a .
528
7.3. CUSTOM DATA TYPES IN C
C++
*
4
+
3
5
Listing 7.3: C for working with a structure
529
CHAPTER 7. CUSTOM DATA TYPES
An enumeration is a list of available options for the type. A variable of an enumeration type
can store one of these values. In C you declare the enumeration using a , and list the
available constants within the braces.
enum name
constant expression
C++
(
*
+
&*
0,*%7&*
7
7
+ ♢
+
+ 4
&*
4
0,*%7&*
*
4
-
4
Listing 7.4: C code illustrating enumeration declarations.
Note
• This is the syntax that allows you to declare an enumeration in C.
• The declaration starts with , which indicates that this is a declaration for a
custom type, and
indicating that this custom type is an enumeration.
♠
• Following this is a list of constants between braces (i.e. {}). Each constant must
have a unique name, and the by convention is all UPPERCASE.
• Finally the typedef ends with the name of the type you are declaring.
530
7.3. CUSTOM DATA TYPES IN C
union name
3 expression 5
*
Figure 7.24: C++ Syntax for Union Declarations
C++
7
35
♢
35
3 5
3
5
35
/
-
(-
4
Listing 7.5: C code demonstrating union declaration and use
531
CHAPTER 7. CUSTOM DATA TYPES
Note
• This is the syntax for declaring your own custom union.
• The declaration starts with , which indicates that this is a declaration for a
custom type, then
indicating the declaration of a union.
• Next comes an option union name. This identifier can be used to refer to the uniona
but requires the keyword
before it. For example, the declaration in Listing 7.5
declares a , or a
, depending on if you use the union name or
the typedef name.
• Following this is a list of fields between braces (i.e. {}). Each field has its own
type that may be of any type, including other structures, arrays, standard types,
enumerations, and unions. This is the same as with a C Record/Structure Decla-
ration, except that when it is stored in memory only one of these fields will have a
value.
• Finally the typedef ends with the name of the type you are declaring.
♠
• Listing 7.5 shows an example of a union in C. The union contains either an
unsigned integer called , or an array of four bytes called
.
• Remember that the type declaration is creating a new type. After declaring the
you can now create variables of the type.
• Please note that when you store a value in a union via one field, that is the field that
has a reliable value. If you access the union’s value via another field the results are
unreliable. This behaviour is demonstrated in Listing 7.5 where a value is stored in
the union via the
field, but accessed via the field. This should be
avoided in ‘real’ code as it relies upon an understanding of how the data is being laid
out in memory which can differ by platform, and can be a source of hard to locate
issues.
*
532
7.3. CUSTOM DATA TYPES IN C
In C you can declare variables from any of the types that you have declared. The type name
in the variable’s declaration can contain the names of the types that you declare using C’s
declaration. See C Type Declaration.
const
expression
Note
• This shows the syntax for declaring variables that use the types you have created.
• In C the type declaration must appear before you can use the type to declare vari-
ables.
*
• The code in Listing 7.6 demonstrates how variables can be declared using custom
defines records, unions, and enumerations.
• In C it is possible to initialise a record/structure using similar notation to that used
♠
to initialise arrays (see C Array Declaration). This uses braces (i.e. {} ) to sur-
round the expression. Within the braces you place one value for each field, in order.
These values are then used to initialise the fields of the variable. See the declaration
of
in Listing 7.6.
• Unions can also have their values initialised. This also uses the brace notation, but
only the first declared field can be initialised.
533
CHAPTER 7. CUSTOM DATA TYPES
C++
3 5
7
'(,7
'(,7
7
7
7
7
7
*
7
7
♢
7
'(,7
7
(
!
4
'(,7
!
4
(
7
4
7
7
4
7
7
Listing 7.6: C code illustrating variable declaration and use with Custom Types
534
7.4. CUSTOM DATA TYPES IN PASCAL
Section 7.2 of this Chapter introduced the Small DB program. A partial implementation of
this program is shown in Listing 7.7. The type definitions, and code are missing the details
needed to store and display double values. This program reads a number of rows of data from
the user (determined by the +!2 constant). Each row stores a single value, being either a
double value, an integer value, or a text value.
+
+-
, #
.
#
!&,7.$ $7.$ ,0,7.$
. ,
.
#
!&,7.$
. !
+
!
( *
,0,7.$ . +
35
535
CHAPTER 7. CUSTOM DATA TYPES
(
!&,7.$ /$
' !
' (
.
$7.$
,0,7.$ /$
' ' (
.
/$
'
'
( *
%
3 7+!2 5 *
.
!
+!
%
Listing 7.7: Pascal code for the Small DB program
Note
• The type definitions must appear before they are used, as a result they commonly
appear at the start of the code. ♠
• The column’s kind has been moved into the
. record.
536
7.4. CUSTOM DATA TYPES IN PASCAL
In Pascal you can declare your own record/structure, union, and enumeration types using a
declaration. It is also possible to create an alias type declaration, in which you assign a
new name to an existing type.
enum declaration
record declaration
3 ordinal type 5
( *
Figure 7.26: Pascal Syntax for Type Declarations
Note
• This syntax allows you to declare your own data types.
• The following sections contain the details of declaring different kinds of custom
types:
– Records/structures and unions are shown in Pascal Record Declaration.
– Enumerations are shown in Pascal Enumeration Declaration.
• Listing 7.8 shows how to declare alias types. An alias type give a new name to an
♠
existing type. Included in this are examples of the following:
– & is an alias for !
.
– & is an alias for an array of five
values.
• Notice that these new types can be used to declare variables, arrays, and parameter.
•
is an array that contains & in each element. Each element of this
array is an array of five integer values.
537
CHAPTER 7. CUSTOM DATA TYPES
Pascal
,
& !
%
♡
&
&
3 5 &
,
, 35
, 3 5
%
Listing 7.8: Testing the alias declarations in Pascal
538
7.4. CUSTOM DATA TYPES IN PASCAL
A record is a type that allows you to store multiple field values. In Pascal the record defines a
list of fields and their types. The field declarations are similar to other variable declarations,
with you specifying the name and then the type of the field.
array spec.
3 ordinal type 5
field name
( *
record name identifier
Note
• This is the syntax for declaring your own custom record.
• The declaration starts with , which indicates that this is a declaration for a
custom type, then indicating the declaration of a structured record.
• Next comes an option struct name. This identifier can be used to refer to the structa
but requires the keyword before it. For example, the declaration in Listing 7.3
declares a
, or a
, depending on if you use the struct name
or the typedef name.
• Following this is a list of fields between braces (i.e. {}). Each field has its own
type that may be of any type, including other structures, arrays, standard types,
enumerations, and unions. ♠
• Finally the typedef ends with the name of the type you are declaring.
• Listing 7.3 shows an example of a record in C. The
record contains an array
of fifty characters called
, and an integer called .
• Remember that the type declaration is creating a new type. After declaring the
you can now create variables of the
type.
• Additional fields could be added to the record, and these will be added to all variables
declared from this type.
a This enables you to declare a struct outside of a .
539
CHAPTER 7. CUSTOM DATA TYPES
Pascal
,*
(
+
!
* $
%
(
3 5 (
' + '
%
Listing 7.9: Pascal for working with a record
540
7.4. CUSTOM DATA TYPES IN PASCAL
Pascal records can include a variant part, which stores a single value from a list of field options.
The variant part comes at the end of the record, starting with the keyword. The variant
parts is matched with a ordinal type (e.g. enumeration) that can also be stored as a tag field,
indicating which field option is currently storing a value. See Listing 7.10 for an example.
Pascal
,-
% '
!+7!&,* !+7$', !+7,0,
%
%-
,
/$
' ' +' ' ' ♡
( *
'
'
!+7$',
!
+
!+7!&,* /$
!
!+7$', /$
!+7,0, /$
+
%
Listing 7.10: Pascal variant record (union)
Note
• The variant part of the record stores a single value.
• %-
, stores three values: ,
, and one value from the variant
part.
♠
• The
field of the %-
, record indicates which of the three field options is
storing a value. This is known as a .
• You have to manage the tag field yourself.
541
CHAPTER 7. CUSTOM DATA TYPES
An enumeration is a list of available options for the type. A variable of an enumeration type
can store one of these values. In Pascal you declare the enumeration by listing the available
constants within parenthesis.
Pascal
,
( *
/
$ + &* 0,*%7&*
%
/
$ +
+ /$
'+ ' ♡
&* /$
'
'
0,*%7&* /$
'*
'
/$
'-
'
%
Listing 7.11: Pascal code illustrating enumeration declarations.
Note
• This is the syntax that allows you to declare an enumeration in Pascal.
• The enumeration type contains a list of constants between parenthesis (i.e. ). ♠
Each constant must have a unique name, and the by convention is all UPPERCASE.
542
7.5. UNDERSTANDING CUSTOM TYPES
Custom data types offer you the opportunity to define how data is organised in your program.
You can create records that contain a number of fields, unions that store a single field value,
and enumerations that define their own list of values. To help you understand these concepts
better the following illustrations demonstrate how these values are stored in the variables in
your code.
Section 7.2.1 Designing Small DB described the design of a Small DB program. The program
allows the user to enter some values that were then stored in variables in the program, making
use of records, unions, and enumerations. The design for this program included a number
of functions and procedures, one of which was the * * function. This function was
responsible for reading a row value from the user and returning it in a * record. The flowchart
for this function is shown in Figure 7.29, which is a repeat of Figure 7.16.
The following illustrations will show this code running to read in a value from the user. This
will demonstrate how the computer stores values in record, union, and enumeration vari-
ables.
The illustrations will show the following:
1. Code is loaded for Small DB
2. * * is called to read in row with id 0
3. Step 1 stores the value 0 in ’s field
4. A double value is entered by the user
5. The double data is stored in the row
6. The row is returned to %
7. This process is repeated for each element of the array
543
CHAPTER 7. CUSTOM DATA TYPES
Read Row
Assign result.data.int
val the integer value
from line
Assign result.data.dbl
Assign result.data.txt
val the double value from
val the value from line
line
Return result
End
544
7.5. UNDERSTANDING CUSTOM TYPES
When the program starts its code is loaded into memory and its procedure is started.
Figure 7.30: When the program starts % allocates space for its local variables, including the array
Note
• In Figure 7.30 the indicated areas show the following:
1. The Program starts and %
is loaded onto the stack, allocating space for its
local variables.
2. The array is allocated space to store its values. Each element of the
array has the fields declared in the * record structure.
3. Each * has an ,
, and value. ♠
4. Each of these values has either a
, a or a .
• Notice that the values in the array are allocated next to each other.
• In the illustration the *’s field will have only one of its fields highlighted,
indicating which field is currently stored in the union.
545
CHAPTER 7. CUSTOM DATA TYPES
The * * function is called to read a value from the user. This will check what the
user has entered and store an appropriate value in the * it returns.
Read Row
1 Read Row is loaded onto
next id: 0
line:
the Stack
Function: Read Row
d6$j%kk00fwRe!dW ----------------------------
Returns: Row - a Row with data read from the user
result:
Parameters:
id: 91623 1: next id (Integer) - the id of the row to be read
kind: UNK_VAL
data.int_val:
Local Variables:
data.dbl_val: -1378 *: line (String - 16 characters) - the text read from the user
data.txt_val: Steps:
1: Set result's id to next id
Instruction: Step 1 2: Output 'Enter value: ' to the Terminal
3: Read text entered by user into line
Main 4: If line is an integer
5: set result's data's Int Val to the integer value in line
i: 0 6: set result's kind to INT_VAL
db_data[]: 7: Else If line is a double
8: set result's data's Dbl Val to the double value in line
id: 7139 9: set result's kind to DBL_VAL
kind: UNK_VAL
data.int_val:
10: Else
data.dbl_val: 10723 11: set result's data's Txt Val to the text in line
data.txt_val: 12: set result's kind to TXT_VAL
id: -91823 13: Output "Stored in row with id ",2and result's id
kind: UNK_VAL 14: Return the result
data.int_val:
data.dbl_val: 36126 Procedure: Main Its result is a Row, and so it
data.txt_val:
---------------------------- has an id, kind, and data
id: 0 Local Variables:
kind: UNK_VAL *: db_data (array containing 3 Row values)
data.int_val:
data.dbl_val: -73 *: i (Integer) -
data.txt_val: Steps:
1: for i loops over each element in db_data
Instruction: Step 2 2: set db_data[i] to result of calling Read Row(i)
3: ...
Figure 7.31: At step 2 % calls * *, getting it to read in the 𝑖𝑡ℎ row from the user
Note
• In Figure 7.31 the indicated areas show the following:
1. When * * is called it is allocated space on the stack.
2. * * will be returning a * value, so its result will have ,
, and
values as these are what is specified in the * record’s definition. ♠
• Each row will have the same kind of data stored within it. The details of this are
specified in the * record’s definition.
546
7.5. UNDERSTANDING CUSTOM TYPES
Read Row
next id: 0 2 result refers to this row
line: Function: Read Row
d6$j%kk00fwRe!dW ----------------------------
Returns: Row - a Row with data read from the user
result:
Parameters:
id: 0 1: next id (Integer) - the id of the row to be read
kind: UNK_VAL
data.int_val:
Local Variables:
data.dbl_val: -1378 *: line (String - 16 characters) - the text read from the user
data.txt_val: Steps:
1: Set result's id to next id
Instruction: Step 1 2: Output 'Enter value: ' to the Terminal
3: Read text entered by user into line
Main 4: If line is an integer
5: set result's data's Int Val to the integer value in line
i: 0 6: set result's kind to INT_VAL
db_data[]: 7: Else If line is a double
8: set result's data's Dbl Val to the double value in line
id: 7139 9: set result's kind to DBL_VAL
kind: UNK_VAL
data.int_val:
10: Else
data.dbl_val: 10723 11: set result's data's Txt Val to the text in line
data.txt_val: 12: set result's kind to TXT_VAL
id: -91823 13: Output "Stored in row with id ", and result's id
kind: UNK_VAL 14: Return the result
data.int_val:
data.dbl_val: 36126 Procedure: Main
data.txt_val:
----------------------------
id: 0 Local Variables:
kind: UNK_VAL *: db_data (array containing 3 Row values)
data.int_val:
data.dbl_val: -73 *: i (Integer) -
data.txt_val: Steps:
1: for i loops over each element in db_data
Instruction: Step 2 2: set db_data[i] to result of calling Read Row(i)
3: ...
Note
• In Figure 7.32 the indicated areas show the following:
1. Step 1 of * * assigns a value to .
2. In this code refers to this variable in * *.
3. The part then refers to this field.
4. As a result the value from the
parameter is read, and its value is as- ♠
signed to .
• Each part of refers to a different kind of data.
• is a row, this has ,
, and fields.
• is an !
, it is the id field of the *.
547
CHAPTER 7. CUSTOM DATA TYPES
Read Row
The value entered is
next id: 0
line: 2 stored in the line string.
Function: Read Row
3.1415 ☐ 00fwRe!dW ----------------------------
Returns: Row - a Row with data read from the user
result:
Parameters:
id: 0 1: next id (Integer) - the id of the row to be read
kind: UNK_VAL
data.int_val:
Local Variables:
data.dbl_val: -1378 *: line (String - 16 characters) - the text read from the user
data.txt_val: Steps:
1: Set result's id to next id
Instruction: Step 7 2: Output 'Enter value: ' to the Terminal
3: Read text entered by user into line
Main 4: If line is an integer
5: set result's data's Int Val to the integer value in line
i: 0 6: set result's kind to INT_VAL
db_data[]: 7: Else If line is a double
8: set result's data's Dbl Val to the double value in line
id: 7139 9: set result's kind to DBL_VAL
kind: UNK_VAL
data.int_val:
10: Else
data.dbl_val: 10723 11: set result's data's Txt Val to the text in line
data.txt_val: 12: set result's kind to TXT_VAL
id: -91823 13: Output "Stored in row with id ", and result's id
kind: UNK_VAL 14: Return the result 1
data.int_val:
data.dbl_val: 36126 Procedure: Main Step 3 reads in the value
data.txt_val:
---------------------------- entered by the user
id: 0 Local Variables:
kind: UNK_VAL *: db_data (array containing 3 Row values)
data.int_val:
data.dbl_val: -73 *: i (Integer) -
data.txt_val: Steps:
1: for i loops over each element in db_data
Instruction: Step 2 2: set db_data[i] to result of calling Read Row(i)
3: ...
At Step 7 the code detects that
3 the value in line is a double, so
code will proceed to Step 8
Figure 7.33: A double value is entered by the user, so the code must store the double in the row
Note
• In Figure 7.33 the indicated areas show the following:
1. At Step 3 the computer reads the text entered by the user.
2. The value read is stored in the
variable. ♠
3. At Step 7 the code determines that the data is a double, and execution will
proceed to step 8.
548
7.5. UNDERSTANDING CUSTOM TYPES
Figure 7.34: A double value is entered by the user, so the code must store the double in the row
Note
• In Figure 7.34 the indicated areas show the following:
1. Step 8 of * * stores the double value entered by the user into the
field of the field of the *.
2. Notice that the union is now shown as storing a value in its field. ♠
3. Step 9 stores the $ .$ value in the
field of the *. This is one of
the values from the #
enumeration.
4. At this point all of the fields of have been assigned values.
549
CHAPTER 7. CUSTOM DATA TYPES
Note
• In Figure 7.35 the indicated areas show the following:
1. At the end of * * the * is returned to %
.
2. In %
the value is used in an assignment statement, that assigns it to the 𝑖𝑡ℎ
value in the array. As is currently 0, this stores the entire row in
35. ♠
3. When this assignment occurs all of the data from the of * * is
copied into 35.
• With Records and Unions you can read/write to individual fields using the dot no-
tation, or you can access the entire record.
550
7.5. UNDERSTANDING CUSTOM TYPES
Second time through the loop Each time the value returned
assigns a value to this element is stored in an element of the array
Figure 7.36: The for loop ensures that a * value is read in for each element of the array
Note
• In Figure 7.36 the indicated areas show the following:
1. Each time through the loop the value is written to an element in the array. This
is showing the last iteration where is 2.
2. The second time this loop was executed the user entered an integer value, this
is now stored in the second element of the array.
3. The third time through the loop, the result returned is storing a string value.
This is returned to %
, and then stored in the array.
♠
• Notice that there is only ever one value in each *’s . This is a union, and only
stores one of its field values.
• See how the enumeration values indicate the field the data has been stored in. This
is why the enumeration’s constants were named in a similara way to the union’s
fields.
a They could have been named anything, but this reflects their purpose well.
551
CHAPTER 7. CUSTOM DATA TYPES
(
* is the other key piece of logic in the Small DB program. This procedure outputs
the values read from the user to the Terminal. It uses the data stored in the *’s fields to
determine how this value is output, and how the data can be read. The flowchart of this logic
is shown in Figure 7.37.
Print Row
To Print's
Kind
INT_VAL DBL_VAL TXT_VAL
Output "has integer " Output "has double " and Output "has text " and
Output "has an unknown
and the Int Val of To the Dbl Val of To Print's the Txt Val of To Print's
value"
Print's data data data
End
Figure 7.37: Flowchart of the steps needed to print a * to the Terminal, from Figure 7.18
Within %
, (
* is called once for each * in the array. The following illustra-
tions demonstrate the third and final call to (
*.
The illustrations will show the following:
1. (
* is called for each element in the array
2. The text value is output to the Terminal
You can use these details to determine how the other data was written to the Terminal.
552
7.5. UNDERSTANDING CUSTOM TYPES
This illustration starts part way through the third call to (
*. At this stage the first two
rows have been output to the Terminal, as has the of the third *.
Print Row
This passes the entire Row
to print: 2 to the parameter (by value, so
id: 2 the data is copied in)
kind: TXT_VAL
data.int_val:
data.dbl_val: Fred☐ Procedure: Print Row Step 1 outputs the 3
data.txt_val: ----------------------------
Parameters: Row's id
Instruction: Step 2
1: to print (Row) - the row to print
Steps:
Main 1: Output 'Row with id ', and to print's id to the Terminal
i: 2: select case from to print's kind
2
3: case is INT_VAL
db_data[]: 4: Output ' has integer ' and int_val of to print's data
5: case is DBL_VAL
id: 0
6: Output ' has double ' and dbl_val of to print's data
kind: DBL_VAL
data.int_val: 7: case is TXT_VAL
data.dbl_val: 3.1415 8: Output ' has text ' and txt_val of print's data
data.txt_val:
id: 1 Procedure: Main Step 2 uses the kind
kind: INT_VAL ---------------------------- 4 of the row to determine
data.int_val: Local Variables:
data.dbl_val: 27
*: db_data (array containing 3 Row values)
the path to take
data.txt_val:
*: i (Integer) -
id: 2 Steps:
kind: TXT_VAL
data.int_val:
2: ...
data.dbl_val: Fred☐ 3: for i loops over each element in db_data
data.txt_val: 4: call Print Row( db_data[i] )
Instruction: Step 4
1
Enter value: 27
Stored in row with id 1
Enter value: Fred
Stored in row with id 2
Row with id 0 has double 3.1415
Row with id 1 has integer 27
Row with id 2
Figure 7.38: ( * is called for each of the * elements in
Note
• In Figure 7.38 the indicated areas show the following:
1. This is the third call to (
*. Each time this procedure is called it receives
a copy of the data from the element passed to it.
2. The parameter is a copy of the data from the array element.
3. The first action in (
* is to output the value from the
*.
4. The illustration is showing the computer at the stage where it is reading ♠
’s
to determine which path to take. As
’s
is currently
,0, .$ it will take the path at Step 8.
• The case statement will allow the code to output the message that matches the kind
of data stored in
.
553
CHAPTER 7. CUSTOM DATA TYPES
Print Row
The kind indicates to read
to print: 2 the txt_val field from the
id: 2 data union
kind: TXT_VAL
data.int_val:
data.dbl_val: Fred☐ Procedure: Print Row
data.txt_val: ----------------------------
Parameters:
Instruction: Step 8
1: to print (Row) - the row to print
Steps:
Main 1: Output 'Row with id ', and to print's id to the Terminal
i: 2: select case from to print's kind
2
3: case is INT_VAL
db_data[]: 4: Output ' has integer ' and int_val of to print's data
5: case is DBL_VAL
id: 0
6: Output ' has double ' and dbl_val of to print's data
kind: DBL_VAL
data.int_val: 7: case is TXT_VAL
data.dbl_val: 3.1415 8: Output ' has text ' and txt_val of print's data
data.txt_val:
id: 1 Procedure: Main
kind: INT_VAL ---------------------------- 1
data.int_val: Local Variables:
data.dbl_val:
data.txt_val:
27
*: db_data (array containing 3 Row values) The txt_val of
id: 2
*: i (Integer) - the Row's data is
Steps:
kind: TXT_VAL
2: ...
output (in quotes)
data.int_val:
data.dbl_val: Fred☐ 3: for i loops over each element in db_data
data.txt_val: 4: call Print Row( db_data[i] )
Instruction: Step 4
Enter value: 27
Stored in row with id 1
Enter value: Fred
Stored in row with id 2
Row with id 0 has double 3.1415
Row with id 1 has integer 27
Row with id 2 has text 'Fred'
Figure 7.39: ( * is called for each of the * elements in
Note
• In Figure 7.39 the indicated areas show the following:
1. Step 8 reads the field of
’s field. This reads the text value
from within that field, and this is output to the Terminal.
2. The
field was used to determine which field to read from the union.
• In this example the record, union, and enumeration are all working together to enable
the required functionality.
• Without the enumeration it would not be possible to determine which field to read ♠
from the union. Reading any of the fields on the union would return data, but only
the field that was written to can be relied about to have a meaningful value.
• Without the union you would need to waste space storing all three data values, but
only ever using one.
• Without the record it would be hard to relate the values stored within a single *.
The row only existed because of the record’s declaration.
• Back in %
, the array allows you to store multiple of these values.
554
7.6. EXAMPLE CUSTOM TYPES
7.6.1 Lights
This example draws three light bulbs to the screen. These lights can be clicked to turn them on
and off. The code includes the declaration of a record/structure and an enumeration.
555
CHAPTER 7. CUSTOM DATA TYPES
C++
&-%7$! ,+
,
556
7.6. EXAMPLE CUSTOM TYPES
C++
557
CHAPTER 7. CUSTOM DATA TYPES
C++
7
7
7
♢
7 35
7
$,7-,,'&
7
7 35
35 7
35 7
Listing 7.14: Lights code in C++, continues in Listing 7.15
558
7.6. EXAMPLE CUSTOM TYPES
C++
$
7 7
7
7 7
7
7 7
%
(
7
7 7
$
7 7 ♢
7
-
7
7 &-%7$! ,+
7
7 &-%7$! ,+
7
77
7 7
7
Listing 7.15: Last of the Lights code in C++
559
CHAPTER 7. CUSTOM DATA TYPES
Pascal
$
, !
- !
&-%7$! ,+
,
,
$+ +%$$7$! , %!-%7$! , $*7$! ,
$
Listing 7.16: Lights code in Pascal, continues in Listing 7.17
560
7.6. EXAMPLE CUSTOM TYPES
Pascal
561
CHAPTER 7. CUSTOM DATA TYPES
Pascal
- $ $
%
$
♡
$
$-
% 35
35 '
35 '
562
7.6. EXAMPLE CUSTOM TYPES
Pascal
%
(
%
3 &-%7$! ,+ 5 $
'
/
'$ '
$
♡
-
(
- $
+
$
*+
/
*
* *
%
Listing 7.19: Lights code in Pascal
563
CHAPTER 7. CUSTOM DATA TYPES
The Shape Drawing program allows the user to create simple shape drawings using circles,
triangles, rectangles, and ellipses.
564
7.6. EXAMPLE CUSTOM TYPES
C++
%07+ (+
%&-7*! ,70
%
+
%&-7*,
%&-7!*$
%&-7,*!&$
%&-7$$!(+
*/!&7(
,
3 %07+ (+ 5
7 7
Listing 7.20: Shape Drawing code in C++, continues in Listing 7.21
565
CHAPTER 7. CUSTOM DATA TYPES
C++
(
7
%&-7!*$
7
%&-7*,
,''
,
♢
7
*,&$
7
7
!*$
7 7
,''
,
-&#&'/&
7
7
7 7
7
%07+ (+
7 35
Listing 7.21: Shape Drawing code in C++, continues in Listing 7.22
566
7.6. EXAMPLE CUSTOM TYPES
C++
(
7
+
%07+ (+
35 -&#&'/&
567
CHAPTER 7. CUSTOM DATA TYPES
C++
(
7
7
.#7)
7
.#7
7
7
7
7
7 %&-7*,
7 *,&$
7
7 %&-7!*$
7 !*$
,''
,
♢
7
7
,
%07+ (+
+
7
*,&$
7
3
5
!*$
7 3
5
,''
,
'
568
7.6. EXAMPLE CUSTOM TYPES
C++
7
7
$,7-,,'&
7
7
7
7
%
♢
7
7
7
7
7
7
7
77
7 7
Listing 7.24: Last of the Shape Drawing code in C++
569
CHAPTER 7. CUSTOM DATA TYPES
Pascal
%07+ (+
%&-7*, *
%&-7!*$
*/!&7( *
, ,
,
, + ,
, ,
+ , !*$7,1( *,&$7,1( -&#&'/&7,1(
♡
+ 3 %07+ (+ 5
!
++ + ,
(
%&-7!*$
*
%&-7*,
,
,
570
7.6. EXAMPLE CUSTOM TYPES
Pascal
+ +
*,&$7,1( *
!*$7,1(
,
,
%07+ (+
+ + 35
( +
571
CHAPTER 7. CUSTOM DATA TYPES
Pascal
(%
(
(
!
* %&-7*,
++ *,&$7,1(
(
(
,
!
%07+ (+
+
++
*,&$7,1( *
+ 3!
5
!*$7,1( + 3!
5
,
572
7.6. EXAMPLE CUSTOM TYPES
Pascal
(%
(
(
!
* %&-7*,
++ *,&$7,1(
(
(
,
!
%07+ (+
+
++
*,&$7,1( *
+ 3!
5
!*$7,1( + 3!
5
,
573
CHAPTER 7. CUSTOM DATA TYPES
Read over the concepts in this chapter and answer the following questions:
1. What is a type?
2. What is the relationship between a type and a value?
3. When you create your own type what have you created? A value, or something else?
4. Why would you want to create your own type?
5. What are the three main kinds of type you can create?
6. What kind of data type(s) could you create to model the following in a program?
(a) An address book, containing names, phone numbers, and email addresses.
(b) The kind of a ‘power up’ in a game, e.g. health pack, upgrade, bonus, etc.
(c) A field that is either an integer, a double, or some text.
(d) A button that has a location on the screen, a width and height, and some text that
is drawn on the button.
7. What is a record? What can it be used to model?
8. What is an enumeration? What can it be used to model?
9. What is a union? What can it be used to model?
10. Why is it a good idea to use an enumeration in conjuncture with a union?
11. Explain the different ways you can store/read a value when you are using a record.
12. Explain the different ways you can store/read a value when you are using a enumeration.
13. Explain the different ways you can store/read a value when you are using a union.
14. Open one of your SwinGame projects and have a look in the folder. This folder contains
a number of source code files used to access SwinGame functionality. Have a look in the
Types file (types.c or sgTypes.pas), and examine the follow types. For each type write a
short description of what it contains.
(a) Rectangle
(b) Circle
(c) LineSegment
(d) Triangle
(e) Point 2D
(f) Vector
574
7.7. CUSTOM TYPE EXERCISES
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. Extend the Small DB program so that each ‘row’ has three ‘columns’.
2. Explore the sizes of the different data types you have created using the + ' function:
in C, or +' in Pascal.
575
Dynamic Memory Allocation
8
here are many places you can draw upon to power your spells. So far
you have been limited by the constraints of this realm. The tools I
give you now will let you stret beyond this realm, and will open your
mind to even greater powers. You will need your orb, your wand, and . . .
So far data has been limited by the constraints of the Stack. With the stack, the compiler must
know how much space to allocate to each variable ahead of time. This means you are limited
to working with a fixed number of values, whether those values are stored in a number of
variables or stored in an array. This constraint is not a problem for small programs, but most
programs will require the flexibility to work with a variable number of data elements.
This chapter introduces the tools needed to dynamically allocate additional memory for your
program to use. With these tools you will be able to dynamically allocate additional space for
your program to use as you need it. As memory is finite you will also see how you can release
this memory back to the computer when you no longer require it.
When you have understood the material in this chapter you will be able to dynamically allo-
cate memory for your program, increasing and decreasing the number of values that you are
storing.
Contents
8.1 Dynamic Memory Allocation Concepts . . . . . . . . . . . . . . . . . . . . . . . 579
8.1.1 Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
8.1.2 Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
8.1.3 Allocating Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
8.1.4 Freeing Memory Allocations . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
8.1.5 Issues with Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
8.1.6 Linked List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
8.1.7 Summary of Dynamic Memory Allocation Concepts . . . . . . . . . . . . . 598
8.2 Using Dynamic Memory Allocation . . . . . . . . . . . . . . . . . . . . . . . . . 599
8.2.1 Designing Small DB 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
8.2.2 The Analysis Phase: Understanding Small DB 2 . . . . . . . . . . . . . . . 600
8.2.3 The Design Phase: Choosing artefacts and designing control flow . . . . . 600
8.2.4 The Implementation Phase: Writing the code for Small DB 2 . . . . . . . . 607
8.2.5 The Testing Phase: Compiling and running Small DB 2 . . . . . . . . . . . 607
8.2.6 Designing Linked Small DB 2 . . . . . . . . . . . . . . . . . . . . . . . . . . 608
8.2.7 The Design Place: Designing Linked Small DB 2 . . . . . . . . . . . . . . . 609
8.3 Dynamic Memory Allocation in C . . . . . . . . . . . . . . . . . . . . . . . . . . 621
8.3.1 Small DB 2, the dynamic array version in C . . . . . . . . . . . . . . . . . . 621
8.3.2 Small DB 2, the linked version in C . . . . . . . . . . . . . . . . . . . . . . 625
577
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
578
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
8.1.1 Heap
When your program is executed it allocated memory to work with. This memory is divided
into different areas based on the kind of values that will be stored there. Previously all of the
program’s data was housed on the Stack, dynamically allocated memory is allocated into a
separate area known as the Heap. Any memory that you allocate to your program will come
from this location.
4 Heap
3 Global Variables
The Program's
Memory
Figure 8.1: The Heap is used to store all dynamically allocated values
Note
• Figure 8.1 includes the following areas:
1. Your program’s machine code is loaded into the Code Area.
2. The Stack is used to manage the execution of the program’s functions and pro-
cedures.
3. Global Variables are allocated their own space.
4. The new area is the Heap. This is used to store all dynamically allocated values.
• Values can be stored in the global variables, in local variables on the Stack, and on
the Heap using dynamic memory allocation functions and procedures. ♠
• The space taken up by the global variables is fixed based on the size of the variables
you have declared.
• Each function/procedure takes a fixed amount of space on the stack. The space
allocated is enough to store each of the local variables, plus some additional space
for various overheads.
• The compiler take care of managing memory in the stack and for the global variables.
• You are responsible for any memory allocation done on the heap.
579
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Dynamic memory allocation is performed with a couple of operations that will be provided by
the programming language you are using. These operations allow you to do the following:
• Allocate Space: You ask the Operating System to allocate you some space into which
you want to store a certain value. The Operating System will then allocate you space on
the Heap that is large enough to store the value you require.
• Free Allocation: When you have finished using a piece of memory you have been allo-
cated on the Heap, you can tell the operating system that you have finished with this
memory, and that it is free to allocate this to some other value.
These are the two basic actions that exist for performing dynamic memory management. Ba-
sically, you can ask for memory, and you can give it back. Once you have been allocated space,
that space will be reserved for your use until you free that allocation. So it is important to
remember to free the memory you have been allocated when you no longer require it.
Allocate Space
----------------------------
Returns: Row - a Row with data read from the user
Parameters:
1: next id (Integer) - the id of the row to be read
Local Variables:
*: line (String - 16 characters) - the text read from the user
Steps:
1: Set result's id to next id
2: Output 'Enter value: ' to the Terminal
3: Read text entered by user into line
4: If line is an integer
5: set result's data's Int Val to the integer value in line
6: set result's kind to INT_VAL
7: Else If line is a double
8: set result's data's Dbl Val to the double value in line
Func or Proc 9:
10: Else
set result's kind to DBL_VAL
11: set result's data's Txt Val to the text in line
12: set result's kind to TXT_VAL
13: Output "Stored in row with id ", and result's id
14: Return the result
val: 5
Free Space
Procedure: Main
----------------------------
Local Variables:
*: db_data (array containing 3 Row values)
*: i (Integer) -
Instruction: Step 2 Steps:
1: for i loops over each element in db_data
2: set db_data[i] to result of calling Read Row(i)
3: ...
Figure 8.2: You can ask for space, and return the space you were allocated
Note
• Figure 8.2 shows the idea behind the two operations.
• You can ask to be allocated space, this will give you access to a space on the heap.
You can then use this to store a value. ♠
• You can tell the Operating System when you are finished with the space, so that it
can allocate it to something else.
580
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
By its very nature, dynamic memory allocation must work a little differently to the way we have
been working with values so far. So far, when you wanted to work with a value you declared
a variable, or an array. This would have been a Local Variable, with its value allocated on
the stack along with the other variables you were working with in the current function or
procedure. The variable and its value were closely related, with the value being located within
the variable. With dynamic memory allocation the values you are allocated are on the heap.
This means that their values are not bound within a variable, but exist entirely outside of any
variables that appear in your code.
One of the challenges of working with dynamically allocated memory is that you can no longer
‘see’ these values in your code. When you were working with variables, they were in the code,
you could see them and think about the value they stored. With dynamically allocated memory
you do not have this advantage, these values will be allocated as a result of the operations
that are performed while the code is running. This is why it is called dynamically allocated
memory. It is not memory allocated to variables, it is memory allocated upon request.
This raises one very important question, as illustrated in Figure 8.3:
If the values exist outside of variables, how do you access them?
For this we require a new kind of data, a new Type. This type is used to store a value that tells
you where the data you want can be located. It is like an address, telling you where the data
can be found. This is the Pointer type.
3.1415 ☐
id: 63 10.0
kind: DBL_VAL
data.int_val:
-5
data.dbl_val: 3.1415☐ 17.21
data.txt_val:
25.1
id: 2
kind: TXT_VAL
?
data.int_val:
data.dbl_val: Fred☐
data.txt_val:
INT_VAL 73
Figure 8.3: How can you access these dynamically allocated values?
581
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
8.1.2 Pointer
A Pointer is a new kind of data type, just like Integer, Double, and Boolean. A Pointer Value
is an address, a location in memory where a value can be found. The name ‘Pointer ’ is very
descriptive, a Pointer points to a value. It tells you, ‘The data I refer to is over there...’.
Type
La
st
chec bit is
k bit a
Will be used
11
store data to
th ts
about ...
...
re 3 bi
001
e
sto rst
Fi
111If the first
larger thanpart is
Th
stor ese
e th bits
the e tim
... e
La
st
chec bit is
k bit a
Will be used
11
Pointer
store data to
th ts
about ...
...
re 3 bi
001
e
sto rst
Fi
111If the first
larger thanpart is
Th
stor ese
e th bits
the e tim
... e
Is a Type built
into the Programming
Language
Just like other types, you can
have Pointer values, and these
can be stored in Variables
Figure 8.4: A Pointer Value is the address of a value, in effect it points to a value
Note
• A pointer is an existing artefact, a data type that is built into the programming
language.
• A pointer has a value, that stores the location of another value.
• It is a good idea to picture a pointer as a value that points to another value. ♠
• The pointer’s value is the memory address of the value it points to.
• The CPU architecture tells you the size of its pointers. A 32bit machine has 32bit
pointers. A 64bit machine has 64bit pointers.
582
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
Pointers can be used to point to locations in the heap. When you ask the Operating System
to allocate you space on the heap, it will give you a pointer value that points to the space you
were allocated. You can use this pointer to access the value at that location.
3.1415 ☐
id: 63 10.0
kind: DBL_VAL
data.int_val:
-5
data.dbl_val: 3.1415☐ 17.21
data.txt_val:
25.1
id: 2
kind: TXT_VAL
data.int_val:
data.dbl_val: Fred☐
data.txt_val:
INT_VAL 73
Procedure: Main
ptr: 0x12 ----------------------------
Local Variables:
*: db_data (array containing 3 Row values)
*: i (Integer) -
Instruction: Step 2 Steps:
1: for i loops over each element in db_data
2: set db_data[i] to result of calling Read Row(i)
3: ...
Figure 8.5: You can use pointers to access values on the heap
Note
• Your code can access values stored on the stack, in its local variables and parame-
ters.
• There is no way to directly access values on the heap.
• The memory allocation functions will give you a pointer to the space you were allo- ♠
cated.
• Storing the pointer in a local variable will mean you can use it to access the value
on the heap.
583
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Pointers store a value that is an address of the value that it points to. This means that you can
point to any value in memory, regardless of where it is. You can have pointer values that point
to Local Variables, Global Variables, Parameters, Array elements, fields of Records or Unions.
One of its key ability, however, is the ability to point to values on the Heap.
24
10100101
Int
Variable
(p) Variable
(i)
This pointer is pointing to
a User Data value in the
Data array
txtVal 'Fred'
intVal =
dblVal = 3.14
User Data
User Data
User Data
=
10100101
73
Variable
(p1)
Array
(Data)
This pointer is pointing to
a Point value in the
Mouse variable
x= 24
10100101 y= 73
Variable Point
(p2)
Variable
(Mouse)
This pointer is pointing to
an Integer value, the value in
the x field, of the Point in
the Mouse Variable.
x= 24
10100101 y= 73
Variable Point
(p3)
Variable
(Mouse)
This is pointing to a Row Value
record that is on the Heap
10100101 id: 2
kind: TXT_VAL
Variable data.int_val:
(p4) data.dbl_val: Fred☐
data.txt_val:
Figure 8.6: A Pointer can point to any value, at any location in memory
Note
• Languages usually require you to declare the kind of data that a Pointer Value will
refer to. So rather than just having a generic pointer, you will have things like a
♠
pointer to an Integer, or a
- . This makes it easier to
work out what you can do with the value the pointer points to.
584
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
A Pointer value is the same as any other value. It can be stored in Local Variables, Global
Variables, it can be passed to a function in a Parameter, it can be returned from a Function,
and it can also exist on the Heap.
Figure 8.7 shows an illustration of some values in memory. The variable is located
somewhere on the stack as a local variable. This variable is storing a pointer value that points
to a &1 that is on the Heap. Each of the nodes on the heap are also storing pointer values
that refer to other values that are also on the heap.
Data = 24
Data = 73
Next = 0x10
Next = 0x00
Node
Node
Data = 73 Nothing!!
Next = 0x1f
There will be a special
Node
value to represent the
fact you pointer value does
not point to anything...
Note
• A pointer value is no different from any other value, and can be stored on the stack,
the heap, or in global variables.
• Languages provide a special value for pointers that do not point to a value. In C this ♠
is the &-$$ value, in Pascal it is the
value, in both cases it is a value that points
to nothing.
1 The & would be a record type declared in the code. This type would contain an Integer value field named ,
585
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
You need to be able to perform certain actions to make pointers useful. These include:
• You must be able to get a pointer to a value. For example, you should be able to get a
pointer to a value stored in a Variable.
• Once you have a Pointer value, you must be able to follow that pointer to its value so that
you can . . .
– Read the value it points to.
– Store a value at the location pointed to.
3.
14
15 3.1415
In an assignment statement
you can follow the pointer (on the
left hand side) and store a value
in the location it points to
873
12.873
12.
Figure 8.8: You can get pointers to values, and you can follow pointers to values
Note
• You can get the address of values in Local Variables, Global Variables, Parameters,
fields of Records and Unions. Basically, you can get the address of any value you
can read.
• Once you have the address (the Pointer value), you can store, or you can use it.
• You need to follow the pointer, called dereferencing the pointer, to read its value or
to assign a new value to the location it refers to.
• Remember there are two values with pointers: ♠
1. There is the value of the pointer itself. This is the address that is pointed to.
The circle at the start of the line in the illustrations.
2. There is the value that pointed to. The one at the end of the arrow in the illus-
trations.
• You can interact with both of these values, depending on whether you follow the
pointer or use the pointer’s value directly.
586
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
Memory is laid out as a sequence of bytes, into which values can be stored. The bytes can
be thought of as being in a long line, with each being given numbered based on its position
in that line. So the first byte would be byte 0, the next is byte 1, the next byte 2, and so on.
This number is then the address of that byte. So byte 975708474 is next to byte 975708475,
which is next to byte 975708476, etc. This number is also unique, so there is only one byte
975708474. It is this number that is the Pointer value, the number of the byte that it is
pointing to.
Figure 8.8 shows an example of memory used by an array of three values. Each value is a
Double, so each one occupies 8 bytes. If the first is at address 975708474, then the second
starts at address 975708482 (975708474 + 8 bytes). This Figure also shows a pointer, , that
points to this value. That means that has the value 975708474, being the address of this
value, stored within it.
One feature that languages have is called pointer arithmetic. When you add, or subtract, a
value from a pointer the compiler will work in terms of the kinds of values the pointer points
to. So in Figure 8.8 is a pointer to a Double, this means that when you add one to p you get
the value 975708482, which is 1 Double past . Therefore,
would be 2 doubles past ,
at 975708490, and so on.
p 10.0
p+1 -5.0
p+2 17.21 This starts at byte 975708482
975
708
474
Variable
(p)
Figure 8.9: The pointer value is the address of the value it points to
Note
• Pointer arithmetic is something you need to know exists, but not something that you
♠
would work with frequently.
587
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
With dynamic memory management, one of the tasks you can perform is to request space from
the heap. With this request the Operating System will locate available space and allocate this
to you for use in your code. The only thing the Operating System really needs to know is how
much space do you require? It can then search for a free space of that size, allocate this to
you, and then give you a pointer to this newly allocated area of memory.
73192837 ?
Variable
(p)
The Heap
????
1312ffd4
Variable
(p)
The Heap
Allocate Space for p
How much space should
be allocated?
Figure 8.10: When requesting a memory allocation you need to specify the size you want
Note
• Allocating memory is an action you can perform by calling appropriate Functions
or Procedures offered to you by the Programming Language.
• Your request for memory must include an indicating of the amount of memory that
you require. ♠
• You also need to have a pointer that will refer to the memory you are allocated.
• It is possible that your request will be denied, this occurs when the computer has
run out of memory to allocate.
588
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
If you want to store a single value on the heap you can ask to be allocated enough space for a
single value. Figure 8.11 shows a Pointer () that points to an Integer value. If you want this
value to be on the Heap you can ask to be allocated enough space to store an integer (4 bytes).
The Operating System will then allocate you 4 bytes of space from the Heap, and give you the
address of this space.
73192837 ?
Variable
(p)
The Heap
10
1312ffd4
Variable
(p)
The Heap
Allocate Space for what p points to (an Integer)
Figure 8.11: You can ask to be allocated enough space to store one value
C++
In C the function from is used to allocate memory. With you must
specify the size of the memory you require in bytes. The function can be used to
give you the size of the value you require. For the above example you would perform the ♢
following, with
giving you the number of bytes needed to store an
value:
Pascal
In Pascal the & procedure is used to allocate memory to a pointer. The & procedure
is passed the pointer to allocate, and Pascal uses the information about what it points
to, to determine how much space to allocate. For the above example you would perform ♡
the following, with & working out that you need to be allocated space for an Integer (the
type of value that points to): &
589
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Storing single values on the Heap can be useful, but often you want to be able to allocate
enough space for a number of values. Arrays on the Stack must be of a fixed length, so this
dynamic allocation allows you to have variable length arrays.
73192837 ?
Variable
(p)
The Heap
73
1312ffd4
124123
Variable -912783
(p)
0
The Heap
Allocate Space for 4 Integer values
C++
In C you can use to allocate space for a number of element. Alternatively the
function from provides direct support for allocating space for an array.
This function takes two parameter, the first takes the number of elements to allocation,
the second the size of those elements. also clears its allocation, setting each byte
allocated to 0. The following code allocates 4 integer values as shown in Figure 8.12:
or using , which would set all values to 0, you
could use
♢
In C you can use the standard array access mechanisms with pointers to access
subsequent elements. So 35 is the value in the first element of the array dynamically
allocated in Figure 8.12, 3 5 is the value of the second element, 3
5 is the value
of the third element, and so on. This relates back to Pointer arithmetic discussed in
Section 8.1.2.
Pascal
Pascal has built in support for dynamic arrays. You can declare an array without a
length, and then call +$
to specify the size you want allocated. Behind the scenes
Pascal will allocate the space for this array on the heap, and will take care of ensuring ♡
that it is cleaned up when you no longer have access to it. If you just want a block of
memory to work with Pascal also offers a % function.
590
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
The advantage of dynamic memory allocation is that you can change your allocations. If you
asked for an array of two values, you may later want to be able to expand that array to three or
four elements. Alternatively, an array with twenty elements may have some data removed and
be shrunk down to only 5 elements. All of this is possible with dynamic memory allocation.
You can ask to have the memory you were allocated changed to a different size.
73
1312ffd4
124123
Variable -912783
(p)
0
The Heap
73
1312ffd4
124123
Variable -912783
(p)
0
The Heap
Change it to point to 2 values
This space is no longer allocated
to the program...
Figure 8.13: You can change the size of the allocation, growing or shrinking the number of element
Note
• These reallocations will keep the data that was in the array previously. Obviously if
the new allocation is smaller than than existing one you will lose some values, but
the others are kept.
♠
• It is possible that the Operating System will need to move your new allocation, so
if you change the size of an array you need to be careful if other pointers refer to
elements in their old locations.
C++
The function from allows you to change the memory allocation of
a pointer. The following C code performs the reallocation shown in Figure 8.13: ♢
Pascal
Pascal dynamic arrays perform this task for you. The +$
procedure allows you to
♡
change the number of elements allocated to a dynamic array as you see fit.
591
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Dynamic memory allocation requires that you manage the memory you are allocated yourself.
You ask to be allocated memory, and it is your responsibility to tell the Operating System
when you are finished with that memory. This is one of the main challenges of working with
dynamically allocated memory. You need to take care to ensure that you do free the memory
you have been allocated when you are finished with it, but at the same time you must make
sure that you do not free the memory while it is still needed.
10
1312ffd4
Variable
(p)
The Heap
p points to an Integer on the Heap
10
1312ffd4
Variable
(p) This space is no longer allocated
to the program...
p still points to the location
where the value The Heap
was previously stored
Free the memory referred to by p
10
00000
Variable Nothing!!
(p)
now p points to
Nothing The Heap
Set p to point to Nothing!
Figure 8.14: You can ask to be allocated enough space to store one value
C++
The function releases the memory allocated to a pointer. To free the memory allocated
to as shown in Figure 8.14 you would use: &-$$ This will both free the ♢
memory allocation and point to nothing so that you cannot accidentally access it later.
Pascal
The procedure releases the memory allocated to a pointer. To free the memory
allocated to as shown in Figure 8.14 you would use:
This will
♡
both free the memory allocation and point to nothing so that you cannot accidentally
access it later.
592
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
Access Violations
The first kind of error you are likely to encounter is caused by trying to accessing memory that
does not exist. This will cause your program to crash. Figure 8.15 shows a common example
where this occurs. Trying to follow a pointer to Nothing will crash the program with an access
violation. This applies whether you are reading or writing to the value at the end of the pointer.
The common name for this kind of error is a segmentation fault, segfault for short.
The only way to avoid these access violations is to take care with your pointers, see Figure 8.16.
When you start working with pointers you need to go a little slower, and think a little more
carefully about what it is you are doing. Having a good understanding of how these dynamic
memory allocation tools work is the first step toward achieving this.
00000
Variable Nothing!!
(p)
argh... it does not
point to anything!
Figure 8.15: Trying to follow a pointer that goes nowhere is a runtime error
Figure 8.16: To avoid access violation, take care with your pointers. From
Note
Here are some tips to help you avoid these access violations:
• If there is any doubt, check your pointers before using them.
• Always initialise your pointers to Nothing, as uninitialised pointers may point to
♠
something, but it wont be something useful.
• You can not see dynamically allocated memory in your code, so use a pencil and
paper to sketch this out as you think through the code.
593
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Memory Leaks
The next error is one that will not cause your program to crash, but will consume all of the
computers memory if it is allowed to run for an extended time. Remember that with dynamic
memory allocation you are responsible for releasing the memory back to the system. If you do
not do this there will come a time when there is no memory left to allocate. . . Memory leaks
are hard to detect, as they do not cause your program to crash or generate any errors in its
calculations. All that happens is that over time it consumes more and more memory.
Once again, the only way to avoid these issues is to take care with your pointers. You need to
make sure that you know where the values are allocated, and where they are released. There
should be reasons why you would the memory was allocated, and reasons why it is being
released.
10
1312ffd4
Variable
(p)
The Heap
10
9123691
Variable
(p) No code has access
to this memory
810273 anymore! It can
never be freed!
The Heap
Allocate some memory, and point p at it
Figure 8.17: If you forget a piece of allocated memory, it can never be freed!
Note
Here are some tips to help you avoid memory leaks:
• Have a clear idea of where memory is allocated, and where it is freed
• Think about the pointer values in local variables at the end of each function and
procedure. Do any of these values refer to something that no other pointer does? ♠
When the function or procedure ends, the variable’s value will be lost. If it is the
only thing referring to some allocated memory then that memory can no longer be
freed, and you have a memory leak.
594
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
The next error occurs when you are overly zealous about releasing memory. You must not
release memory before you are finished with it. The problem occurs when you continue to
access a value, after its memory has been released. This is one of the most difficult problems
to locate, as it will not cause any problems initially.
Take Figure 8.18 as an example. This demonstrates a case where two pointers refer to one
value. It is possible to free that value via one pointer, and then forget that the second refers
to the same location. When you read the value from
later, it is likely to still be , so the
program will continue to run as normal. The issue will only appear later when something else
is allocated to use that piece of memory. All of a sudden the value you thought was allocated
to
is now changing apparently on its own. Worst of all, the actual cause of the bug could
be hundred of lines of code away from where the problem appears. This is what makes this
kind of error very difficult to find.
The solution, once again, is to take care with pointers.
Memory was
1312ffd4 freed via p1
Variable
(p1)
10
1312ffd4
Variable
(p2) The Heap
Free memory at p1
1312ffd4 Memory is no
Variable Nothing!! longer allocated!
(p1)
10
1312ffd4
Variable
(p2) The Heap
Figure 8.18: You can still read values from memory even when they are unallocated...
Note
Here are some tips to help you avoid accessing released memory:
• When you free memory, spend some time thinking about the things that could be ♠
referring to the value you just released.
595
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Pointers and dynamic memory allocation make it possible to store values in new and interesting
ways. One way of structuring this data is to dynamically allocate each value, and link these
together using pointers. An illustration of this is shown in Figure 8.19.
Linked lists have the advantage of being very fast to perform insert and delete actions, when
compared with arrays. The disadvantage is an increase in storage size to keep all the pointers,
and the fact you must loop through the nodes to access any value in the list.
... Nothing!!
...
Next = 0x00
Next = 0x10
Node
Node
Node
Each Node stores its data ...
and a pointer to the
next Node in the list Next = 0x1f
Node
Note
• A Linked List is a term given to a certain way data can be structured in memory.
• A Linked List has Nodes, the equivalent of the elements of an array.
• Each Node, has some data and a pointer to the Next element in the list.
• The Last element in the list has Nothing as its next node.
• To access a Node in the list you must loop through from the first node until you reach
the node you are after.
• You can insert and delete elements by changing the links in the list. ♠
• If the grey node in Figure 8.19 is being inserted then the previous node must be
adjusted to point to it, and it to point to the next element of the list.
• If the grey node in Figure 8.19 is being deleted then the previous node changes its
link to skip that node and point to the next node in the list.
• The pseudocode in Listing 8.1 shows the standard way of applying an action to each
node of a Linked List.
596
8.1. DYNAMIC MEMORY ALLOCATION CONCEPTS
Pseudocode
597
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
This chapter has introduced a number of concepts related to working with pointers and per-
forming dynamic memory allocation.
Term
Is a way of organising
data using Node that
Linked List store the data along
with a pointer to
the next value
Term
Heap
Figure 8.20: Memory management focuses on allocating memory, releasing this allocation, pointers,
and the heap
Note
• Heap - an area of memory you can be allocated to store values.
• Allocate Memory - gives you ownership of a piece of the heap’s memory.
• Release Memory - once you own the memory it is yours until it is released. If you
♠
forget to release it, it cannot be used by others.
• Pointers - are values that point to locations in memory. They store the address of
the area of memory they refer to, and are needed to give you access to the heap.
598
8.2. USING DYNAMIC MEMORY ALLOCATION
Dynamic memory allocation makes it possible for you to allocate additional space for your
program to use from the Heap. We are going to look at two different examples of how to use
dynamic memory allocation, both of which extend the Small DB program created in Chapter 7.
The first version will use a dynamically allocated array to allow the program to store a variable
number of rows. Whereas, the second example will dynamically store each row, and link them
together in memory.
Table 8.1 contains the extended description of the Small DB program that will be explored in
this chapter. The main change is that in Chapter 7 the program only read in a fixed number of
values. In this version the program will be able to respond to the user wanting to add or delete
data stored in the program. In effect the program will store a variable number of elements,
with elements being added and removed by the user.
Program Description
Name Small DB 2
Description Stores a number of values for the user. These values can be
text (up to 7 characters), a whole number, or a real number.
Each value entered is stored in a row with a unique identi-
fier that will be assigned by the system. The first value will
be assigned the id 0, the second will be assigned the id 1,
and so on.
The program will show the user a menu, and allow them
to add new data to the program, print the data in the pro-
gram, delete data from the program, or quit.
Add: will read a value from the user and store it within the
program. This data will be allocated a sequential id.
Print: will print all of the values from the program, along
with their types.
Delete: this will ask the user to enter the id of the data
they want to delete, and then search for this data in the
program. If a row exists with this id, it is removed from the
program.
As before, the process to design and implement this program will follow a number of steps:
1. Analyse the problem (understand it and associated tasks).
2. Design the solution, its artefacts and control flow.
3. Implement the design in code.
4. Test the solution, compiling and running it to check it works as required.
599
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
The first task in any software development is to understand, as fully as you can, the require-
ments of the program, and the associated tasks and data. As this is an extension of the
Small DB program from Chapter 7 most of that analysis has already been done. A number of
tasks and data types were identified in the process of Understanding Small DB, and Choosing
Artefacts for Small DB.
To successfully implement these new features you must first think about what is required of
the new software. Then you can move on to think about how you can achieve these goals in
your code.
As identified above, the new goal is to allow the user to enter a variable number of values. They
need to be able to add and remove data as they wish. To achieve this a menu will need to be
added that allows them to choose the action they want to perform next. From the menu the
user will be able to choose to add, print, or delete data or to quit the program. These tasks
give us hints about the kinds of functions and procedures we can add to achieve this.
As well as thinking about additional tasks, you should also see if there is additional data.
Read over the description and see if you can identify any additional data that the user may
need to either enter into the program, or get out of it.
At first glance there may not appear to be any new data needed by this program. After all it
is still allowing the user to enter the same values that it did in Chapter 7. There is, however,
one additional kind of data that is hinted at in the description. There will be data associated
with the menu. The program is likely to need to work with values associated with the options
the user will be selecting. This can be modelled in the code, making it a better reflect the the
concepts associated with the program.
8.2.3 The Design Phase: Choosing artefacts and designing control flow
Once you have understood what is required, you need to set about designing the solution.
This involves choosing the artefacts to create and use, and designing the control flow within
the functions and procedures you create. This is all about making decisions, how will you
structure this functionality? What control flow will enable this behaviour? The many decisions
you make will define the overall design of the software.
This program already has an existing design, that needs to be extended. The data is described
in the Data Dictionary in Table 7.2. An overview of the functions and procedure of the solution
was shown in the structure chart in Figure 7.19. These are a good starting point, and for the
most part will require no changes. The new additions will build on top of these.
Modelling the data should always be high on your priority list, so the first task can be to think
about how the menu options can be modelled. The user needs to be able to select from add,
print, delete, and quit. At later stages there may be more options, but at this point that is
the list.
If you think back to Chapter 7, there are only three kinds of type you can use to model the
data associated with a program: records, unions, and enumerations. These are the tools
that are available to you to model your data. A record has a number of values one for each
field, a union has one value with the type based on the field it was stored in, a enumeration
represents a list of options.
An enumeration is the obvious choice for modelling the list of options the user can choose
from the menu. We can create a %
'
type that has the values ,, (*!&, ,,
$, ,, and )-!,.
600
8.2. USING DYNAMIC MEMORY ALLOCATION
One of the first processes that needs to be designed is the process to * to the data
stored in the program. This can use the * * function that already exists to get the data
from the user, so its focus is on allocating additional space for the row and determining the
row’s id.
A review of the code in the current Small DB program indicates that the row’s index and its
id were the same value, and %
was taking advantage of this. When %
called * *, it
passed in as the for the new row. In effect, the value in was being used as the index that
looped over the elements of the array as it was being populated, and it was keeping track of the
value for the newly created rows. This is no longer going to be the case as the user can now
add and delete rows. When they delete a row the index and the id will no longer linked, so one
variable cannot track both values. A & * ! value needs to be kept somewhere.
The & * ! and the * data are associated. These values can be modelled as a single
+ record, with each + having fields for the & * ! and *. This will
keep the relevant information together, and allow the code to work with these values as a
group.
• & * ! will be an integer, it will be assigned the value 0 at the start and have its
value incremented each time a row is added.
• * will be a dynamically allocated array of * values.
C++
In C, another issue that needs to be resolved is the fact that there will now be a variable
number of rows in the program. The number of rows will also need to be recorded, and
maintained as rows are added and deleted. A *
value can also be added to the
+ record.
♢
77 ,
7
,
7
Pascal
Pascal has built in support for dynamic arrays. This means that it keeps track of the *
for you. The number of rows in a + value can be determined by using the
$
function with the +’s * field.
+ ♡
&*! !
,
* * ,
Table 8.2 shows the new data dictionary for Small DB 2. This includes the addition of the %
'
enumeration and the + record.
The next step is to choose the functions and procedures that need to be created or used to
implement this program. Once again, this can build on the structure implemented in Small
DB, as shown in Figure 7.19. This included the code needed to read a row from the user, and
to output the row to the Terminal.
601
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Data Details
* The record/struct from Table 7.2 that stores the row’s , ,
and
.
. The union from Table 7.2 that stores either an integer, double,
or text value.
Main
ion
opt
data store (by ref)
da
ta
f)
st
re
or
y
(b
e
(b
e
or
y
ta
nst
da
re
f)
next id
row
row
index
row id
602
8.2. USING DYNAMIC MEMORY ALLOCATION
Small DB 2 needs to add some additional functionality to this program. The following list
shows the tasks that need to be coded, and the functions or procedures that will code their
behaviour. This is shown in the Structure Chart in Figure 8.21.
• Show the menu to the user, and get the option they want to perform ( %
'
function).
• Add a row to the data managed in the program ( * procedure).
• Print all of the rows ((
* procedure).
• Delete a row from the data managed by the program ( * procedure).
In Small DB the logic for (
* was coded into %
. This logic can be moved from
there into its own procedure. The control flow for the other functions and procedures will need
to be designed.
The code for %
'
should be fairly simple. The basic actions it needs to perform
will be:
1. Output the text showing the list of options to the Terminal.
2. Read a number from the user, making sure it is in the range of the list of options (1 to 4).
3. Return the value of the option selected as a %
'
value.
The first part of this process will involve a sequence of output commands, displaying the
different text to the Terminal. The code to read a number from the user will need a standard
validation loop, repeatedly asking them to enter a number until they enter one between 1 and
4. The final part can use a Case Statement to return the correct result from the function.
The process for adding a row will involve the following steps, as shown in Listing 8.2:
1. Record the next row id, and then increase the & * ! in the +.
2. Increase the memory allocated to the +’s * (and the Row Count, in C), and
store the * read from the user into this newly allocated memory.
Pseudocode
603
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Deleting an element out of an array is a common task, but one that will require you to perform
all of the hard work. Remember that arrays are contiguous blocks of memory, so technically
you cannot delete an element from the middle of this array. You can only remove the last
element. There are three options for how this can be achieved, as shown in Figure 8.22. All
of the options involve moving data, and then resizing the dynamically allocated array to have
one fewer element than before. The different options involve copying different pieces of data
to free the last slot so that its allocation can be released.
1. Only copy the last element over the element to be deleted. This is the fastest, but the
order of the elements is not preserved. If this is important then you cannot use this
approach.
2. The second option is to copy the value of each element in the array back over the previous
element. This maintains the order of the elements, but takes more time as you have to
copy all of the values after the element being deleted back one spot.
3. A faster option is to take advantage of the fact the array is stored as a contiguous block,
and to perform a bulk move/copy of the memory past the element. In effect, you can
copy all of the elements with one request and take advantage of the hardware which is
optimised for this kind of task.
Element 3 Element 4
My Array: Element 1 Element 3 Element 4 Element 4
604
8.2. USING DYNAMIC MEMORY ALLOCATION
Figure 8.23 shows the flowchart of the process for deleting a node from the * array using
Option 2. This option has been chosen as it helps demonstrate the use of the elements of the
array, as well as working with the dynamic memory.
The implementation of this option also demonstrates a frequently seen pattern when working
with two consecutive elements of an array. In this case one element is being copied over
another, but many algorithms will require you to work with two elements at a time. Each time
through the loop, this code will access the 𝑖𝑡ℎ element and its neighbour, the (𝑖 + 1)𝑡ℎ element.2
This means the loop needs to go from a starting element, to the second last element of the
array. If looped to the last element of the array then would attempt to access an element
past the end of the array.
Delete a Row
End
Figure 8.23: Flowchart describing the process for deleting a row with a given id
2 An alternative version of this is to start 1 element past the first element you want to interact with, and use the 𝑖𝑡ℎ
605
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
The !
* ! function will search a +’s * for the index of the * with
the ! it is searching for. This is used by the & procedure so that it can find the
index of the row it needs to delete.
This is implemented using a standard search pattern. This pattern involves looping over all of
the elements in the array, and for each element checking ‘Is this the element I am after?’. When
a match is found the search can end, as can the function. This can be implemented using the
appropriate Exit statement for the language, with the function returning the index of the row
it found, in this case. However, if the loop gets to the end of the array without finding a match,
then there is no element in the array that matches the search and the function can return a
value that indicates no match was found, in this case the index is returned as this cannot
be a valid index. The flowchart illustrating these steps is shown in Figure 8.24.
Index of Row
with Id
End
Figure 8.24: Flowchart describing the process for finding the index of a row with a given id
%
is the last remaining procedure. The implementation of this will require you to declare
a + variable that will be manipulated by the other procedures previously discussed.
This will need to be initialised with no elements in its *, and other a & * ! of 0.
The control flow of Main will involve a Post-Test Loop that will repeat code until the user chooses
to quit. Within the loop %
can get the option the user wants to perform by calling the
%
'
function, can then use a Case Statement to run either the * procedure,
the (
* procedure, or the * procedure.
606
8.2. USING DYNAMIC MEMORY ALLOCATION
The following two sections, Section 8.3 Dynamic Memory Allocation in C and Section 8.4 Dy-
namic Memory Allocation in Pascal, contain a description of the syntax needed to code dynamic
memory allocation in the C and Pascal programming languages. Use this information to write
the code for Small DB 2, and other programs.
Whenever you work with dynamic memory allocation, you need to spend a good proportion of
your time checking that your solution is working. This is now an interactive program, so you
can test multiple things each execution. The following are some of the aspects that you should
test in this program:
• Test the basic functionality:
– Can you add new rows?
– Can you delete a row?
– Can you print the rows?
– Are you able to quit the program?
• Test for potential issues related to memory allocation:
– Try deleting the first row, the last row, and a non-existent row.
– Delete all of the rows.
– Print when there are no rows.
– Delete and then add, delete all rows then add, etc.
Think about the places where you may have made a mistake, and test to check that you can
not cause the program to crash.
Note
There is a bug in the current design, as presented in this chapter. If you run these tests
you should be able to find the bug, which has the potential to cause the program to crash.
♠
See if you can locate the bug, correct it, and implement the required fix. Like most bugs
the fix only requires a small change, so think carefully about what is required.
607
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Arrays are only one way of dynamically allocating space for a program. In an array the elements
are allocated in a contiguous block, each element next to the previous one. This structure is
good when you want to access an element based on its position, but operations like delete and
insert can be tricky as you need to move elements around to make or remove space.
An alternative to the array, is to dynamically allocate space for each value individually, and to
use pointers to record their locations. The general structure is called a Linked List, and we
can use this to manage the *s in the linked version of the Small DB 2 program.
Figure 8.25 shows the difference between how the rows are stored in the previous array ver-
sion of Small DB 2, and the linked version we will now explore. In the array version, each
* is stored next to the previous one in an array. With this version you can use an index
value to access the middle elements of the array quickly, but it is slower to delete or insert
elements.
The linked version of Small DB 2 is made up of nodes (the *s) that each store the data and
a link (pointer) to the
node in the list. In this version the *s are not stored next to each
other, so you cannot use an index to calculate the position of any one element. Instead you
need to start at the first element, and work your way through the list one element at a time
using the
pointer to move from the current node to the next node of the list. Inserting or
deleting elements of the list can be much faster as the links can be adjusted to introduce new
elements, or remove existing one from the list.
... Nothing!!
...
Next = 0x00
Next = 0x10
Row
Row
Row
Figure 8.25: Illustration of memory layout for Array and Linked versions of Small DB 2
608
8.2. USING DYNAMIC MEMORY ALLOCATION
The linked version of the Small DB 2 program is an alternative implementation for the same
program developed in Section 8.2.1. This means that the information from the analysis phase
is still valid, and can be used to inform what must be done in this program. Similarly, the
testing strategies developed will also be valid so when the design and implementation are
complete you can test it in the same way as the previous program.
The parts that do need to change will be the design and implementation. The design needs
to structure the data differently, and this will impact on the structure of the code as well.
The first step, therefore, is to design the new structure for the data and then to use this to
determine the new structure for the code.
Table 8.3 shows the new data dictionary for the linked version of the Small DB 2 program.
Most of the changes relate to the + record. This used to store all of the rows in a
dynamically allocated array. Now, in the linked version, the + includes two pointers:
one pointing to the first *, the other pointing to the last *. Only the first of these two is
actually required, but the pointer to the last * will make some tasks easier.
The * pointer, points to the first * value allocated on the heap. Tasks like (
* will use this pointer to start looping through the *s. The $ * pointer exists to
make it easier to add new *s to the +. New *s are added to the end of the list,
and the $ * pointer means you can get to the end of the list without first having to loop
through each node.
Data Details
* The record/struct from Table 7.2 that stores the row’s , ,
and
. This now also has an additional field to point to the
location of the next *
& A pointer to the next *.
. The union from Table 7.2 that stores either an integer, double,
or text value.
%
'
An enumeration from Table 8.2 with options for adding a row,
printing all rows, deleting a row, or quitting the program.
One tricky aspect of the linked *s, is that the * must include a pointer to a *. In most
cases the compiler requires that the thing you are using is declared before its use. Here that
is not possible, the declaration of the row must include the point to the row which is still being
declared. Each language caters for this in its own way, the tricks for doing this in C are shown
in Figure 8.26, the Pascal version is shown in Figure 8.27.
609
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
C++
The following code shows how the new + and * structures can be implemented
in C. The one trick here is that you must use the name of the * when declaring
the
field. This is because C has not yet encountered the type name for the *, so
you need to use its alternate name.
, *
.
7
7
7
♢
7
,
*
,
77 ,
7
7
7
Figure 8.26: C code for declaring the *, with a next pointer
Pascal
The following code shows how the new + and * structures can be implemented
in Pascal. The trick here is to declare an alias for the *( (a pointer to a Row) before
the * declaration, but in the same type declaration part.
(
*
*( 6*
,
+
*! !
,
* 6*
* 6*
Figure 8.27: Pascal code for declaring the *, with a next pointer
610
8.2. USING DYNAMIC MEMORY ALLOCATION
The overall structure for Small DB 2 will not change much, as the basic actions the program
needs to complete remain the same. The only real change is that the !
* !
function is no longer required, as indexes no longer serve as a means of accessing the * values
in the +. The updated version of the Structure Chart is shown in Figure 8.28.
Main
op tion
da
f)
ta
re
by
st
or
(
e
e
Get Menu Option or
(b
st
y
ta
re
da
f)
Delete a Row Add a Row Print All Rows
next id
index
row
Read Row Print Row
611
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
The first activity that can be examined in detail is the * procedure. This will need to
create a new * value, and have it added to the end of the list. To start with, let us have a
look at how this should work conceptually.
Figure 8.29 shows an illustration of the add process for the first row. At the start the code
has a single + value, this will be from within the %
procedure. When the
program start the data store will need to have its * and $ * fields initialised to
point to Nothing. This indicates that there is no first row, or last row in the + at this
stage.
When a new Row is added the first step is to allocate space for it on the heap, and then to read
the user’s input into that space (using * *). As this * will be added to the end of the
+, its & field can be set to Nothing to indicate that there are no more * values
after this one.
Figure 8.29: The first Row becomes the start and end of the List
The code for * now needs to link this new * into those already in the +.
This is where it checks to see if there is a * value currently referred to be the of the
+ value. As this refers to Nothing at this point, the code takes a branch that sets the
and the both to refer to the newly created * value. At this point, the new
* is both the first and the last row in the +
612
8.2. USING DYNAMIC MEMORY ALLOCATION
Most the time when you add a new row it will not be the first one in the list. Typically, you will
need to add the row to the existing rows in memory. This involves updating the current
so that its
points to the newly created row, and then you can change the +’s
to point to it as well. This is shown in Figure 8.30, with the whole pseudocode shown
in Listing 8.3.
first row:
last row: The new Row is going to
be the last row, so its
Data Store Next is set to Nothing
when it is created
...
Next = 0x10 Nothing!!
Row ...
Next = 0x10 Nothing!!
Row
first row:
The last row is changed to
last row: point to the newly created row
Data Store
...
Next = 0x1f
Row
...
Next = 0x10 Nothing!!
Row
The old "last row" must have
its next set to point to
the newly created row
Figure 8.30: When a new row is added, it becomes the new last row, and the old last node points to it
613
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Pseudocode
Note
• Step 3 of Listing 8.3 allocates space on the heap for the row data, and stores a pointer
to it in & *.
• Step 6 checks if this is the first * in the +. ♠
• Step 9 reads ’s $ * pointer, then follows it to the *, so that it can store
a value in that *’s & field.
614
8.2. USING DYNAMIC MEMORY ALLOCATION
The code in * will enable you to create a list of any length. Each row is linked in by
changing the old to point to the newly created row, and then the of the
+ is updated. This is all very nice, but now that you have the data within the program
how do you use it?
As with an array, the think that you need to determine is how to perform some action for each
node in the list. There is no index that you can use to access the Nodes, so the standard For
Loop is not going to be of assistance. Instead, what you need to do is to iterate through the
list by following the
pointers in each *.
The standard pseudocode for looping through each node in a list is shown in Listing 8.1. The
main idea is that you can have a
node that you are processing. Then, to get to the
next node you follow
pointer and read the
field. The result is then a pointer to the
next node in the list and can be stored as the
node. This process can then be repeated
while
. This process is shown in Figure 8.31.
first row:
last row:
Data Store
...
Next = 0x1f
Row
...
Next = 0x10 Nothing!!
Row
Current = 0x3d
Current is a pointer to the
"current" Row to be printed,
you follow this pointer to
read the value that is to be
printed to the Terminal
first row:
last row:
Data Store
...
Next = 0x10 Nothing!!
Row
Current = 0x3d
Figure 8.31: When a new row is added, it becomes the new last row, and the old last node points to it
615
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Pseudocode
C++
Pascal
616
8.2. USING DYNAMIC MEMORY ALLOCATION
Deleting a row in the linked version of Small DB 2 will perform much faster than the equivalent
array version, as it does not need to copy the array elements. Instead, the deletion of a *
is just a matter of adjusting the links so that the row is no longer included. Though, while it
may be faster it will require more thinking and testing as it requires some careful work with
pointers.
Figure 8.32 shows an illustration of the actions that need to be coded into the *
procedure. This code will need to locate the Row to delete, the previous Row, as well as the
next Row. When these are located the delete code can change the previous row’s
field to
be a pointer to the Row that follows the row that is being deleted. With this done the Row has
been removed but is still consuming memory. So the last step of this procedure will need to
release that memory as it is no longer needed.
The code in Listing 8.7 shows the C code for this process, while the code in Listing 8.8 shows
the matching Pascal code. One key thing to notice is the tracking of the * pointer along
with the
. Effectively this is a standard ‘for each node’ loop, like that used in Printing
all rows in the linked version of Small DB 2. In this case, the pointer remembers the last
value of
each time through the loop. This ensures that it will have a pointer to the
previous Row when the desired Row is found.
Note
This illustration, and the matching code, only works for nodes in the middle of the list.
To fully implement the required functionality you will need to add in a few additional
branches that test for the following conditions:
• Was a matching Row found? If there is no match then
will point to Nothing,
and reading
’s
will cause the program to crash.
• If the Row is the fist row in the list there will be no previous Row, so will point
to Nothing. Setting ’s
will cause the program to crash. ♠
• Similarly, if the Row is the last row in the list then
will be Nothing. This will
not cause the program to crash, but will give you errors when you try to add a new
node.
See if you can work out the required logic to address these issues, and implement the full
version of this procedure.
This concludes the design for the linked version of Small DB 2. As you have done in the past
you will need to work out how to code this using the syntax diagrams and examples from hhe
following two sections: Section 8.3 Dynamic Memory Allocation in C and Section 8.4 Dynamic
Memory Allocation in Pascal.
During the implementation process you should also be testing your solution. With pointers,
as with anything, it is best to write a little and then test it. Use the same testing strategy as
discussed in The Testing Phase: Compiling and running Small DB 2. This should help you
locate any memory issues with this code.
Note
As this code requires more work with pointers you are likely to have more issues. You
should expect your program to crash a few times as you work through these, so do not
worry if this does happen. The best way to work through these issues is with a piece of ♠
paper and a pencil. Use this to draw up the different * values and their pointers. Then
work through the actions yourself on paper.
617
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
first row:
last row:
Linked List
... Nothing!!
...
Next = 0x00
Next = 0x10
Row
Row
This is the
next row... ...
Next = 0x13
...
Next = 0x23
Row
Row
This is the previous row...
its "next" must be changed ...
to skip the row... Next = 0x1f
Row
first row:
last row:
Linked List
... Nothing!!
...
Next = 0x00
Next = 0x10
Row
Row
...
Next = 0x13
...
Next = 0x23
Row
Row
The "next" now points to
the row that followed the row ...
that was deleted... Next = 0x1f
Row
The row's memory
has been released...
Figure 8.32: When a new row is added, it becomes the new last row, and the old last node points to it
618
8.2. USING DYNAMIC MEMORY ALLOCATION
C++
Pascal
619
8.3. DYNAMIC MEMORY ALLOCATION IN C
Section 8.2, Using Dynamic Memory Allocation, introduced a version of the Small DB program
with a dynamic array structure, as opposed to the fixed array structure used to manage the
rows in Chapter 7. The C code for the altered functions and procedures is shown in Listing 8.9,
the original version can be found in Listing 7.1.
(
,
*
77 ,
7
,
7
(
7
7
7
+
(
7
7
7 7
621
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
7,
(*!&,7,
$,7,
*
)-!,
)-!,
7 7
77
7
77
622
8.3. DYNAMIC MEMORY ALLOCATION IN C
*
7 7
7 7 7 7
623
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
%
7
7 7 &-$$
7
7
7,
7 7 7
$,7,
7 7 7
(*!&,7,
7 7 7
)-!,
4
*
)-!,
Listing 8.9: C code for the dynamic array version of Small DB, see Listing 7.1 for the original version of
this program
Note
• This version of the Small DB program includes the ability to add, delete, and print
rows from the data store.
♠
• The data store includes a dynamic array that is managed using realloc.
• See Section 8.2 for a discussion of how this works.
624
8.3. DYNAMIC MEMORY ALLOCATION IN C
Section 8.2, Using Dynamic Memory Allocation, introduced a version of the Small DB pro-
gram with a linked structure, as opposed to the array structure used to manage the rows in
Chapter 7. The C code for the altered functions and procedures is shown in Listing 8.10, the
original version can be found in Listing 7.1.
(
,
*
,
77 ,
7
7
7
(
7
7
7
+
(
625
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
7 7
77
7
77
&-$$
626
8.3. DYNAMIC MEMORY ALLOCATION IN C
*
&-$$ /
7
(
,
%
7
7 7 &-$$ &-$$
Note
•
, , and are the only procedures that have changed
significantly.
• Each of these is explained in more detail in Section 8.2. ♠
• Each row has a pointer to the next row in the database, this will point to nothing in
the last row.
627
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
In C you can declare pointer variables. This includes Local Variables, Global Variables, and
Parameters.
3 5
expr list
array declaration
constant expression
{ expression list }
*
Note
• This code allows you to declare your own Pointer variables in C.
• For variable declarations, the main aspect to pay attention to is the . This indicates
♠
that the variable is a pointer.
• See Listing 8.11 for example variable declarations.
C does not have built in support for Pass by Reference. Instead, in C you must pass a Pointer
to the variable you want passed to the function or procedure. Listing 8.11 shows an examples
of procedures that accept pointers variables.
Note
• A pointer can be used to point to any value.
• Also see: Section 4.3.8 C Procedure Call (with pass by reference), and Section 4.3.7 ♠
C++ Reference Parameters.
628
8.3. DYNAMIC MEMORY ALLOCATION IN C
C++
*
♢
35
7
7
7
7
3 5
Listing 8.11: C code with pointer variables
629
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
C provides a number of pointer operators that allow you to get and use pointers.
You can get a pointer to a value using the ampersand operator (&). This operator lets you get
the address of a variable, field, etc.
C++
7
*
7
7
7
7
7
7
4
7
4
7 35 7 3 5
7
4
7 7
4
7 7
Listing 8.12: C code showing pointer operator usage
Note
• The address of operator gets a pointer to the value in the expression that follows it.
• Dereference means ‘follow the pointer, and read what it points to’.
• Use the asterisks () to dereference the pointer and get the value it points to.
• You can use to dereference a pointer to a structure value, and then to read one of ♠
the fields from within the structure.
• Listing 8.12 shows how you can get addresses of different variables, and how you
can access the value pointed to using and .
630
8.3. DYNAMIC MEMORY ALLOCATION IN C
In C you can declare custom types that make use of pointers. This includes alias types, structs,
and unions.
const
Figure 8.34: C++ Syntax for array and alias type declarations with pointers
Note
• This is the C syntax to for custom alias type that include Pointers.
• The main difference is the inclusion of the in the direct type declaration. This
indicates that the custom type can alias pointer types. This would allow you to
*
declare a type such as
that is a pointer to a person.
• The inner type declaration allows you to have array of pointers, and pointers to arrays. ♠
In these cases you use the brackets to indicate if you want to declare a pointer to
an array, or an array of pointers. See Listing 8.13 for an example of these type
declarations.
•
631
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
C++
♢
7
7
7
35 3 5 3
5 35
35 4
35
7 35 4
7 35 7 35
35 4
7 35
35
4
Listing 8.13: C code demonstrating type aliasing with pointers
632
8.3. DYNAMIC MEMORY ALLOCATION IN C
struct name
3 expression 5
C++
*
7
&-$$
7
Listing 8.14: C code with a struct that contains a pointer
633
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
union name
3 expression 5
C++
*
7
7
7
7
7
♢
Listing 8.15: C code with a union that contains pointer fields
634
8.3. DYNAMIC MEMORY ALLOCATION IN C
malloc
is the standard memory allocation function. You tell it how much space you want, and
it allocates you that many bytes on the heap. This is a function, that returns a pointer to the
space allocated.
Function Prototype
Returns
A pointer to the allocated space is returned.
Parameter Description
The number of bytes to allocate on the heap.
C++
*
7
Listing 8.16: Example calls to
Note
• is used for memory allocation.
• You need to include stdlib.h to use .
• allows you to allocate space on the heap. It returns a pointer to this space.
♠
• returns a pointer, you need to type cast this to the kind of pointer you
want, for example
casts it to an integer pointer.
• returns &-$$ if it fails to allocate memory.
635
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
calloc
The difference between and is that clears the memory allocation. When
you call you pass it a number and a size, and returns you a pointer to a block
of memory that is 𝑛𝑢𝑚𝑏𝑒𝑟 × 𝑠𝑖𝑧𝑒 bytes.
Function Prototype
Returns
A pointer to the allocated space is returned.
Parameter Description
The number of elements to allocate to the array.
C++
7
*
Listing 8.17: Example calls to
Note
• is used for getting a cleared memory allocation.
• You need to include stdlib.h to use .
• performs a similar task to malloc, with the addition of clearing the space
allocated. ♠
• After calling the memory you are allocated will have all of its bytes set to 0,
whereas with malloc the memory retains whatever value was there previously.
• returns &-$$ if it fails to allocate memory.
636
8.3. DYNAMIC MEMORY ALLOCATION IN C
realloc
Like and , allows you to allocate space from the heap. allows
you to allocate or change (reallocate) space on the heap.
Function Prototype
Returns
A pointer to the allocated space is returned.
Parameter Description
The pointer to reallocate space for on the heap.
C++
&-$$
*
♢
35
3 5 35
&-$$
Listing 8.18: Example calls to
Note
• allows you to reallocate memory for a pointer.
• You need to include stdlib.h to use .
• must be a &-$$, or a pointer to a memory block on the heap, i.e. space previously
allocated with malloc, calloc, or realloc. ♠
• returns &-$$ if it fails to allocate memory.
• may need to move the memory allocation, so you need to assign the result
to a pointer as it may differ from the value passed to the parameter.
637
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
free
When you allocate memory you are responsible for freeing that memory when you no longer
require it. The function allows you to do this.
Procedure Prototype
Parameter Description
The pointer to the space to free on the heap.
Note
• allows you to free the memory allocated to a pointer.
• You need to include stdlib.h to use .
• a pointer to a memory block on the heap, i.e. space previously allocated with
♠
malloc, calloc, or realloc.
• You can also pass a &-$$ value, in which case nothing occurs.
• It is good practice to assign a &-$$ value to the pointer after freeing it.
*
638
8.4. DYNAMIC MEMORY ALLOCATION IN PASCAL
Section 8.2, Using Dynamic Memory Allocation, introduced a version of the Small DB program
with a dynamic array structure, as opposed to the fixed array structure used to manage the
rows in Chapter 7. The Pascal code for the altered functions and procedures is shown in
Listing 8.19, the original version can be found in Listing 7.7.
+
+-
,
#
.
*
,
+
( *
*! !
,
*
+
(
639
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
7,
(*!&,7,
$,7,
)-!,
)-!,
+
+$
$
3 5 * * !
640
8.4. DYNAMIC MEMORY ALLOCATION IN PASCAL
+$
$
%
%
%
'
+
( *
*!
+$
%
'
7, *
$,7, *
(*!&,7, (
*
)-!, /$
''
)-!,
%
Listing 8.19: Pascal code for the dynamic array version of Small DB, see Listing 7.7 for the original
version of this program
Note
• This version of the Small DB program includes the ability to add, delete, and print
rows from the data store.
♠
• The data store includes a dynamic array.
• See Section 8.2 for a discussion of how this works.
641
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Section 8.2, Using Dynamic Memory Allocation, introduced a version of the Small DB program
with a linked structure, as opposed to the array structure used to manage the rows in Chap-
ter 7. The Pascal code for the altered functions and procedures is shown in Listing 8.20, the
original version can be found in Listing 7.7.
+
+-
%
'
#
.
,
+
*! !
,
* *(
* *(
642
8.4. DYNAMIC MEMORY ALLOCATION IN PASCAL
( *
*
,
*
+
6
643
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
%
%
%
'
+
*!
*
( *
*
%
Listing 8.20: Pascal code for the linked version of Small DB, see Listing 8.19 for the array version of
this program
Note
• (
, *, and * are the only procedures that have changed signifi-
cantly.
• Each of these is explained in more detail in Section 8.2.
• Each row has a pointer to the next row in the database, this will point to nothing in
♠
the last row.
• The + has a pointer to the first and last rows in the database.
• Adding and removing rows is done by changing the links between row values on the
heap.
644
8.4. DYNAMIC MEMORY ALLOCATION IN PASCAL
In Pascal you can declare pointer variables and types. Pointer variables can be used to declare
Local Variables and Global Variables, but cannot be used as Parameters. To pass a pointer to
a parameter you need to declare your own pointer type and use that.
Note
• This code allows you to declare your own Pointer variables in C.
• For variable declarations, the main aspect to pay attention to is the 6: this indicates
that the variable is a pointer.
♠
• See Listing 8.21 for example variable declarations.
• The variables in %
could be declared as 6!
or as !
(. It is good practice
to declare and use your own pointer types, so !
( is preferred.
Pascal
( *
!
( 6 !
%
!
!
(
3 5 6 !
35 ♡
3 5
(
!
(
(
!
(
(
!
(
(
!
(
3 5
%
Listing 8.21: Pascal code with pointer variables
645
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Pascal provides a number of pointer operators that allow you to get and use pointers.
You can get a pointer to a value using the at operator (@). This operator lets you get the address
of a variable, field, etc.
Pascal
(
+
(
( 6 (
%
7 +
(
( *
( 6 +
( (
(
( 7
7 ♡
/$
( 6
(
(
/$
( 6
(
(
/$
( 6 '' ( 6
%
Listing 8.22: Pascal code showing pointer operator usage
Note
• The address of operator gets a pointer to the value in the expression that follows it.
• Dereference means ‘follow the pointer, and read what it points to’.
• Use the caret (6) to dereference the pointer and get the value it points to. ♠
• Listing 8.22 shows how you can get addresses of different variables, and how you
can access the value pointed to using 6.
646
8.4. DYNAMIC MEMORY ALLOCATION IN PASCAL
In Pascal you can declare custom types that make use of pointers.
enum declaration
record declaration
pointer declaration
Figure 8.38: Pascal Syntax for array and alias type declarations with pointers
Pascal
( *
, !
(
!
( 6 !
%
!
!
(
( !
(
!
♡
(
/$
' ' ( 6
' 3' '5 ' 35
%
Listing 8.23: Pascal code demonstrating type aliasing with pointers
647
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
array spec.
3 ordinal type 5
field name
Pascal
&( 6&
&
!
&(
%
Listing 8.24: Pascal code with a struct that contains a pointer
648
8.4. DYNAMIC MEMORY ALLOCATION IN PASCAL
Pascal includes a number of memory allocation functions: New, Dispose, and Set Length.
New
In Pascal the & procedure allocates space for a pointer. The amount of memory allocated
is based on the size of the type referred to by the pointer, for example an Integer pointer is
allocated enough space to store one integer value.
Function Prototype
Parameter Description
The pointer to allocate the space for. After the call this
will point to the allocated memory.
Pascal
&
%
( *
6 !
&
%
Listing 8.25: Example calls to &
Note
• & is used for memory allocation.
♠
• & allows you to allocate space on the heap.
649
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Dispose
When you allocate memory you are responsible for freeing that memory when you no longer
require it. The procedure allows you to do this.
Procedure Prototype
Parameter Description
The pointer to the space to free on the heap.
Note
• allows you to free the memory allocated to a pointer.
• See Listing 8.26 for example code.
• is a pointer to a memory block on the heap, i.e. space previously allocated with
♠
New.
• You can also pass a
value, in which case nothing occurs.
• It is good practice to assign a
value to the pointer after freeing it.
( *
650
8.4. DYNAMIC MEMORY ALLOCATION IN PASCAL
Set Length
Pascal includes support for dynamic arrays. These are arrays where the contents is stored
on the heap, and can be dynamically resized during execution using the +$
proce-
dure.
Procedure Prototype
Parameter Description
The pointer to the space to free on the heap.
The new length for the array , preserving any existing
data up to the new length.
Pascal
%
+
+
( *
!
+$
$
+$
$
!
♡
3
5
+
* $
%
Listing 8.26: Example calls to +$
Note
• +$
allows you to set the length of a dynamic array.
• , $, and $
determine the valid indexes and length of the array.
♠
• Data for a dynamic array is allocated on the heap.
• Dynamic arrays are declared without specifying the indexes (just use ).
651
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
Read over the concepts in this chapter and answer the following questions:
1. What is the difference between the heap and the stack?
2. Why would you want to allocate space on the heap?
3. How can you allocate space on the heap?
4. Why do you need to free the space you are allocated? Why do you not need to do this
with values stored on the stack?
5. What is a pointer?
6. What can a pointer point to?
7. Why do you need pointers to make use of the heap?
8. Where can pointers be stored?
9. How can you get a pointer to an existing value?
10. What can you do with the pointer?
11. The pointer has a value, and points to a value. What is the value of the pointer? How is
this different to the value it points to?
12. What are the different ways you can allocate memory? Describe each, and explain what
they can be used for.
13. What additional issues are you likely to encounter when working with pointers? Explain
each, and how you plan to handle these issues.
652
8.5. EXERCISES FOR DYNAMIC MEMORY ALLOCATION
Use what you have learnt to read and understand the following code samples, and answer the
associated questions.
1. Read the code for the dynamic array version of Small DB 2 (for your language of choice)
and do the following:
(a) Draw a picture of an empty data store that shows what it looks like in memory.
(b) Draw a new picture showing how the data store will appear after one row is added.
(c) Draw a new picture showing how the data store will appear after three rows have
been added.
(d) Explain how the Add Row code is able to add rows to the data store.
(e) Explain how the Delete Row code is able to delete a row from the data store. Include
a drawing that illustrates the process.
(f) Explain the steps you would need to perform to add an Insert Row option for the
user.
2. Read the code for the linked version of Small DB 2 (for your language of choice) and do
the following:
(a) Draw a picture of an empty data store that shows what it looks like in memory.
(b) Draw a new picture showing how the data store will appear after one row is added.
(c) Draw a new picture showing how the data store will appear after three rows have
been added.
(d) Explain how the Add Row code is able to add rows to the data store.
(e) Explain how the Delete Row code is able to delete a row from the data store. Include
a drawing that illustrates the process.
(f) Explain the steps you would need to perform to add an Insert Row option for the
user.
653
CHAPTER 8. DYNAMIC MEMORY ALLOCATION
If you want to further your knowledge in this area you can try to answer the following questions.
The answers to these questions will require you to think harder, and possibly look at other
sources of information.
1. Try implementing an alternate approach to deleting a row from the array version of the
small db program.
2. Alter the * type in your small db program to have a variable number of column values
(rename).
3. Compare the dynamic array and linked versions of the Small DB 2 program. Discuss the
relative advantages and disadvantages of each approach.
4. Test the speed difference between the dynamic array and linked versions of the Small DB
2 program for the following operations:
(a) Adding rows (test with adding 10, 100, 1000, and 10000 rows)
(b) Inserting rows (test with inserting 10, 100, 1000, and 10000 rows)
(c) Deleting rows (deleting 10, 100, 1000, and 10000 rows)
654
Input and Output
9
ou are progressing well. You have already mastered most of the basics
of spell and potion craft, so now we can turn our attention to the
creation of scrolls. These magical devices will allow you to capture
the magical energies created in your spells, and store them to be retrieved at
a later time. Gather your parment and wand, now summon the energies for
your spell and . . .
Over the previous chapter you have leant to create programs that manipulate data. So far this
data has only existed within the program, with the values stored being lost when the program
terminates. If you want to be able to maintain these values between executions you need to
learn to save data to file. By saving the program’s data to file you can then load it back in
when the program is restarted.
This chapter will introduce the artefacts needed to save data from your program to file, and
to load that data from file. Using this you will be able to persist data, making it available to
future executions of the program.
When you have understood the material in this chapter you will be able to save and load data
from text and binary files.
655
CHAPTER 9. INPUT AND OUTPUT
Contents
9.1 Input and Output Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657
9.1.1 Persisting Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657
9.1.2 Interacting with Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 658
9.1.3 File Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
9.1.4 File Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660
9.1.5 Other Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661
9.2 Using Input and Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
9.2.1 Saving Data from Small DB . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
9.2.2 Loading Data for Small DB . . . . . . . . . . . . . . . . . . . . . . . . . . . 664
9.2.3 New Structure for Small DB . . . . . . . . . . . . . . . . . . . . . . . . . . . 665
9.2.4 Writing Code to Load and Save Data for Small DB . . . . . . . . . . . . . . 665
9.3 Input and Output in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
9.3.1 Implementing Small DB File IO in C . . . . . . . . . . . . . . . . . . . . . . 667
9.3.2 C File Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
9.3.3 C File Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671
9.4 Input and Output in Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677
9.4.1 Implementing Small DB File IO in C . . . . . . . . . . . . . . . . . . . . . . 677
9.4.2 Pascal Text Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
9.4.3 Pascal File Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680
9.5 Input and Output Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684
9.5.1 Concept Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684
9.5.2 Code Writing Questions: Applying what you have learnt . . . . . . . . . . . 684
9.5.3 Extension Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684
656
9.1. INPUT AND OUTPUT CONCEPTS
When a program is running it uses variables and dynamically allocated memory to store the
data it requires. These values exist within the memory allocated to the program when it was
started. When the program ends its allocated memory is released, and the values stored within
the program are lost. If values must be remembered between executions then this data must
be stored outside of the program. To achieve this you can save data from the program into
files that are stored on the computer’s hard drive or solid state drive (SSD).
Heap
Global Variables
Figure 9.1: When a program ends its data is gone, unless you save it to file
Note
• Data stored within a program is lost when the program ends.
• To remember data between executions it must be saved to file.
• The files are stored in a persistent way on a hard drive, or solid state drive. ♠
• Hard drives, and solid state drives, are as data storage devices to persist data needed
by programs on the computer.
657
CHAPTER 9. INPUT AND OUTPUT
Programming languages offer a number of functions and procedures that are used to interact
with files. These will allow you to save data to a file, and load data back from the file.
A cursor keeps
track of the current
location in the file...
Open
10010011 00000000
10010010 11100010
10100101 00110010
00110000 01100011
Write 00000000
00110000
11011100
01100011
Read
11001110 01100011
00110000 10100001
00111001 00000001
11100101 11111111
10101110 01001001
00101000 00001101
11111100 01100011 Read and write
operations work
Close at the cursors
location, moving the
cursor as they go
Figure 9.2: File operations include the ability to open, read, write, and close files
Note
• Programming languages will provide functions and procedures to:
– Open a file so you can interact with its contents.
– Read data from a file that has been opened to be read.
– Write data to a file that has been opened to be written to.
– Close a file that is currently open.
• Languages will also provide built in file types that are used with these functions and
♠
procedures.
• When you open a file you indicate if you want read and/or write access to its contents.
• Opening a file gives you access to a cursor that you can use to read data from the
file, or write data to the file.
• Standard usage will be to open the file, read/write data to the file, and then close
the file.
658
9.1. INPUT AND OUTPUT CONCEPTS
There are two main file formats that you can work with in your program: binary files and text
files. A text file stores its data as textual characters, whereas a binary file stores the values
directly in the file.
Character 'e'
01001000
01100101
01101100
Write as Text 01101100 Read as Text
01101111
00100000
00110001
Text data is the 00110010
Character '1'
same when written 00110111
to a text or a Character '2'
binary file...
Character '7'
Character 'H'
Other values Character 'e'
will differ...
01001000
01100101
01101100
Write as Binary 01101100 Read as Binary
01101111
01111111
Value 127
In a "binary" file the
values are stored
directly as the binary
values in the file
Note
• Figure 9.3 shows a binary and text file used to save the text ‘Hello’ and the integer
127.
• In the text file they are stored as the characters ‘H’, ‘e’, ‘l’, ‘l’, ‘o’, and ‘1’, ‘2’, and ‘7’
separated by a space.
♠
• In the binary file the characters are stored in the same way (as they are text), but the
integer is stored as the value 127 which if interpreted as text is a delete character.
• If you opened these files in a text editor you could read the values from the text file,
but you would see a strange character instead of the number 127 in the binary file.
659
CHAPTER 9. INPUT AND OUTPUT
When thinking about using using files, the one aspect that you need to spend the most time
on will be the organisation of the data in the file. You need to ensure that the data you save
includes sufficient information that it can be read back into the program at a later stage. Some
common strategies are to:
1. Write fixed size data blocks where possible.
2. Store meta data1 , such as the number or size of variable data blocks.
3. Alternatively, mark the end of variable sized or numbered data blocks with a sentinel
values.
How is this
structured?
01001000 01100101
01101100 01101100
Write 01101111 00100000 Read
00110001 00110010
00110111 10100011
01001000 01100101 01101100 01101100 01101111 00100000 00110001 00110010 00110111 10100011 01001000 01100101 01101100 01101100 ...
number
of row 1 row 2 row3 row ...
rows
01001000 01100101 01101100 01101100 01101111 00100000 00110001 00110010 00110111 10100011 01001000 01100101 01101100 01101100 ...
sentinel
row 1 row 2 row3 row ...
(end marker)
Figure 9.4: You need to structure data within the file to make it possible to read back successfully.
Note
• Figure 9.4 shows different ways of structuring a variable number of ‘row’ values
within a file.
• The row values are fixed size blocks, or use their own strategy to manage variable
length data.
• One version stores the number of elements in the data before storing the data itself. ♠
• An alternate strategy is to store a sentinel value at the end of the variable length
data.a
a There is an end of file marker that can also be used for this purpose.
660
9.1. INPUT AND OUTPUT CONCEPTS
The input/output operations are fairly standardised across different device types. Saving data
to a file is very similar to writing it to the Terminal or to a network. The skills you learn with
any one of these will be transferable to other devices.
01001000
01100101
01101100
Write 01101100 Read
01101111
Write Read
or to the Terminal
Write Read
Note
• The tasks you need to do to read and write data are similar, regardless of the desti-
nation device.
• Reading and writing to file is similar to reading and writing from the Terminal. ♠
• You can open connections to other machines, and read and write data across these
connections. Lookup details on sockets if you are interested in doing this.
661
CHAPTER 9. INPUT AND OUTPUT
Using File Input and Output it is now possible to load and save data. As an example we will
examine how you can go about saving and loading data in the small db program.
The Small DB2 program allows the user to enter a number of row values, with each row having
a single column that stores a data value (either an integer, text, or double value). At this stage
the program only keeps its data while it is executing, once it ends the data is gone. The first
step is therefore to save the data from the program into a file.
When thinking about saving data the first task is to try to determine how the data can be
saved so that it can later be read back into the program. The following information can help
us design the structure of the file saved from the program:
1. There are a variable number of rows.
2. Each row has a fixed size, when you know the kind of data it is storing.
In the array based version of the Small DB program the number of rows is stored in the
. Saving this data to file can be achieved by saving the number of rows before storing
the data from each row. This will mean that when the file is loaded the program can read the
number of rows, and use this information to create enough space for these in memory before
reading them from the file. Figure 9.6 shows an example of the file structure saved from the
program.
Each row saves its id, its "kind", and its data
2 In this chapter we will be saving data from the array based version of the Small DB program, though a similar
662
9.2. USING INPUT AND OUTPUT
The pseudocode in Listing 9.1 shows the steps that can be followed to save the data from a
data store into a file. Notice that the number of rows is being saved into the file, before the
row data. This will make it easier to load the file back into memory.
Pseudocode
( +
(
+
+
$
!
,
♣
+
!
/ ' & * !
/ ' *
/ *
'
Listing 9.1: Pseudocode for Save (for Small DB array version)
The + procedure calls a / * procedure to store each row in the file. The
pseudocode for this procedure is shown in Listing 9.2. This code saves the and
values
to the file, and then uses a Case Statement to ensure it saved the correct value from the ’s
data.
Pseudocode
663
CHAPTER 9. INPUT AND OUTPUT
Once you can save data the logical next step will be to load that data back into the program.
The file structure is set, so all that needs to be done is to determine the steps that need to be
taken in order to load that data back into memory.
The pseudocode for loading the data store file and reading an individual row from file are shown
in Listing 9.3 and Listing 9.4. Notice how these mirror the structure of the save procedures.
The $ procedure open the file, and then reads the & * ! value and *
. The
*
data is used to allocate space in memory for the data store’s rows, and to determine
how many row values to read from the file.
Pseudocode
( $
(
+
+
$
!
,
+ ♣
!
* ' & * !
* ' *
' *
' *
$ *
Listing 9.3: Pseudocode for Load (for Small DB array version)
Pseudocode
664
9.2. USING INPUT AND OUTPUT
Figure 9.7 shows the new structure chart for this version of the Small DB program. This shows
the new $ and + procedures. When the program starts %
will load the data from file,
and then loop through performing the add, delete, and print actions as the user desires. When
the user chooses to quit %
will save its + back into the file. In this way the changes
the user makes in the program will be persisted across executions.
Main
tion da
op ta
) st
or
ref e
dat
y (b
(b y
as
re co
o ns
st
tor
tr
f)
a ef
y re
at
e
Get Menu Option )
(by
d
con
stor
st r
Save
data
ef)
Load
output file,
Print All Rows
row
Delete a Row
row (by ref)
input file
Add a Row
Figure 9.7: The structure chart showing the functions and procedures in Small DB
Having completed the design for this version of the Small DB program, the next step is to
covert these ideas into code. The pseudocode shown in this section communicate the logic
that needs to be coded into the functions and procedures of the new version of the Small DB
program. The following two sections, Section 9.3 Input and Output in C and Section 9.4 Input
and Output in Pascal, contain a description of the tools needed to load and save data in the C
and Pascal programming languages.
The good approach for implementing these additions will be to write the code to save the data
to file first. Once you have this working you can run the program and check the file to see that
the data you added was successfully saved. When this is working correctly you can move on
to the code needed to read the values back from file.
Figure 9.8 shows the program running. Notice that that data remains the same even after
quitting and running the program again.
665
CHAPTER 9. INPUT AND OUTPUT
Figure 9.8: Running Small DB program twice, notice the data persists between executions
Figure 9.9: The contents of Small DB’s data file, from Figure 9.8
666
9.3. INPUT AND OUTPUT IN C
Section 9.2 presented an altered version of the Small DB program from Chapter 8. The changes
introduced four new procedures used to save the programs data to file, and to reload the data
from file. The new code is presented in Listing 9.5.
$
+
*
7
7
7
*
!&,7.$
*
4
7
7
,0,7.$
*
364
54
7 7
7
7
7 &-$$
+
7 7
667
CHAPTER 9. INPUT AND OUTPUT
7
!&,7.$
*
7 &-$$
+
4
7
77
4
7 7
668
9.3. INPUT AND OUTPUT IN C
%
7
7 7 &-$$
7
)-!,
7
Listing 9.5: New C code for the Small DB program with file loading and saving
*
Note
• The !$ type is used to refer to files that have been opened for the application. See
Section 9.3.2 C File Type. ♠
•
669
CHAPTER 9. INPUT AND OUTPUT
C includes a !$ type that is used to interact with files on the computer. This type includes
all of the information that C needs to read and write data to a file.
C++
3
5 /
7 35
7
!$
!$
Listing 9.6: Example use of the FILE type to read and write text data
Note
• The !$ type is used to read and write data from a file.
• You open the file using
.
• After the file has been opened you must remember to close it using .
• File based versions of
and
allow you to read and write data from the ♠
file.
• The IO code in C always works with !$ pointers, as a result all of your !$ variables
will be pointers.
670
9.3. INPUT AND OUTPUT IN C
There are a number of functions and procedures in the stdio.h header that will give you the
ability to read and write data from files.
Opening a file
Before you can interact with a file the first step will be to open the file. This is done with the
function. This function will return a FILE pointer you can then use to interact with the
file.
Function Prototype
Returns
!$ If successful this returns a pointer to the file stream
opened, otherwise it returns NULL.
Parameter Description
The name of the file to open. This can include a relative
or absolute path to the file.
*
exist.
Open the file for writing. This will create
a new file, or replace an existing file.
Open the file for appending data. This
will append data to an existing file, or cre-
ate a new file if it does not exist.
Open the file for reading, and writing.
The file must exist.
Open the file for writing, and reading.
This will create a new file, replacing any
existing files.
Open the file for appending, and reading.
This ensures that all write operations are
always performed at the end of the file.
Note
• Remember to check that
has returned you a valid pointer, if you get back NULL
then it failed to open the file.
♠
• For binary files you can append a to the mode. For example, to open a binary file
for reading you use the mode , to open for writing and reading you use .
671
CHAPTER 9. INPUT AND OUTPUT
Closing a file
Once you have opened a file it is important that you also close it. The function can be
used to close an opened file.
Function Prototype
Returns
Returns 0 when it is successfully closed.
Parameter Description
The file to close.
Note
• Make sure to close all opened files.
♠
• Remember to check all paths through your code.
You can use
to write data to a !$ that has been opened with write capabilities. This
works the same as
and
.
*
Function Prototype
Returns
The number of characters written to the
by
.
Parameter Description
The FILE to write the output into.
The text that is to be written to the file. This text may
contain format tags to include other values. This is
the same as
, see Figure 2.29 for the syntax of
the format tag.
Note
• This will write the data as text to the file.
♠
• The file must be opened with write permissions.
672
9.3. INPUT AND OUTPUT IN C
Reading text data from a file is similar to reading data from the Terminal or from a string. The
function works in the same way as
and
, but writes its data to a text
file.
Function Prototype
Returns
The number of values read by
.
Parameter Description
The file from which the input is read.
The variables into which the values will be read. There
must be at least as many variables as format tags in the
format specifier.
*
Note
• This will read text data from the file.
♠
• The file must be opened with read permissions.
C++
( 7
!$
7
7
673
CHAPTER 9. INPUT AND OUTPUT
The function allows you to write binary data to a file. This requires you to pass a pointer
to your data, as well as the size and number of elements you want written.
Function Prototype
!$
Returns
The number of elements written to the
by . If this does not equal the
parameter
it indicates an error occurred writing the data to the
file.
Parameter Description
A pointer to the data to be saved to the file.
Note
• The file must be opened with write permissions.
♠
• This will write the binary data to file from the values pointed to by the parameter.
C++
7
!$
35
Listing 9.8: Example code that writing an array of double values to a binary file.
674
9.3. INPUT AND OUTPUT IN C
To read back binary data you need to use . This reads back a block of data from the file,
and stores it in memory at a location indicated by a pointer.
Function Prototype
!$
Returns
The number of elements read from the
by
. If this does not equal the
parameter
it indicates an error occurred reading the data from
the file.
Parameter Description
A pointer to the location to store the loaded data. This
must be large enough to store the values loaded.
*
Note
• The file must be opened with read permissions.
♠
• You must ensure that points to sufficient space to load the data into.
675
CHAPTER 9. INPUT AND OUTPUT
C++
!$
Listing 9.9: Example code that reads an array of double values from a binary file.
676
9.4. INPUT AND OUTPUT IN PASCAL
Section 9.2 presented an altered version of the Small DB program from Chapter 8. The changes
introduced four new procedures used to save the programs data to file, and to reload the data
from file. The new code is presented in Listing 9.5.
$
+
*
* $
$ $
( *
$
!&,7.$ * $
$
.
,0,7.$ * $
$ .
$
.
677
CHAPTER 9. INPUT AND OUTPUT
+
!&,7.$ /$
+
.
,0,7.$ /$
+ .
/$
''
%
%
'
+
*!
+$
$ ' '
%
Listing 9.10: New Pascal code for the Small DB program with file loading and saving
678
9.4. INPUT AND OUTPUT IN PASCAL
Pascal includes and , types that are used to interact with files on the computer. The
type is used for binary files, the , type is used for text files.
Pascal
%
+
' / '
% +
!
. !
,
' '
*
/$
/$
( *
%
Listing 9.11: Example use of the Text type to read and write text data
Note
• The , type is used to read and write text data from a file.
• You open the file for reading using
then *, to write use
then
*.
♠
• After the file has been opened you must remember to close it using .
• File based versions of /$
and * $
allow you to read and write text data from
the file.
679
CHAPTER 9. INPUT AND OUTPUT
There are a number of functions and procedures in Pascal that will give you the ability to read
and write data from files.
Assigning a filename
Before you can interact with a file the first step will be to assign a filename to the , vari-
able.
Procedure Prototype
Parameter Description
. The file variable to have its filename set
The * procedure is used to reset the file cursor to the start of the file for reading.
Procedure Prototype
Parameter Description
. The file to reset, after this call you can read from this
file.
You can call either * or
to write to the file. Rewrite deletes the old file contents,
append moves to the end of the file and adds new data there.
Procedure Prototype
Parameter Description
. The file to rewrite. After this call you can write data to
this file, this will override the existing contents.
680
9.4. INPUT AND OUTPUT IN PASCAL
can also be used to open a file for write access. This will not overwrite existing data,
keeping the cursor at the end of the existing file.
Procedure Prototype
Parameter Description
. The file to append data to. After this call you can write
data to this file and it will appear after the existing con-
tents of the file.
Closing a file
Once you have opened a file it is important that you also close it. The procedure can be
used to close an opened file.
Procedure Prototype
Parameter Description
( *
. The file to close.
Note
• Make sure to close all opened files.
♠
• Remember to check all paths through your code.
681
CHAPTER 9. INPUT AND OUTPUT
You can use /$
to write data to a , file that has been opened with write capabili-
ties.
Procedure Prototype
Parameter Description
The Text file to write the output into.
Note
• This will write the data as text to the file.
♠
• The file must be opened with write permissions using * or
( *
Reading text data from a file is similar to reading data from the Terminal or from a string.
Procedure Prototype
Returns
The number of values read by
.
Parameter Description
The Text file from which the input is read.
Note
• This will read text data from the file.
♠
• The file must be opened with read permissions.
682
9.4. INPUT AND OUTPUT IN PASCAL
Pascal
,!'
%
,
+ !
$ !
' '
*
* $
$
%
( *
Listing 9.12: Example code that demonstrates writing a value and reading it back from a text file
683
CHAPTER 9. INPUT AND OUTPUT
1. Write two programs that save three integer values to file, one that saves it to a text file
the other to a binary file. Execute the two programs and compare the files created.
2. Write two programs that read three integer values from file, one that reads them from
a text file the other from a binary file. Once the data is loaded into memory have the
program output them to the terminal.
3. Use the code from this chapter to implement saving data for the Small DB program.
4. Revisit your statistics programs and have it save the values the user enters to file when
the programs ends. Once this is working add the code to load the data from the file when
the programs starts.
1. Explore the other file IO functions and procedures offered by the language you are using.
See if you can work out how to move the cursor within the file (seek to a new location).
Use this to move back and forth within a file reading individual values in response to
user input.
684