You are on page 1of 121

UNIT 1

INTRODUCTION TO PROGRAMMING

Resources you will need: Internet, computer

1.1 What Is Programming

Computer programming (often shortened to programming) is a process that leads from an


original formulation of a computing problem to executable computer programs. The purpose of
programming is to find a sequence of instructions that will automate performing a specific task
or solving a given problem. The process of programming thus often requires expertise in many
different subjects, including knowledge of the application domain, specialized algorithms
and formal logic.
Related tasks include testing, debugging, and maintaining the source code, implementation of the
build system, and management of derived artifacts such as machine code of computer programs.
These might be considered part of the programming process, but often the term software
development is used for this larger process with the term "programming", "implementation", or
"coding" reserved for the actual writing of source code. 

Computers are so widespread in our society because they have three advantages over us humans.
First, computers can store huge amounts of information. Second, they can recall that information
quickly and accurately. Third, computers can perform calculations with lightning speed and
perfect accuracy.

The advantages that computers have over us even extend to thinking sports like chess. In 1997,
the computer Deep Blue beat the world chess champion, Garry Kasparov, in a chess match. In
2003, Kasparov was out for revenge against another computer, Deep Junior, but only drew the
match. Kasparov, while perhaps the best chess player ever, is only human, and therefore no
match for the computer’s ability to calculate and remember prior games.

1
However, we have one very significant advantage over computers. We think on our own, while
computers don’t, at least not yet anyway. Indeed, computers fundamentally are far more brawn
than brain. A computer cannot do anything without step-by-step instructions from us telling it
what to do. These instructions are called a computer program, and of course are written by a
human, namely a computer programmer. Computer programs enable us to harness the
computer’s tremendous power.

1.1.2 Programming is problem-solving


Essentially, a program tells the computer how to solve a specific problem. Because the world is
full of problems, the number and variety of programs that people can write for computers is
practically endless.
But to tell a computer how to solve one big problem, you usually must tell the computer how to
solve a bunch of little problems that make up the bigger problem. If you want to make your own
video game, for example, you need to solve some of the following problems:
 Determine how far to move a cartoon figure (such as a car, a spaceship, or a man) on-screen
as the user moves a joystick.
 Detect whether the cartoon figure bumps into a wall, falls off a cliff, or runs into another
cartoon figure on-screen.
 Make sure that the cartoon figure doesn't make any illegal moves, such as walking through a
wall.
 Draw the terrain surrounding the cartoon figure and make sure that if the cartoon figure
walks behind an object such as a tree, the tree realistically blocks the figure from sight.
 Determine whether bullets that another cartoon figure fires are hitting the player's cartoon
figure. If so, determine the amount of damage, how it affects the movement of the damaged
cartoon figure, and how the damage appears on-screen.
The simpler the problem is that you need to solve, the more easily you can write a program that
tells the computer how to work. A program that displays a simple Ping-Pong game with two
stick paddles and a ball is much easier to write than a program that displays World War II fighter
airplanes firing machine guns and dropping bombs on moving tanks while dodging anti-aircraft
fire.

1.1.3 What It takes to Program


Programming really isn't that difficult or mysterious. If you can write step-by-step instructions
directing someone to your house, you can write a program.

2
The hardest part about programming is identifying all the little problems that make up the big
problem that you're trying to solve. Because computers are completely stupid, you need to tell
them how to do everything.
If you want to tell your friend how to prepare a meal say, nshima, you don’t have to tell them all
the details. For the computer however these may not be clear. You need to specify how much
Millie meal, how big should the pot be, how long the water boil, and many other specific and
precise details should.
You need to tell computers how to do everything, which can make giving them instructions as
aggravating and frustrating as telling children what to do. Unless you specify everything that you
want the computer to do and exactly how to do it, the computer on its own will not know how to
do what you want it to do.

1.1.4 Data Representation In The Computer


Let’s take a bit of time to talk about how data is represented in a computer. Your computer
successfully creates the illusion that it contains photographs, letters, songs, and movies. All it
really contains is bits, lots of them, patterned in ways you can't see. Your computer was
designed to store just bits - all the files and folders and different kinds of data are illusions
created by computer programmers.
Basically, computer instructions perform operations on groups of bits.  A bit is either on or off,
like a lightbulb. Figure 1.1 shows an open switch and a lightbulb that is off - just like a transistor
in a computer represents a bit with the value: zero. The figure on the right shows the switch in
the closed position and the lightbulb is on, again just like a transistor in a computer representing
a bit with the value: one.

Light bulb off Light bulb on


Figure 1.1 A light bulb-synonymous to representation in computers

A microprocessor, which is the heart of a computer, is very primitive but very fast.  It takes
groups of bits and moves around their contents, adds pairs of groups of bits together, subtracts
one group of bits from another, compares a pair of groups, etc. Inside a microprocessor, at a very
low level, everything is simply a bunch of switches, also known as bits - things that are either on
or off! 

Symbols As Bits - Ascii Characters


3
Ok, so numbers are simply groups of bits.  What other objects will the computer's instructions
manipulate?  How about the symbols that make up an alphabet?
It should come as no surprise that symbols that make up alphabets are just numbers, groups of
bits, too.  Let's walk through a couple of examples, entries in the table.  Here are some
characters, their decimal value and their binary value which is then transformed into an octal
number.

Uppercase 'A' = decimal 65 = binary 01000001 = 01 000 001 = octal 101


Uppercase 'Z' = decimal 90 = binary 01011010 = 01 011 010 = octal 132
The digit '1' = decimal 49 = binary 00110001 = 00 110 001 = octal 061

Table 1.0 ASCII character set, just enough to give you a flavor of its organization.

ASCII in in in in
Character Binary Octal Decimal Hex
Space 00100000 040 32 20
( 00101000 050 40 28
) 00101001 051 41 29
* 00101010 052 42 2A
0 00110000 060 48 30
1 00110001 061 49 31
2 00110010 062 50 32
9 00111001 071 57 39
A 01000001 101 65 41
B 01000010 102 66 42
C 01000011 103 67 43
Z 01011010 132 90 5A
A 01100001 141 97 61
B 01100010 142 98 62
C 01100011 143 99 63
Z 01111010 172 122 7A

This might look a bit strange but the main point you have to pick up from here is that the computer does
not store data as we do using different characters, rather everything is stored as bit. You will learn more
about this fact in computer Architecture.

4
There is a difference between the language that a computer understands and the languages that we use as
humans. So then the question is in which language can we speak to the computer so that it can understand
us?

1.2 What you are going to learn in this course

In this course you are going to learn the following

 Problem analysis and program development: where you will learn how to design a
program before you implement it. We shall also cover the tools that are used in this.
 Implementing a program design: this will include the actual program in c++. We shall use
c++ because it is best optimized for learning.
 Structured programming: were you will learn advanced programming skills that will
prove useful in programming.

To begin let us talk about programming languages before were cover the other topics outlined
above.

UNIT SUMMARY

 A program is a set of instructions used by the computer to carry out a task. The
instructions must be precise and specific.
 Programming is the art of writing computer programs
 Programming is problem solving
 Computers do not understand the languages that used by humans. They use 0s and 1s to
represent data.
 Programming is done using a programming language

5
EXERCISE

Answer the following questions

1. Explain what programming is.

2. How does instructing a person differ from instructing a computer?

3. Elaborate three (3) reasons why programs are developed.

4. Explain the role that programming plays in the business world.

UNIT 2
COMPUTER PROGRAMMING LANGUAGES

6
Resources you will need: Internet

2.1 Need For Programming Languages


As stated earlier, computers carry out their operations in the language of 1s and 0s, which makes
their operations different from the perception of humans. This language is called machine
language.
Machine computations are low level, full of details about the inner workings of the machine.
Machine language is a collection of very detailed instructions that control the computer’s internal
circuitry. Machine language is the native language of the computer; it is the notation to which the
computer responds directly. For example a machine language code might look like this;
000000101111001010
000000101111110010
000000110011101010
The above code adds the numbers in locations 10 and 11 and stores the result in location 12. This
should be quite difficult to interpret not so? How can you tell which number represent the
addition instruction? This requires a lot of effort. This is exactly what the machine understands.
Each different type of CPU has its own unique machine language. Programs in machine
language are usually unintelligible at the lowest level, since they consist only of 0s and 1s.
Programming languages were invented to make machines easier to use. They are tools for
instructing machines. Programming languages are used for specifying, organizing, and reasoning
about computations.

7
2.2 What Is A Programming Language
A programming language is a notation for specifying a sequence of operations to be carried out
by a computer. Programming languages are artificial languages created to tell the computer what
to do. They consist of vocabulary and a set of rules to write programs.
Tip: think of a programming language the same way you think of the different languages you
know e.g English, Bemba, French. Each of these languages can be used to make the same
instructions but not using the same grammar. That is the idea behind programming languages!!!

A programming language has a vocabulary and set of grammatical rules for instructing a
computer to perform specific tasks. The term programming language usually refers to high-level
languages, such as BASIC, C, C++, COBOL, FORTRAN, Ada, and Pascal. These are quite
advanced languages, at least above machine code, because they are able to use languages which
can readily be perceived by humans. Just as people speak many languages, you should
understand there are different kinds of programming languages.

2.3 Types Of Programming Languages:


There are many different languages that can be used to program a computer. Computer
languages can be classified as first, second and third generation languages. Usually, a program
will be written in some language whose instruction set is more compatible with human languages
and human thought processes. Such a language is called a high-level language e.g. Pascal, Visual
Basic, C++, and Java etc. programming languages can be said to fall into two categories;
I. Low level languages (LLL) and
II. High level languages (HLL)
As a rule, a single instruction in a high-level language will be equivalent to several instructions
in machine language. This greatly simplifies the task of writing complete, correct programs. Low
level languages refer first to machine language. It being low is in comparison to human
languages. It can be said to be quite low, which means far from human language. Lying between
machine languages and high-level languages are languages called assembly languages. Assembly
language is also regarded to be a low level language. One notable feature of low level languages
is that they are machine specific, which is in contrast with high level languages as will be
discussed later.
There is quite a variety of high level languages. Take some time however in the next frame to
understand the common features among the different programming languages.

2.4 Common Features Of Programming Languages


Every programming language has core features. These features have evolved over a period,
depending on the purpose the languages were created for and the market they targeted. All
programming languages have common core set of common features. Implementation of these
core set of features varies from language to language. The history of the language will give us an

8
idea of tvhe market the languages were intended for.

Here is a list of the common features:

1. A place for storing data. Arrays are advanced storing data facility. Also known as data
structures.
2. Rules for writing programs in that programming language
3. Control statements – which are building blocks for logic implementation.
4. Most programming languages of today support Object Oriented Programming (OOP). So,
constructs to implement like features Class declaration, objects, inheritance,
polymorphism and constructors are included.
5. Every language has operators. Operators are used execute mathematical operations.
6. All languages include facility to write programs, functions and procedures. Incidentally,
this is the place where you write your programs. Functions return values after execution,
whereas procedures simply execute programs.
7. All programs include facility to write libraries. Libraries are themselves programs, which
can be used in other programs.
8. All languages support exception handling. This feature is helpful to identify errors and
generate appropriate messages.
9. All languages include built in functionalities, provided as classes and functions. These
classes help to write better programs.
10. All languages include a compiler and memory handling features. These are implemented
in different ways by the person(s) who developed the language.

2.5 Development Of Programming Languages


Programming languages can also be classified by levels or generations. Lower-level languages
are the oldest while high level generations are newer and advanced. The five generations of
programming languages are:
 Machine languages
 Assembly languages
 Procedural languages
 Problem-oriented languages
 Natural languages
Take note that the first two are low level languages while the last three are high level languages.
Let’s examine each of these generations.

9
2.5.1 Machine Languages: the First Generation

A machine language consists of the numeric codes for the operations that a particular computer
can execute directly. The codes are strings of 0s and 1s, or binary digits (“bits”), which are
frequently converted both from and to hexadecimal (base 16) for human viewing and
modification. Machine language instructions typically use some bits to represent operations, such
as addition, and some to represent operands, or perhaps the location of the next instruction.
Machine language is difficult to read and write, since it does not resemble conventional
mathematical notation or human language, and its codes vary from computer to computer.
Assembly language is one level above machine language. It uses short mnemonic codes for
instructions and allows the programmer to introduce names for blocks of memory that hold data.
One might thus write “add pay, total” instead of “0110101100101000” for an instruction that
adds two numbers. (Hemmendinger, 2015). Machine code programs are very efficient, but
obviously difficult to write.

2.5.2 Assembly Languages: the Second Generation


According to Hemmendinger (2015), assembly language is designed to be easily translated into
machine language. Although blocks of data may be referred to by name instead of by their
machine addresses, assembly language does not provide more sophisticated means of organizing
complex information. Like machine language, assembly language requires detailed knowledge of
internal computer architecture. It is useful when such details are important, as in programming a
computer to interact with input/output devices (printers, scanners, storage devices, and so forth).

The following are some observable facts about assembly language

 Assembly languages use abbreviation or mnemonics such as ADD that are automatically
converted to the appropriate sequence of 1s and 0s
 Assembly languages are much easier to use than machine language, but still more
difficult to use than higher level languages
 These tend to be hardware dependent, but very efficient
This is a second level programming language. It is a variant of machine language in which
names and symbols take the place of the actual codes for machine operations , values and storage
locations , making individual instructions more readable
mov ax, WORD PTR Long1[0] ; AX = low word, long1
mov dx, WORD PTR Long1[2] ; DX = high word, long1
add ax, WORD PTR Long2[0] ; Add low word, long2
adc dx, WORD PTR Long2[2] ; Add high word, long2
ret ; Result returned as DX:AX

10
2.5.3 High-level Languages: Third Generation
These are considered portable languages because they are not tied specifically to certain
hardware like machine and assembly languages. This implies that you can write a program on
one machine, and transfer the same program on another machine and it will run successfully.
High level languages are not tied to a specific machine. These languages are also referred to as
procedural languages. This is because of the fact that they are designed to express the logic
procedures to solve general problems.
Examples of languages in this generation include Cobol, Basic, Fortran, and C++, Basic, Pascal,
C e.t.c. Depending on the language, the source code is translated into machine code using an
interpreter or a compiler. (you will soon learn about compilers and interpreters). Once compiled,
the program code can be stored as the object code, which is then saved to be run over and over
(without going through the compile process each time). Pascal, Cobol, and Fortran use
compilers.
An interpreter does a similar process, only the translated code is not saved – each time the
program is run, it is interpreted into machine code and run again. The Basic programming
language uses an interpreter.
Take note that each language can use either an interpreter or a compiler.

2.5.4 Problem-oriented Languages: the Fourth Generation


Problem-oriented languages (aka 4GLs – 4th generation languages) are very high level languages
designed to make it easy for people to write programs. These are designed to tackle specific
problems, such as financial or statistical analysis, data storage, and such. For example,
 IFPS (Interactive Financial Planning System) is used to create financial models
 Many 4GLs are part of DBMS systems.

11
In this generation we find such languages as the following;

Query Languages
 Query languages enable non-programmers to use certain easily understood
commands to search and generate reports from a database
 Structured Query Language (SQL) is one of the most widely used query languages

Application Generators
 An application generator (aka program coder) is a program that provides modules
of prewritten code.
 Programmers can quickly create a program by referencing the appropriate modules
 MS Access has a report generation application and a Report Wizard for quickly
creating reports
Because they are easier to use compared to 3rd generation languages, 4th generation languages are
called Very High Level Languages.

2.5.5 Natural Languages and Visual Programming: the Fifth Generation


 A 5th GL is a computer language that incorporates the concepts of artificial intelligence
to allow direct human communication.
 These languages would enable a computer to learn and to apply new information as
people do.
 Visual programming languages are also included in 5GLs, such as Microsoft’s Visual
Basic. Such languages have proved to be easier to use. You do not need to struggle to
create a user interface in visual basic compared to other lower generation languages.
Such languages are somewhat close to the thinking and language of human, and hence
the term Natural Languages.

The following diagram can help you to have an overview of the programming languages

Figure 2.1programming languages illustrated (Beal, 1995)

12
Machine language is the language that interacts directly with the hardware. This explains why it
is suppose to be machine specific. Assembly language is quite close to hardware and hence is
also machine specific.
By now you have a good understanding of programming languages. Let’s take a close look at
high level languages and what is involved in executing their programs in terms of compiling and
interpreting.

2.6 HIGHER LEVEL LANGUAGES


These have replaced machine and assembly language in all areas of programming. Programming
languages were designed to be high level. A language is high level if it is independent of the
underlying machine. Portability is another term for machine independence; a language is
portable if programs in the language can be run on different machines with little or no change.
Furthermore, the rules for programming in a particular high-level language are much the same
for all computers, so that a program written for one computer can generally be run on many
different computers with little or no alteration. Thus, we see that a high-level language offers
three significant advantages over machine language: simplicity, uniformity and portability. Lying
above high-level languages are languages called fourth-generation languages (usually
abbreviated 4GL). 4GLs are far removed from machine languages and represent the class of
computer languages closest to human languages.
The question of which language is best is one that consumes a lot of time and energy among
computer professionals. Every language has its strengths and weaknesses. For example,
FORTRAN is a particularly good language for processing numerical data, but it does not lend
itself very well to organizing large programs. Pascal is very good for writing well-structured and
readable programs, but it is not as flexible as the C programming language. C++ embodies
powerful object-oriented features, but it is complex and difficult to learn.
The choice of which language to use depends on the type of computer the program is to run on,
what sort of program it is, and the expertise of the programmer. Regardless of what language you
use, you eventually need to convert your program into machine language so that the computer
can understand it.

2.6.1 Need For a Translator


A program that is written in a high level language must, however, be translated into machine
language before it can be executed. So a small program (which comes with every programming
Language) comes into picture which is called as translator which converts High level language
into low level language and vice – a - versa.
There are two types of translators: Interpreters and Compilers.
A Translator is itself a computer program. It accepts a program written in a high-level language
as input, and generates a corresponding machine-language program as output. The original high-
level program is called the source program.

13
2.6.2 Interpreters
Interpreters, proceed through a program by translating and then executing single instructions or
small group of instructions. An Interpreter takes a program and its input at the same time. It
translates the program, implementing operations as it encounters them, and doing input/output as
necessary. One main advantage of an interpreter is that execution as well as syntax errors are
detected as each statement is encountered, thus debugging is easier in interpreted languages.

With an interpreter, the language comes as an environment, where you type in commands at a
prompt and the environment executes them for you. For more complicated programs, you can
type the commands into a file and get the interpreter to load the file and execute the commands
in it. If anything goes wrong, many interpreters will drop you into a debugger to help you track
down the problem.

The advantage of this is that you can see the results of your commands immediately, and
mistakes can be corrected readily. The biggest disadvantage comes when you want to share your
programs with someone. They must have the same interpreter, or you must have some way of
giving it to them, and they need to understand how to use it. Also users may not appreciate being
thrown into a debugger if they press the wrong key! From a performance point of view,
interpreters can use up a lot of memory, and generally do not generate code as efficiently as
compilers.

It can however be said that, interpreted languages are the best way to start if you have not done
any programming before. This kind of environment is typically found with languages like Lisp,
Smalltalk, Perl and Basic.

2.6.3 Compilers
Compilers translate the entire program into machine language before executing any of the
instructions. Compilers translate source code into machine oriented target code called object
code. After source code is compiled into object code , no futher references is made to the source
language.

First of all, you write your code in a file (or files) using an editor. You then run the compiler and
see if it accepts your program. If it did not compile, grit your teeth and go back to the editor; if it
did compile and gave you a program, you can run it either at a shell command prompt or in a
debugger to see if it works properly.

Program compilation is a complicated process. A compiler is a software program that translates a


high-level source language program into a form ready to execute on a computer. Early in the
evolution of compilers, designers introduced IRs (intermediate representations, also commonly
called intermediate languages) to manage the complexity of the compilation process. The use of

14
an IR as the compiler's internal representation of the program enables the compiler to be broken
up into multiple phases and components, thus benefiting from modularity.

An IR is any data structure that can represent the program without loss of information so that its
execution can be conducted accurately. It serves as the common interface among the compiler
components. Since its use is internal to a compiler, each compiler is free to define the form and
details of its IR, and its specification needs to be known only to the compiler writers. Its
existence can be transient during the compilation process, or it can be output and handled as text
or binary files.

2.6.4 The Importance of IRs to Compilers

An IR should be general so that it is capable of representing programs translated from multiple


languages. Compiler writers traditionally refer to the semantic content of programming
languages as being high. The semantic content of machine-executable code is considered low
because it has retained only enough information from the original program to allow its correct
execution. It would be difficult (if not impossible) to re-create the source program from its lower
form. The compilation process entails the gradual lowering of the program representation from
high-level human programming constructs to low-level real or virtual machine instructions
(figure 2.2). In order for an IR to be capable of representing multiple languages, it needs to be
closer to the machine level to represent the execution behavior of all the languages. Machine-
executable code is usually longer because it reflects the details of the machines on which
execution takes place.

15
Figure 2.2 Intermediate representation as an intermediate (Chow, 2013)

A well-designed IR should be translatable into different forms for execution on multiple


platforms. For execution on a target processor or CPU, it needs to be translated into the assembly
language of that processor, which usually is a one-to-one mapping to the processor's machine
instructions. Since there are different processors with different ISAs (instruction set
architectures), the IR needs to be at a higher level than typical machine instructions, and not
assume any special machine characteristic.  

Using an IR enables a compiler to support multiple front ends that translate from different
programming languages and multiple back ends to generate code for different processor targets
(figure below). The execution platform can also be interpretive in the sense that its execution is
conducted by a software program or virtual machine. In such cases, the medium of execution can
be at a level higher than assembly code, while being lower or at the same level as the IR.

16
Figure 2.3 Main aim of intermediate representation (Chow, 2013)

2.6.5 Comparison Between Compilers And Interpreters


The repeated examination of the source program by an interpreter allows interpretation to be
more flexible than compilation. An interpreter directly runs the source program, so it can allow
program to be changed whenever required, to add features or correct errors.
Furthermore, an interpreter works with the source text, so it can pinpoint an error in the source
text and report it accurately. With a compiler all translation is completed before the object code
is run, which prevents the object file from being readily adapted as it runs.
It can also be observed that programs which are compiled run faster compared to those which are
interpreted. This is because the interpreter still does the translation during run time, as opposed
to the compiler which does no translation during runtime.

Key
 A compiler is a program that changes source code to object code
 An interpreter translates source code one line at a time and executes the instruction

Figure 2.4 Operation of the interpreter and compiler compared (source:wikepedia)

17
Libraries
If you had to create everything from scratch every time you wrote a program, it would be tedious
indeed. The same kind of functionality is often required in many programs—reading data from
the keyboard, for example, or displaying information on the screen. To address this,
programming languages tend to come supplied with considerable quantities of pre-written code
that provides standard facilities such as these, so you don’t have to write the code for them
yourself.
Standard code intended for use in any program is kept in a library. The library that comes with a
particular programming language is as important as the language itself, as the quality and scope
of the library can have a significant effect on how long it will take you to complete a given
programming task.
The object file produced by the compiler cannot be executed .If the source contains library
functions the code for these functions are not included in the object file. It is the job of the Linker
to integrate the code of the library functions with the object code into a single executable file.

Executable File
It is a file in a format that the computer can directly execute. Unlike source file, executable files
cannot be read by humans. To transform a source file into an executable file you need to pass it
through a compiler or assembler Example of Compiled Languages are C, C++. The translation of
a source program into object code is said to occur at translation time. Once translation is
complete the object code is run at a later time called run time. The object code created by the
compiler occupies more space than machine code .

Figure 2.5: Linking Libraries into an executable file

18
2.7 Program Languages Semantics And Syntax
Each programming language has a unique set of keywords (words that it understands) and a
special ‘grammar’ for organizing program instructions. Syntax of a computer language is the set
of rules that defines the combinations of symbols that are considered to be a correctly structured
document or fragment in that language. This applies both to programming languages, where the
document represents source code, and markup languages, where the document represents data.
The syntax of a language defines its surface form. Text-based computer languages are based on
sequences of characters, while visual programming languages are based on the spatial layout and
connections between symbols (which may be textual or graphical). Documents that are
syntactically invalid are said to have a syntax error. This is synonymous to the languages we
speak. If someone wants to ask for water, what do you expect them to say? “may I please have
some water”. This is grammatically correct. What about this, “I please some may water? have”.
This is grammatically incorrect. This is similar to a syntax error in a programming language.
Syntax – the form – is contrasted with semantics – the meaning. In programming languages,
semantic processing generally comes after syntactic processing, but in some cases semantic
processing is necessary for complete syntactic analysis, and these are done together
or concurrently. In a compiler, the syntactic analysis comprises the frontend, while semantic
analysis comprises the backend (and middle end, if this phase is distinguished).
Implementing a programming language means bridging the gap from the programmer's high-
level thinking to the machine's zeros and ones. If this is done in an efficient and reliable way,
programmers can concentrate on the actual problems they have to solve, rather than on the
details of machines. But understanding the whole chain from languages to machines is still an
essential part of the training of any serious programmer. It will result in a more competent
programmer, who will moreover be able to develop new languages. A new language is often the
best way to solve a problem, and less difficult than it may sound.

Computer language syntax is generally distinguished into three levels:

 Words – the lexical level, determining how characters form tokens;


 Phrases – the grammar level, narrowly speaking, determining how tokens form phrases;
 Context – determining what objects or variables names refer to, if types are valid, etc

2.7.1 Syntax versus semantics


The syntax of a language describes the form of a valid program, but does not provide any
information about the meaning of the program or the results of executing that program. The
meaning given to a combination of symbols is handled by semantics (either formal or hard-coded
in a reference implementation). Not all syntactically correct programs are semantically correct.
Many syntactically correct programs are nonetheless ill-formed, per the language's rules; and
may (depending on the language specification and the soundness of the implementation) result in

19
an error on translation or execution. In some cases, such programs may exhibit undefined
behavior. Even when a program is well-defined within a language, it may still have a meaning
that is not intended by the person who wrote it.

2.8.3 Lexical Analysis


Lexical analysis is the process of converting a sequence of characters into a sequence of tokens,
i.e. meaningful character strings. A program or function that performs lexical analysis is called
a lexical analyzer, lexer, tokenizer, or scanner, though "scanner" is also used for the first stage of
a lexer. A lexer is generally combined with a parser, which together analyze
the syntax of programming languages, such as in compilers, but also HTML parsers in web
browsers, among other examples.
Strictly speaking, a lexer is itself a kind of parser – the syntax of some programming languages is
divided into two pieces: the lexical syntax (token structure), which is processed by the lexer; and
the phrase syntax, which is processed by the parser. (Farrell, 1995)
For more information about lexical analysis and passing see appendix I.

2.9 Bytecode
Bytecode, also known as p-code (portable code), is a form of instruction set designed for
efficient execution by a software interpreter. Unlike human-readable source code, bytecodes are
compact numeric codes, constants, and references (normally numeric addresses) which encode
the result of parsing and semantic analysis of things like type, scope, and nesting depths of
program objects. They therefore allow much better performance than direct interpretation of
source code.

The name bytecode stems from instruction sets which have one-byte opcodes followed by
optional parameters. Intermediate representations such as bytecode may be output
by programming language implementations to ease interpretation, or it may be used to reduce
hardware and operating system dependence by allowing the same code to run on different

20
platforms. Bytecode may often be either directly executed on a virtual machine (i.e. interpreter),
or it may be further compiled into machine code for better performance.
Since bytecode instructions are processed by software, they may be arbitrarily complex, but are
nonetheless often akin to traditional hardware instructions; virtual stack machines are the most
common, but virtual register machines have also been built. Different parts may often be stored
in separate files, similar to object modules, but dynamically loaded during execution

A bytecode program may be executed by parsing and directly executing the instructions, one at a


time. This kind of bytecode interpreter is very portable. Some systems, called dynamic
translators, or "just-in-time" (JIT) compilers, translate bytecode into machine language as
necessary at runtime: this makes the virtual machine hardware-specific, but doesn't lose the
portability of the bytecode itself. For example, Java and Smalltalk code is typically stored in
bytecoded format, which is typically then JIT compiled to translate the bytecode to machine code
before execution. This introduces a delay before a program is run, when bytecode is compiled to
native machine code, but improves execution speed considerably compared to direct
interpretation of the source code, normally by several magnitudes

2.9.1 Advantage of Byte Code

Because of its performance advantage, today many language implementations execute a program
in two phases, first compiling the source code into bytecode, and then passing the bytecode to the
virtual machine. There are bytecode based virtual machines of this sort
for Java, Python, PHP, Tcl, and Forth (however, Forth is not ordinarily compiled via bytecodes
in this way, and its virtual machine is more generic instead). The implementation
of Perl and Ruby 1.8 instead work by walking an abstract syntax tree representation derived from
the source code.

2.9.2VIRTUAL MACHINE (JAVA VIRTUAL MACHINE)


A virtual machine is basically a Machine Within a Machine or An abstract computing machine,
or virtual machine. JVM is a platform-independent execution environment that converts
Javabytecode into machine language and executes it. Most programming languages compile
source code directly into machine code that is designed to run on a specific microprocessor
architecture or operating system, such as Windows or UNIX.
JVM -- a machine within a machine -- mimics a real Javaprocessor, enabling Java bytecode to be
executed as actions or operating system calls on any processor regardless of the operating
system. For example, establishing a socket connection from a workstation to a remote machine
involves an operating system call. Since different operating systems handle sockets in different

21
ways, the JVM translates the programming code so that the two machines that may be on
different platforms are able to connect. (Beal, 1995)

A JVM language is any language with functionality that can be expressed in terms of a valid
class file which can be hosted by the Java Virtual Machine. A class file contains Java Virtual
Machine instructions (or bytecode) and a symbol table, as well as other support information.

EXERCISE

Answer the following questions

1. What is a programming language?


2. Explain HLL and LLL highlighting the difference between the two
3. Explain why high level languages need a translator. Discuss the types of translators used
in high level languages
4. Explain why byte code is unique.
5. Discuss the common features of programming languages.
6. Discuss the two elements of programming languages: semantics and syntax
7. Discuss the five generations of programming languages.

UNIT SUMMARY

We have covered the following points in this unit;

 A programming language is a notation for specifying a sequence of operations to be


carried out by a computer. Programming languages are artificial languages created to tell
the computer what to do. They consist of vocabulary and a set of rules to write programs.
 A program that is written in a high level language must, however, be translated into
machine language before it can be executed.
 Compilers translate the entire program into machine language before executing any of the
instructions. Compilers translate source code into machine oriented target code called
object code After source code is compiled into object code , no futher references is made
to the source language.

22
 Interpreters, proceed through a program by translating and then executing single
instructions or small group of instructions.
 Syntax of a computer language is the set of rules that defines the combinations of
symbols that are considered to be a correctly structured document or fragment in that
language.
 Semantics refers to the meaning of statements in a programming language.
 There are five generations of programming languages i.e. 1st, 2nd…5th generations.

UNIT 3

PROBLEM ANAYSIS AND DEVELOPMENT OF PROGRAMS

Resources: Computer, Internet

Spend about 8 hours on this unit

3.1 Program Development Life Cycle

The System Development is the interactive process which consists of the following stages. These
stages may vary slightly depending on which book you are reading or which model you are
following.

Sometimes software needs to be written to specific criteria rather than be purchased from a shop.
There are times that software must do specific things that just cannot be done by software that is
purchased off-the-shelf. When this occurs, software development is undertaken during the

23
development phases of the SDLC. A separate set of steps are engaged for the development of
software. These steps are:

 Analysis
 Design
 Development (coding and debugging)
 Testing
 Documentation
 Implementation and
 Evaluation

Programs are logical sets of instructions that can be understood and executed by a computer.
They are used to direct the computer to perform the functions that transform data into
information. Programs are usually developed using a general-purpose information-processing
language comprising sets of symbols and codes that are used to construct a logical sequence of
instructions.
Some programming languages are designed to create programs for particular purposes but can be
used for other purposes as well. For example, COBOL is used for business applications, Fortran
for scientific and engineering purposes, Lisp for creating artificial intelligence programs, Java for
developing programs that run on a range of hardware platforms, dBASE for producing database
applications, Visual Basic for Applications (VBA) is used with Microsoft products such as
Access, and Excel to customise the way they process data.

If a decision is made in the design stage of the SDLC to use custom-built software, then a set of
program specifications is produced. They specify the data and the input-processing-output
components of the program to be developed. When the development stage is underway, program
specification are given to the programming team so they can start work. As the program is
developed, it progresses through the following series of stages.

3.1.1 ANALYSIS STAGE


The analysis stage revisits and analyses the program specifications that come from the design
phase of the SDLC. The program specifications usually contain:
 a list of data
 requirements for input and output
 descriptions of the processes that will be used to transform the data into information.
These are described using design tools such as data dictionaries, context diagrams
and dataflow diagrams (DFDs), structured English and flowcharts.
The purpose of analysis is to understand and specify the exact requirements of the program to be
developed and built. The same design tools can be used again to represent the conceptual design

24
but with more detail of course. Analysis in software development can involve interviews with the
system designer and with the future users of the programs so that a clearer understanding of the
requirements is communicated.

3.1.2 DESIGN STAGE


Tasks in the design stage are broken down into smaller parts. For example, a large program is
broken down into modules and then further divided into smaller modules. This process is called
top-down decomposition design. The process is finished when each module is clearly and simply
defined, and small enough to be coded as a single program. If only a part of the software needs to
be developed the process is called bottom-up design as the new software has to be compatible
with the rest of the software.
The first step in the design stage is to define the structure of the overall program and the
relationship between the modules and represent them in a structure chart. At the same time the
layout diagrams of the input and output screens and reports are produced.

The next step is to define the purpose and method of operation of each module as an algorithm.
An algorithm is a description of a procedure or set of instructions required to perform a specific
task, and contains descriptions of the data to be used. Various design tools can be used to
represent the algorithm, such as flowcharts, Nassi-Schneidermann diagrams and structured
English (pseudocode). The algorithms for the modules must be clear for the programmer to work
from without the need to clarify them with the designer. The method used to represent the
structure and the algorithms depends on the type of programming language chosen. If an object-
orientated language is to be used the representation would be different from that used for a
procedure-based language.
The last part of the designs stage is checking the logic of the algorithms. This is checked using
specially designed test data and a process of stepping through the alogrithm called desk-
checking. It is much easier to correct errors in the design stage than when the program has been
written.

3.3 DEVELOPMENT STAGE

25
The development stage consists of two components: coding and debugging. These components
are done in an iterative manner, moving from debugging back to coding, and then debugging the
new code, and so on until all errors are found and removed.

Coding occurs when errors are removed from the code. Errors are generally of two types:
1. Syntax errors, which are often spelling mistakes.
2. Logic errors, which give wrong results.
The same test data that was used in the design stage desk-checking is used to check the logic as
the results are already known. Modern languages have extensive debugging tools built into an
integrated development environment (IDE) that allow tracking of the value of variables as the
program is run instruction by instruction. These tools greatly assist in the debugging process as
the results of each step are checked.

3.1.4 TESTING STAGE


The testing stage is where the actual program is checked against the program specifications from
the SDLC design phase. This often involves testing by some of the end users of the program.
Program documentation includes both external and internal documentation. External
documentation also includes:
 technical documentation
 the original program specifications
 the various designs and test data from the previous stages
 operating instructions and user’s manuals.

Internal documentation includes:

 the code with full internal documentation


 description of variables, files and data structures
 introductions to each module and code structure
 comments on lines of code that are not easily understood.

3.1.5 IMPLEMENTATION
The implementation stage invovles the installation of the program in the environemtn where it
will be tested against live data with trained users. This type of testing is often more thorough than
specially designed test data. The implementation may only involve a small number of the end-
users to begin with and then extend to all the staff and branches.

26
3.1.5 EVALUATION STAGE

The program is usually evaluated some time after it has been fully implemented within the
organisation. This is known as the evaluation stage. The program is evaluated against criteria that
are specified in the program specifications and feedback from the users.
After the software development implementation and evaluation stages, the completed software
then rejoins the System Development Life Cycle. The SDLC has its own implementation and
evaluation stages. The implementation and evaluation of the software needs to be integrated with
the implementation and evaluation of the full information system.

These stages can be represented as part of a continuous cycle as below;

Figure 3.1 Stages of program development

27
UNIT SUMMARY
 creating a program or software is a life cycle which involves a number of stages
 Problem analysis stage aim at understanding the problem at hand so as to know the input
which will be required, the processing need, and the subsequent output
 The Design stage aim at trying creating a solution to the identified problem using
program design tools
 Development, also referred to as coding is the act of implementing the designed solution
into a program using an appropriate programming language.
 Implementation means the program is used as required by the user to evaluate it.
 Evaluation stage is when you are checking if the program you have produced does
what it was meant to do and meets the problem identified during analysis.

28
UNIT 4
PROGRAM DESIGN AND ALGORITHMS

Resources: Computer, internet

4.0 Introduction
Let’s now discuss three tools used to convert algorithms into computer programs: flowcharts,
pseudocode, and hierarchy charts. As you have seen above, you not just write a program from
without – it must be designed first. This is similar to what a tailor does. Before they can sew an

29
outfit, they first design it. In a similar manner a program before it is put in programming
language is called an algorithm. There are three tools that are used to design programs. But then
how can we define an algorithm?

4.1 What is an Algorithm?


An algorithm is a self-contained step-by-step set of operations to be performed. You use
algorithms every day to make decisions and perform tasks. A computer program can be viewed
as an elaborate algorithm. In mathematics and computer science, an algorithm usually means a
small procedure that solves a recurrent problem. (Algorithms, 2014)

A common example of an algorithm would be instructions for assembling a model airplane.


Given the starting set of a number of marked pieces, one can follow the instructions given to
result in a predictable end-state: the completed airplane. Errors in the instructions, or a failure to
properly follow a step, will result in a faulty end product. A computer program is another
pervasive example. Every computer program is simply a series of instructions, which may vary
in complexity, and is listed in a specific order, designed to perform a specific task. Mathematics
also uses algorithms to solve equations by hand, without the use of a calculator.

Everything we do every day, is about algorithms. For instance, whenever you mail a letter, you
must decide how much postage to put on the envelope. One rule of thumb is to use one stamp for
every five sheets of paper or fraction thereof. Suppose a friend asks you to determine the number
of stamps to place on an envelope. The following algorithm will accomplish the task.
1. Request the number of sheets of paper; call it Sheets. (input)
2. Divide Sheets by 5. (processing)
3. Round the quotient up to the next highest whole number; call it Stamps. (processing)
4. Reply with the number Stamps. (output)
The preceding algorithm takes the number of sheets (Sheets) as input, processes the
data, and produces the number of stamps needed (Stamps) as output. We can test the algorithm
for a letter with 16 sheets of paper.
1. Request the number of sheets of paper; Sheets = 16.
2. Dividing 5 into 16 gives 3.2.
3. Rounding 3.2 up to 4 gives Stamps = 4.
4. Reply with the answer, 4 stamps.

Of the program design tools available, the three most popular are the following:
1. Flowcharts: Graphically depict the logical steps to carry out a task and show how the
steps relate to each other.
2. Pseudocode: Uses English-like phrases with some Visual Basic terms to outline the task.
3. Hierarchy charts: Show how the different parts of a program relate to each other

30
4.3 PSEUDOCODE
Pseudocode is an abbreviated version of actual computer code (hence, pseudocode). The
geometric symbols used in flowcharts are replaced by English-like statements that outline the
process. As a result, pseudocode looks more like computer code than does a flowchart.
Pseudocode allows the programmer to focus on the steps required to solve a problem rather than
on how to use the computer language. The programmer can describe the algorithm in Visual
Basic-like form without being restricted by the rules of Visual Basic. When the pseudocode is
completed, it can be easily translated into the Visual Basic language. The following is
pseudocode for the postage stamp problem:

Program: Determine the proper number of stamps for a letter


Read Sheets (input)
Set the number of stamps to Sheets / 5 (processing)
Round the number of stamps up to the next whole number (processing)
Display the number of stamps (output)

Pseudocode Examples

An algorithm is a procedure for solving a problem in terms of the actions to be executed and the
order in which those actions are to be executed. An algorithm is merely the sequence of steps
taken to solve a problem. The steps are normally "sequence," "selection, " "iteration," and a case-
type statement.

In C, "sequence statements" are imperatives. The "selection" is the "if then else" statement, and
the iteration is satisfied by a number of statements, such as the "while," " do," and the "for,"
while the case-type statement is satisfied by the "switch" statement.

Pseudocode is an artificial and informal language that helps programmers develop algorithms.
Pseudocode is a "text-based" detail (algorithmic) design tool.

4.3.1 Pseudocode Examples

31
Example 1: this pseudocode for a program that prints the text “Failed” of the marks of the
student is less than 60 and “Passed” if the marks entered is 60 or above

If student's grade is greater than or equal to 60

Print "passed"

else

Print "failed"

You can see that the statements Print "passed" and Print "failed" are dependent on the condition.
Hence they have been indented, ie not in the same line as the statement above. In the above
examples check other the statements which have been indented and circle them!

Example 2: this algorithms allows the user to enter grade of the marks obtained for 10 students,
and then compute the average of the marks obtained.

Set total to zero

Set grade counter to one

While grade counter is less than or equal to ten

Input the next grade

Add the grade into the total

Set the class average to the total divided by ten

Print the class average.

Example 3: the following psedocode lets the user enter grades. If a number of grades have been
entered, the program calculates and prints the average. If no grades have been entered the
program displays that ‘no grade have been entered’.

Initialize total to zero

Initialize counter to zero

Input the first grade

32
while the user has not as yet entered the sentinel

add this grade into the running total

add one to the grade counter

input the next grade (possibly the sentinel)

if the counter is not equal to zero

set the average to the total divided by the counter

print the average

else

print 'no grades were entered'

Example 4. The pseudocode below allows the user to enter marks for ten (10) student. If the
number of students who have passed is eight (8) or above then raise the tuition fees and print the
number of those who have passed and the number of those who have failed.

initialize passes to zero

initialize failures to zero

initialize student to one

while student counter is less than or equal to ten

input the next exam result


if the student passed
add one to passes

else

add one to failures

add one to student counter

33
print the number of passes

print the number of failures

if eight or more students passed

print "raise tuition"

Below are additional examples of algorithms. On top is the scenario or question, then followed
by the solution.

Scenario: Write an algorithm to add two numbers entered by user.

Step 1: Start

Step 2: Declare variables num1, num2 and sum.

Step 3: Read values num1 and num2.

Step 4: Add num1 and num2 and assign the result to sum.

sum←num1+num2

Step 5: Display sum

Step 6: Stop

Scenario: Write an algorithm to find the largest among three different numbers
entered by user.

Step 1: Start

Step 2: Declare variables a,b and c.

Step 3: Read variables a,b and c.

Step 4: If a>b

If a>c

34
Display a is the largest number.

Else

Display c is the largest number.

Else

If b>c

Display b is the largest number.

Else

Display c is the greatest number.

Step 5: Stop

Scenario: Write an algorithm to check whether a number entered by user is prime


or not.

Step 1: Start

Step 2: Declare variables n,i,flag.

Step 3: Initialize variables

flag←1

i←2

Step 4: Read n from user.

Step 5: Repeat the steps until i<(n/2)

5.1 If remainder of n÷i equals 0

flag←0

Go to step 6

5.2 i←i+1

Step 6: If flag=0

35
Display n is not prime

else

Display n is prime

Step 7: Stop

Scenario: Write an algorithm to find the Fibonacci series till term≤1000.

Step 1: Start

Step 2: Declare variables first_term,second_term and temp.

Step 3: Initialize variables first_term←0 second_term←1

Step 4: Display first_term and second_term

Step 5: Repeat the steps until second_term≤1000

5.1: temp←second_term

5.2: second_term←second_term+first term

5.3: first_term←temp

5.4: Display second_term

Step 6: Stop

Some Keywords That Should Be Used

For looping and selection, The keywords that are to be used include Do While...EndDo; Do
Until...Enddo; Case...EndCase; If...Endif; Call ... with (parameters); Call; Return ....; Return;
When; Always use scope terminators for loops and iteration.

As verbs, use the words Generate, Compute, Process, etc. Words such as set, reset, increment,
compute, calculate, add, sum, multiply, ... print, display, input, output, edit, test , etc. with careful
indentation tend to foster desirable pseudocode.

36
Do not include data declarations in your pseudocode.

4.4 Hierarchy Chart


The last programming tool we’ll discuss is the hierarchy chart, which shows the overall program
structure. Hierarchy charts are also called structure charts, HIPO (Hierarchy plus Input- Process-
Output) charts, top-down charts, or VTOC (Visual Table of Contents) charts. All these names
refer to planning diagrams that are similar to a company’s organization chart. Hierarchy charts
depict the organization of a program but omit the specific processing logic. They describe what
each part, or module, of the program does and they show how the modules relate to each other.
The details on how the modules work, however, are omitted. The chart is read from top to
bottom and from left to right. Each module may be subdivided into a succession of submodules
that branch out under it. Typically, after the activities in the succession of submodules are carried
out, the module to the right of the original module is considered. A quick glance at the hierarchy
chart reveals each task performed in the program and where it is performed. Figure 4.1 below
shows a hierarchy chart for the postage stamp problem.

Figure 4.1 hierachy chat example

The main benefit of hierarchy charts is in the initial planning of a program. We break down the
major parts of a program so we can see what must be done in general. From this point, we can
then refine each module into more detailed plans using flowcharts or pseudocode. This process is
called the divide-and-conquer method. The postage stamp problem was solved by a series of
instructions to read data, perform calculations, and display results. Each step was in a sequence;
that is, we moved from one line to the next without skipping over any lines. This kind of
structure is called a sequence structure. Many problems, however, require a decision to
determine whether a series of instructions should be executed. If the answer to a question is

37
“Yes,” then one group of instructions is executed. If the answer is “No,” then another is
executed. This structure is called a decision structure. Figure 4.1 contains the pseudocode and
flowchart for a decision structure.

4.5 Flowchats

Flowcharts are written with program flow from the top of a page to the bottom.  Each command
is placed in a box of the appropriate shape, and arrows are used to direct program flow.  It must
however be noted that at times, flow may sometimes go up, as will be seen from the forth-
coming examples.

Table 4.1 Flowchat Symbols

Symbol Represents Description


Process Data being processed eg
additional of numbers,
operations on strings, saving
data, retrieving data
Flow Show the next step in the
algorithm

Decision/condition A situation which is tested for


and ca evaluate to true or false

Begin or End Shows where the algorithms


starts form and where it ends.
In each flowchat, there is one
end symbol and begin symbol
Input/output Represents the inputting of
data from the user, or any
form of output such as
displaying data to a user or
printing data to the user.

38
Table 4.1 above shows flowchart symbols adopted by the American National Standards Institute
(ANSI). The main advantage of using a flowchart to plan a task is that it provides a pictorial
representation of the task, which makes the logic easier to follow. We can clearly see every step
and how each step is connected to the next. The major disadvantage with flowcharts is that when
a program is very large, the flowcharts may continue for many pages, making them difficult to
follow and modify.
Pseudocode program designs are both text-based, the statements are written. Flow charts are a
graphical method of designing programs and once the rules are learned are very easy to draw.

In any flow chat you will come across, it will portray the following elements which are a part of
programming;

 Sequence – implying a simple flow from one step to the next


 Selection – implying choosing between two sets of statements depending on the condition
 Repetition- meaning some steps have to be repeated for as long as a particular condition
is true

4.5.1 The language of flow charts

The major symbols are the decision (the diamond symbol – refer to the table 4.1) and the
sequence (or process – the rectangle shape) symbols. The START and STOP symbols are called
the terminals. The subprocess symbol is a variation on the sequence symbol. There are also
connectors drawn between the symbols and you will see these used in the examples below. There
is at least one other sequence symbol which is used to represent input/output processes but I
think it is unnecessary so I don't use it.

There are some important rules concerning the symbols and these rules apply also to other ways
of stating algorithms:

 Processes have only one entry point and one exit point.
 Decisions have only one entry point, one TRUE exit point and one FALSE exit point.

39
Repetition

Figure 4.2 do while (repeat until) flowchat

The example above is good illustration of a repetition case. A typical scenario where you might
apply this is with regard to counting which day you must go to school. Assume that there is no
holiday in that particular week. You will go to school for as long as the day is not a weekend.
you will go to school on Monday, then check if the following day is a weekend. if not you will
go to school again and then check if the current day is a weekend. if not you will go to school
again the following day.

This is somehow a bad algorithm for such a scenario because it will make you go to school on a
Saturday.

40
Such a flow chat demonstrates a repetition structure called “do while” or “repeat until”. It
executes some process and checks the condition latter. A better flowchat for the school scenario
above would be the one shown below.

Figure 4.3 while loop flowchat

This loop is called the while loop. The while loop is basically the reverse of the repeat until loop,
the decision comes first, followed by the process. The while loop is usually written so that it
iterates while the condition is true, the repeat iterates until the condition becomes true. An
interesting question is: When should a repeat loop be used rather than a while loop? and vice-

41
versa. The while loop should be used when it is possible that the process or processes which are
in the scope of the decision (that is, in the loop) may not need to execute. For example assume
you have a designed an air-conditioner controller program and the program turns on the
compressor while the ambient temperature is above the desired temperature. A while loop is a
good choice here since the ambient temperature may be at the desired level before the
compressor part of the program is executed. If a repeat loop (do while) was used then the
compressor would be turned on but it wouldn't be necessary.

Selection

Figure 4.4 Selection structure (the if structure)

42
The IF ... THEN is used to implement selection in this case is shown here and is also known as
the NULL ELSE, meaning that there is no ELSE part. We have used lines with arrow-heads
(connectors) to indicate the flow of sequence. Although this is important in flow charts once you
have gained some skill in using them and if you draw them carefully you will find that
determining the sequence is straight forward. A typical rule is to use arrow-heads on connectors
where flow direction may not be obvious.

The diagram below adds the else part in the


algorithm.

Figure 4.5 Selection flowchat in flowchat (the if-else structure)

The IF ... THEN ... ELSE ... construct has a process at each branch of the decision symbol. The
only difference here is that each value of the decision  (TRUE/FALSE) has a process associated
with it.

4.5.3 Flowchat Examples

43
Take a look at the flowchat below. It basically counts the number of even numbers

from the range of numbers from 0 to 20

44
Figure 4.6 Even/Odd number program flowchat

The equivalent of t flowchat is the pseudocode below.

sum = 0  
count = 1  
REPEAT  
  IF count is even THEN sum = sum + count  
  count = count + 1  
UNTIL count > 20  
DISPLAY sum

You can see quite clearly from this example what the price of flow charting is. There is quite a
bit of drawing to do in addition to writing the legend in the symbols.

The pseudocode is quite simple by comparison. May be you are thinking, “why bother so much
with symbols, how to connect them, after all they are quite difficult?” The major reasons are that
the flow chart.

 is easier to read
 more closely follows a standard, this is not the case with pseudocode
 probably lends itself more readily to computer-aided techniques of program design

Some rules for flow charts

Well-drawn flow charts are easy to read. What must you do to draw well-drawn flow charts?
Here are a few rules:

1. Every flow chart has a START symbol and a STOP symbol

45
2. The flow of sequence is generally from the top of the page to the bottom of the page. This
can vary with loops which need to flow back to an entry point.
3. Use arrow-heads on connectors where flow direction may not be obvious.
4. There is only one flow chart per page
5. A page should have a page number and a title
6. A flow chart on one page should not break and jump to another page
7. A flow chart should have no more than around 15 symbols (not including START and
STOP)

Maybe you can try this now and test your understanding.

46
Figure 4.7: Solution to summation/average program

Flow charts and subprocesses

One process can be further broken into additional processes called subprocesses. Sometimes it is
useful to use subprocesses. The subprocess is useful because:

 it provides a means of simplifying programs by making common processes available to a


wide number of programs.
 it permits the modularisation of complex programs.
 it makes for more reliable programs since once it is shown that a process works then it
can be made a subprocess and need not be tested again.

In flow charts subprocesses are also useful in dealing with the flow charting rule that a flow chart
should have no more than 15 or so symbols on a page.

A subprocess flow chart can contain other subprocesses, there is no limit to how deeply these
could be nested.

47
Take an example of the following situation: a college accepts students on the basis of the
following requirements;
 first checks if the candidate has a credit in English
 if so then check if the candidate has a a credit or better in Mathematics
 if so then the check if the student has an average of a credit in sciences
 if so then check if they have any other credit. If the candidate passes all the above
requirements, then they are accepted

Can you think of how this can be implemented in flowchat? Look at the solution as figure 4.8
shows.

TRUE

FALSE

TRUE

FALSE TRUE

48
FALSE

FALSE

Figure 4.8 Candidate solution example

Lets now review the things you have learnt in this unit.

UNIT SUMMARY

49
 programs can be made from algorithms. An algorithm defines a set of finite steps taken to
solve a particular problem

 program can be designed using tools such as hierarchy chats, flowchats and pseudocode

 pseudocode is a text form, English like statements used to write algorithms

 flowchats are a pictorial tool used to write algorithms

 Hierarchy chats are used to show the components that make up a program. They are are
used as a tool for divide and conquer.

UNIT 5

IMPLEMENTING A PROGRAM DESIGN

50
Resources you will need: Internet, computer, Dev C++ (a software which allows
you to write c++ code and compile it). You can download Dev C++ on the
internet or any other c++ too like code blocks.

5.0 Introduction

After you have made your design as outlined above, you need to implement it. You have to
create the programming in a particular programming language. In our case we shall learn how
implement the particular program in c++. If you understand how to do this in C++, you can
easily learn how to do this in other languages. Take not of the of the following as we do read this
unit;

 the syntax of the C++ language (the rules of grammar of C++)

 basic structure of a C++ program

 how to write valid statements in C++

The best way to learn a programming language is by writing programs. To do this you will
require an editor tool that will help you to be able write C++ code. Download dev c++ or code
blocks on the internet and use them to write you programs. Exact details of how to use these
tools will be explained and demonstrated in class. It is advisable you try out any program that we
discuss so that you can gain a thorough understanding of what will be talked about.

Typically, the first program beginners write is a program called "Hello World", which simply
prints "Hello World" to your computer screen. Although it is very simple, it contains all the
fundamental components C++ programs have:

1 // my first program in C++ Hello World!


2 #include <iostream>
3

51
4 int main()
5{
6 cout << "Hello World!";
7}

The left panel above shows the C++ code for this program. The right panel shows the result
when the program is executed by a computer. The grey numbers to the left of the panels are line
numbers to make discussing programs and researching errors easier. They are not part of the
program.

Let's examine this program line by line:

Line 1: // my first program in C++


Two slash signs indicate that the rest of the line is a comment inserted by the programmer but
which has no effect on the behavior of the program. Programmers use them to include short
explanations or observations concerning the code or program. In this case, it is a brief
introductory description of the program.

Line 2: #include <iostream>

Lines beginning with a hash sign (#) are directives read and interpreted by what is known as
the preprocessor. They are special lines interpreted before the compilation of the program itself
begins. In this case, the directive#include <iostream>, instructs the preprocessor to include a
section of standard C++ code, known as header iostream, that allows to perform standard input
and output operations, such as writing the output of this program (Hello World) to the screen.

Line 3: A blank line.

Blank lines have no effect on a program. They simply improve readability of the code.

Line 4: int main ()

This line initiates the declaration of a function. Essentially, a function is a group of code
statements which are given a name: in this case, this gives the name "main" to the group of code
statements that follow. Functions will be discussed in detail in a later chapter, but essentially,
their definition is introduced with a succession of a type (int), a name (main) and a pair of
parentheses (()), optionally including parameters.

The function named main is a special function in all C++ programs; it is the function called when
the program is run. The execution of all C++ programs begins with the main function, regardless
of where the function is actually located within the code.

Lines 5 and 7: { and }

52
The open brace ({) at line 5 indicates the beginning of main's function definition, and the closing
brace (}) at line 7, indicates its end. Everything between these braces is the function's body that
defines what happens when main is called. All functions use braces to indicate the beginning and
end of their definitions.

Line 6: cout << "Hello World!";

This line is a C++ statement. A statement is an expression that can actually produce some effect.
It is the meat of a program, specifying its actual behavior. Statements are executed in the same
order that they appear within a function's body.

This statement has two parts: cout, (read as ‘C OUT’) basically means ‘print this’ on the
computer screen. Second, the insertion operator (<<), which indicates what is to be printed.
Finally, a sentence within quotes ("Hello world!"), is the content inserted into the standard
output. (Kent, 2004)

Notice that the statement ends with a semicolon (;). This character marks the end of the
statement, just as the period ends a sentence in English. All C++ statements must end with a
semicolon character. One of the most common syntax errors in C++ is forgetting to end a
statement with a semicolon.

The program above indicates to you the basic structure of a C++ program. take note that all the
code that you want to write should come between the { and } following the int main()

5.1 Comments

As noted above, comments do not affect the operation of the program; however, they provide an
important tool to document directly within the source code what the program does and how it
operates.

C++ supports two ways of commenting code:

1 // line comment
2 /* block comment */

The first of them, known as line comment, discards everything from where the pair of slash signs
(//) are found up to the end of that same line. The second one, known as block comment, discards
everything between the /* characters and the first appearance of the */ characters, with the
possibility of including multiple lines.

53
Let's add comments to our second program: 

1 /* my second program in C++ Hello World! I'm a C++ program


2 with more comments */
3
4 #include <iostream>
5
6 int main ()
7{
8 cout<< "Hello World! ";// prints HelloWorld!
9
10 cout<<"I'm a C++ program"; //prints I'm a C++ //program
}

If comments are included within the source code of a program without using the comment
characters combinations //,/* or */, the compiler takes them as if they were C++ expressions,
most likely causing the compilation to fail with one, or several, error messages.

5.3 Variables and Datatypes

While doing programming in any programming language, you need to use various variables to
store various information. Variables are nothing but reserved memory locations to store values.
This means that when you create a variable you reserve some space in memory.

You may like to store information of various data types like character, wide character, integer,
floating point, double floating point, boolean etc. Based on the data type of a variable, the
operating system allocates memory and decides what can be stored in the reserved memory. A
data type basically defines the nature (kind) of values stored in a particular location

5.3.1 Primitive Built-in Types:

C++ offer the programmer a rich assortment of built-in as well as user defined data types.
Following table lists down seven basic C++ data types:

Table 5.1 Common Data types

Type Keyword DESCRIPTION RANGE

Boolean Bool Stores a true or false value NA

54
Stores a single character on the -127 to 127 or 0
Character Char keyboard e.g “K”, “L”, “t”, ESC, to 255
ENTER

Stores whole numbers e.g 101, -2147483648 to


Integer Int -3400, 21, 0. Numbers such as 2147483647
3.656 are not integers

Can store both whole numbers and +/- 3.4e +/- 38


Floating point Float
integers (~7 digits)

Can store whole numbers and +/- 1.7e +/- 308


Double floating
Double decimal numbers with a higher (~15 digits)
point
precision e.g 54.4348584858584

Integer with a wider range -2,147,483,647


Long integer long int
to 2,147,483,647

STRING String Stores a chain of characters

Several of the basic types can be modified using one or more of these type modifiers:

 signed

 unsigned

 short

 long

Table 5.1 shows the variable type, how much memory it takes to store the value in memory, and
what is maximum and minimum vaue which can be stored in such type of variables. (Stroustrup,
Variables and Data types, 1997)

The sizes of variables might be different from those shown in the above table, depending on the
compiler and the computer you are using. (Stroustrup, 1997)

55
5.3.2 Variable Definition in C++

A variable definition means to tell the compiler where and how much to create the storage for the
variable. A variable definition specifies a data type, and contains a list of one or more variables
of that type as follows:

type variable_list;
Here, type must be a valid C++ data type including char, w_char, int, float, double, bool or any
user-defined object, etc., and variable_list may consist of one or more identifier names separated
by commas. Some valid declarations are shown here:

int i, j, k;
char c, ch;
float f, salary;
double d;

The line int i, j, k; both declares and defines the variables i, j and k; which instructs the compiler
to create variables named i, j and k of type int.
When naming variables the following rules apply
1. a variable name cannot start with a number e.g ‘2Age’ is wrong. They can however have
a number in between e.g ‘Age2’ is a valid variable name.
2. Spaces are not allowed in variable names. Eg ‘Pupil Name’ is not valid. Such a variable
can be written with underscores as ‘Pupil_Name’ or ‘PupiName’
3. Variables should be named intelligently ie the name should be a reflection of the nature
of the values it is stroring. For example a variable storing the age of a puil is better off
named as ‘Pupil_Age’ instead of ‘A’ or ‘PA’. This is not really a rule of syntax but a
good programming practice and it contributes to the readability of a program.

A variable declaration provides assurance to the compiler that there is one variable existing with
the given type and name so that compiler proceed for further compilation without needing
complete detail about the variable. A variable declaration has its meaning at the time of
compilation only, compiler needs actual variable declaration at the time of linking of the
program.

5.3.3 Initializing Variables

Variables can be initialized (assigned an initial value) in their declaration. The initializer consists
of an equal sign followed by a constant expression as follows:

type variable_name = value;

after the variables are declared, it can later on be assigned a value. The equal sign (=) is used to
assign a value to a variable as the following example can show

56
int d = 3, f = 5; // definition and initializing d and f.
char x = 'x'; // the variable x has the value 'x'.
#include <iostream>
using namespace std;

int main ()
{
// Variable definition:
int a, b;
int c;
float f;

// actual initialization
a = 10; // assign the value 10 to variable a
b = 20; // assign the value 20 to variable a
c = a + b; //add the value of a and and store the value in c

cout << c << endl ;

f = 70.0/3.0;
cout << f << endl ;

return 0;
}

(Kent, 2004)

When the above code is compiled and executed, it produces the following result:

30
23.3333

The statement cout << c << endl ; displays the value that is stores in the variable c and moves
the cursor into the next line because of the ‘endl’;

Take note that variable do not assume the same value throughout the program. Once assigned a
value, does not mean the variable will assume the same value all the time for example if we have
the statement;

a = 10; // assign the value 10 to variable a


b = 20; // assign the value 20 to variable a
c = a + b; //add the value of a and and store the value in c

we can still assign a new value to the variable a e.g

a = 15; // assign the value 10 to variable a

57
This will not result into an error but will just overwrite the value written in a with the new value,
in this case 15.

5.4 Arithmetic Operators

An operator is a symbol that represents a specific action. We have discussed and used operators
in prior chapters, including the assignment operator, =. C++ also supports operators for
arithmetic, specifically addition, subtraction, multiplication, and division. Operators used for
arithmetic are called, naturally enough, arithmetic operators. Table 5.2 summarizes them.

Table 5.2: Arithmetic Operators (Kent, 2004)

Operator Purpose Example Result


+ Addition 5+2 7
- Subtraction 5–2 3
* Multiplication 5*2 10
/ Division (Quotient) 5/2 2
% Division (Remainder) 5%2 1

The % operator, also called the modulus operator, may look unfamiliar. It returns the remainder
in division.

5.5 Getting Input From the User

It is not usually the case that we need to assign values to variables in a program. Normally,
values for values are entered by the user. All we do is declare the variable and create a provision
for the user to enter the values.

Key: getting input from the user is done using the “cin” reserved word, which is read as ‘c in’.
the basic syntax is as follows

cin>>VariableName;

Take a look at the following example.

58
#include <iostream>
using namespace std;
int main(void)
{
int num;
cout << "Enter a whole number: ";
cin >> num; // captures the number entered by user into the variable num
cout << "The number is even" << endl;
return 0;
}

5.5 The If Statement

The if statement is used to execute code only when the value of a relational expression is true.
The syntax of an if statement is;

if (Boolean value)
statement;

Both lines together are called an if statement. The first line consists of the if keyword followed
by an expression, such as a relational expression, that evaluates to a Boolean value, true or false.
The relational (or other Boolean) expression must be in parentheses, and should not be
terminated with a semicolon.

The next line is called a conditional statement. Remember that a statement is an instruction to the
computer, directing it to perform a specific action. The statement is conditional because it
executes only if the value of the relational expression is true. If the value of the relational
expression is false, then the conditional statement is not executed—meaning, it’s essentially
skipped.

The following program, which tests if a whole number entered by the user is even, illustrates the
use of an if statement.

#include <iostream>
using namespace std;
int main(void)
{
int num;
cout << "Enter a whole number: ";
cin >> num;
if ( num % 2 == 0 )
cout << "The number is even" << endl;
return 0;

59
}

If the user enters an even number, then the program outputs that the number is even.

Enter a whole number: 16


The number is even

However, if the user enters an odd number, then there is no output that the number is even.

Enter a whole number: 17

5.5.1 The if / else Statement

One problem with the program that tests whether a number is even is that there is no output if the
number is odd. While there is a conditional statement if the relational expression is true, there is
no corresponding conditional statement (cout << “The number is odd”) if the relational
expression is false.

The solution is to add an else part to the if statement. The result is an if / else statement. The
syntax of an if / else statement is

if (relational expression)
conditional statement;
else
conditional statement;

Accordingly, the program may be modified to add an else part to the if statement:

#include <iostream>
using namespace std;
int main(void)
{
int num;
cout << "Enter a whole number: ";
cin >> num;
if ( num % 2 == 0 )
cout << "The number is even" << endl;
else
cout << "The number is odd" << endl;
return 0;
}

Run this code. If the inputted number is even, then the output once again is “The number is
even.” However, if the number is now odd, instead of no output, the output is “The number is
odd.”

60
Enter a whole number: 17
The number is odd

Read through the following program and interpret it. Write down the output of this program i,e
write what the program will be priting on the screen wherever there is a cout.

#include <iostream>
using namespace std;
int main(void)
{
int age;
char choice;
bool citizen;
cout << "Enter your age: ";
cin >> age;
cout << "Are you a citizen (Y/N): ";
cin >> choice;
if (choice == 'Y')
citizen = true;
else
citizen = false;
if (age >= 18)
if(citizen == true)
cout << "You are eligible to vote";
else
cout << "You are not eligible to vote";
else
cout << "You are not eligible to vote";
return 0;

Check the solution from the following source: (Kent, Nested if Statements, 2004)

UNIT SUMMARY

 A variable is a memory location reserved to store a value of a specific type

61
 Data type is a specification of the kind of variables stored in a variable

 cout is used to display values and text in a program while cin is used for getting input
from the user.

 Common data tyes in programming languages include Boolean, integers, floating point
number, characters, strings e.t.c

 Integers store whole numbers

 Floating point numbers store decimals and whole number

 Booleans stores the values true or false

 String store any variable involving the use of text

 The if-else statements used in combination with an appropriate condition is used to


implement selection in C++

UNIT 6

62
STRUCTURED PROGRAMMING

Resources you will need: internet, computer

You are advised to spend 6 hours on this unit

6.0 Introduction

Structured programming is one way of programming aimed at improving the clarity, quality, and
development time of a computer program by making extensive use of subroutines, block
structures and for and while loops—in contrast to using simple tests and jumps such as the goto
statement which could lead to "spaghetti code" which is both difficult to follow and to maintain.
It has also been defined as a technique for organizing and coding computer programs in which a
hierarchy of modules is used, each having a single entry and a single exit point, and in which
control is passed downward through the structure without unconditional branches to higher levels
of the structure.

Three types of control flow are used: sequential, test (commonly known as selection), and
iteration.

6.1 Control Structures Used in Structured Programming

At a low level, structured programs are often composed of simple, hierarchical program flow
structures. These are sequence, selection, and repetition:

63
 "Sequence" refers to an ordered execution of statements.
 In "selection" one of a number of statements is executed depending on the state of the
program. This is usually expressed with keywords such as if..then..else..endif, switch, or
case. In some languages keywords cannot be written verbatim, but must be stropped.
 In "repetition" a statement is executed until the program reaches a certain state, or
operations have been applied to every element of a collection. This is usually expressed
with keywords such as while, repeat, for or do..until. Often it is recommended that each
loop should only have one entry point (and in the original structural programming, also
only one exit point, and a few languages enforce this).

Remember that this has been covered earlier on when we were looking at algorithms. The same
principles apply here.

Sequence selection repetition

Figure 6.1 Graphical representations of the three basic patterns.

The box diagrams represent the sequence of statements to executed while the diagram right next
to it represents the equivalent flowchats. (Wikipedia, 2006)

Many languages do support structured programming, of course with variations across several
languages. There are however similarities in structures among all programming languages. You
must recall from our lesson about algorithms that implementing a programs involves use of
conditions, ie a statements that can evaluate to true or false depending values involved. In many
languages, these are called Conditional statements, conditional expressions and conditional
constructs. These are features of a programming language which perform different computations
or actions depending on whether a programmer-specified boolean condition evaluates to true or
false. Apart from the case of branch predication, this is always achieved by selectively altering
the control flow based on some condition. This implies that the as the program is running, it
comes across a condition, then decides to run over (to execute) a block of statements depending
on whether the condition is true of false. Lets now examine common structures used to
implement structured programming.

64
6.2 Selection Structures

6.2.1 If–then (–else)

The if–then construct (sometimes called if–then–else) is common across many programming
languages. Although the syntax varies quite a bit from language to language, the basic structure
(in pseudocode form) looks like this:

IF (boolean condition) THEN


Statement 1
Statement 2
Statement 3
ELSE
Statement 4
Statement 5
Statement 6
END IF

When an interpreter finds an If, it expects a boolean condition – for example, x > 0, which means
"the variable x contains a number that is greater than zero" – and evaluates that condition. If the
condition is true, the statements following the then are executed. Otherwise, the execution
continues in the following branch – either in the else block (which is usually optional), or if there
is no else branch, then after the end If.

In this case its either statements 1 to 3 will be executed or statements 4 to 6 if the condition is
true of false respectively.

If statements can be nested further as the following example shows.

if condition then
--statements
Else
if condition then
-- more statements
Else
if condition then
- more statements;
...
End if
End if
End if

65
This creates a multiway selection structure where there is a chain of conditions that depend on
other condition. The key still remains the same: a block of statements will be executed or others
will depending on the conditions.

If all terms in the sequence of conditionals are testing the value of a single expression (e.g., if x
== 0 ... else if x == 1 ... else if x == 2), then an alternative is the switch statement.

6.2.2 The Switch

You must, at least by now, know that the if statements just depends on a condition being true or
false. What if we have a situation where we say if this variable is say 1, they execute statements
1, if it is 2 they execute statement 2, if it is 3 then execute statement 3,… how can we implement
this? The other case of selection is the use of the switch statement. Look at the examples below.
In this example the Value can have different options. It is like multiple choice. Depending on the
value of Value, the program decides to execute different blocks of statements.

switch(Value)
{
case value1:
statement(s);
break;
case value2:
statement(s);
break;
case value3:
statement(s);
break;
default:
statement(s);
}

(Gookin, 2010)

When we want to implement multiple choice, we use the switch statements instead of the if-else
structure. Remember that it is also used to implement the selection structure.

66
6.3 Repetition Structures

This allows us to run a set of statements more than once. This is implemented using loops. Loops
are basically repetition structures in programming languages. We will examine some of the
common loops used in a number programming languages. These are while, do while, and repeat.

6.3.1 While loop

This can be represented using a flowchat as shown below.

While loop (Wikipedia, 2006)

In most computer programming languages, a while loop is a control flow statement that allows
code to be executed repeatedly based on a given boolean condition. The while loop can be
thought of as a repeating if statement.

The while construct consists of a block of code and a condition. The condition is evaluated, and
if the condition is true, the code within the block is executed. This repeats until the condition
becomes false. Because while loop checks the condition before the block is executed, the control
structure is often also known as a pre-test loop. Compare with the do while loop, which tests the
condition after the loop has executed.

67
For example, in the C programming language (as well as Java, C# and C++, which use the same
syntax in this case), the code fragment

int x = 0;
while (x < 5)
{
cout<<x;
x = x+ 1;
}
The statements cout<<x; and x = x+ 1; are being repeated depeding on the condition specified
above as while (x < 5). This loop tests for the condition before it can execute the statements.

6.3.2 Do while loop

A do while loop is a control flow statement that allows code to be executed once based on a
given Boolean condition. Note though that unlike most languages, Fortran's do loop is actually
the same as the for loop. (Wikipedia, 2006)

The do while construct consists of a process symbol and a condition. First, the code within the
block is executed, and then the condition is evaluated. If the condition is true the code within the
block is executed again. This repeats until the condition becomes false. Because do while loops
check the condition after the block is executed, the control structure is often also known as a
post-test loop. Contrast with the while loop, which tests the condition before the code within the
block is executed.The do-while loop is an exit-condition loop. This means that the code must

68
always be executed first and then the expression or test condition is evaluated. If it is true, the
code executes the body of the loop again. This process is repeated as long as the expression
evaluates to true. If the expression is false, the loop terminates and control transfers to the
statement following the do-while loop.

It is possible, and in some cases desirable, for the condition to always evaluate to true, creating
an infinite loop. When such a loop is created intentionally, there is usually another control
structure (such as a break statement) that allows termination of the loop.

Some languages may use a different naming convention for this type of loop. For example, the
Pascal language has a "repeat until" loop, which continues to run until the control expression is
true (and then terminates) — whereas a "while" loop runs while the control expression is true
(and terminates once the expression becomes false).

6.3 Advantages Of Structured Programming

Structured application programs require more discipline at the design and logical structuring
stage but they can be coded more quickly. The time required to reach the testing stage is roughly
the same, but the benefits of SPs are significant from this point and onward.

Using the SPs requires a more disciplined approach to programming and, therefore, provides the
following advantages:

 Application programs are easier to read and understand.


 Application programs are less likely to contain logic errors.
 Errors are more easily found.
 Higher productivity during application program development.
 Improved application program design.
 Application programs are more easily maintained.

Using structured programming emphasizes:

 The total logic of an application program.


 What the application program does.
 What the logical flow through the application program should be.

69
EXERCISE: ANSWER THE FOLLOWING QUESTIONS

1. Define structured programming highlighting its advantages and disadvantages

2. Discuss the three types of structures used in structured programming

3. Differentiate between posttest and pretest loops citing examples.

4. Draw the flowchats for each of selection and repetition structures

UNIT SUMMARY

 Structured programming is a technique for organizing and coding computer programs in


which a hierarchy of modules is used, each having a single entry and a single exit point,
and in which control is passed downward through the structure without unconditional
branches to higher levels of the structure.
 Structured programs are often composed of simple, hierarchical program flow structures.
These are sequence, selection, and repetition
 Selection is implemented using the if-else, or switch. Repetition is implemented using
while, do while or repeat until.
 Posttest loops check for the condition after executing the statement while pretest loop
checks for the condition before executing statements

UNIT 7

70
MODULAR PROGRAMMING

Resources: computer, internet

You are advised to spend 10 hours on this unit

7.0 Introduction

A module is a separate software component. It can often be used in a variety of applications and
functions with other components of the system. Similar functions are grouped in the same unit of
programming code and separate functions are developed as separate units of code so that the
code can be reused by other applications. (Janssen, 2010)
Object-oriented programming (OOP) is compatible with the modular programming concept to a
large extent. Modular programming enables multiple programmers to divide up the work and
debug pieces of the program independently.

Modular programming is simply subdividing your program into separate subprograms such as
functions and subroutines. Use these. For example, if your program needs initial and boundary
conditions, use subroutines to set them. Then if someone else wants to compute a different
solution using your program, only these subroutines need to be changed. This is a lot easier than
having to read through a program line by line, trying to figure out what each line is supposed to
do and whether it needs to be changed. And in ten years from now, you yourself will probably no
longer remember how the program worked.

71
6.1 Why Use Modular Programming?

1. Subprograms make your actual program shorter, hence easier to read and understand.
Further, the arguments show exactly what information a subprogram is using. That makes
it easier to figure out whether it needs to be changed when you are modifying your
program. Forgetting to change all occurrences of a variable is a very common source of
errors.

2. Subprograms make it simpler to figure out how the program operates. If the boundary
conditions are implemented using a subroutine, your program can be searched for this
subroutine to find all places where the boundary conditions are used. This might include
some unexpected places, such as in the output, or in performing a numerical check on the
overall accuracy of the program.

3. Subprograms reduce the likely hood of bugs. Because subprograms can use local
variables, there is less change that the code in the subroutine interferes with that of the
program itself, or with that in other subprograms. The smaller size of the individual
modules also makes it easier to understand the global effects of changing a variable.
4. A single procedure can be developed for reuse, eliminating the need to retype the code
many times.
5. Programs can be designed more easily because a small team deals with only a small part
of the entire code.
6. Modular programming allows many programmers to collaborate on the same application.
7. The same code can be used in many applications – which is know as code re-use
8. The scoping of variables can easily be controlled.

Modules in modular programming enforce logical boundaries between components and improve
maintainability. They are incorporated through interfaces. They are designed in such a way as to
minimize dependencies between different modules. Teams can develop modules separately and
do not require knowledge of all modules in the system. (Janssen, 2010)

72
6.2 Types of Subprograms

There are two types of subprograms;

I. Procedure and
II. Functions (return type, name, arguments code block),

A procedure prescribes a group of instruction for parameterized computation, and defines a new
statement. A procedure produces results by altering either the parameters or the non-local
variable but does not have return value. It prescribes a group of instruction for parameterized
computation, and defines a new statement. A procedure produces results by altering either the
parameters or the non-local variable since it does not have return value.
A function models after a mathematic relation between a set of parameters and a return value,
therefore a function defines a new operator. A pure function produces result not by side effects,
but by the return value. Otherwise a function could work just like a procedure by side effects.
The major difference between the two is that a procedure does not return a value while a function
does. A function models after a mathematic relation between a set of parameters and a return
value, therefore a function defines a new operator. A pure function produces result not by side
effects, but by the return value. Otherwise a function could work just like a procedure by side
effects.
6.3 Implementing Subprograms
Subprogram is a form of process abstraction. Relative instructions for accomplishing a task are
grouped together as a logical unit. The concept not only saves space but also code development
efforts. A subprogram is basically a unit of the whole programming that performs a specific task.
It has a name, which can be used to call it form the main program or other subprograms. Take a
look at the program segment below.

// void function example I'm a function!


#include <iostream>
using namespace std;

void printmessage ()
{
cout << "I'm a function!";
}

int main ()
{
printmessage ();
return 0;

73
}

If you have understand how to write a program, in C++ you must understand the main () part of
the program. This is the main program, it being the first part of the program that is executed
when the program starts running. This can be also be referred to as a subprogram. The other
subprogram is the one with the label ‘print message’

6.3.1 General Subprogram Characteristics


 Each subprogram should have a single entry. This implies that each subprogram has got a
specific starting point
 The caller is suspended until the callee returns. In the above example the caller is the
main(). This makes a call to the printmessage() subrpgram. A call is basically a request to
execute the code in the called subprograms. The subprogram that is called is referred to
as the callee. When the callee is called, control shifts to the callee until all the code in the
callee has been executed then, it goes back to the caller.
 The caller resumes from the next instruction after the subroutine call.

6.3.2 Terms associated with Subprograms


Have you so far understood what a module is? It is also referred to as a subroutine. A subroutine
definition includes the interface that declares the function and the code that implements the
function. You need to understand the following terms;
 A subroutine call is the statement that invokes the subroutine. From the program shown
below (listing 7.1), the subroutine call is the statement AddNumbers(x,y) in the main
program is a subroutine call, which invokes (calls) the AddNumbers subroutine above.
 A subroutine is active if it has been invoked but not yet returns.
 A subroutine header starts the syntactical construction for a subroutine, and indicates the
name of the subroutine, plus a list of parameters. From the listing 7.1 below, the
subroutine name is Addnumbers, and the parameters are the integers a and b

// void function example 14


#include <iostream>
using namespace std;

int AddNumbers (int a, int b)


{
Int sum = a + b;
return sum;
}

int main ()
{
Int x, y;

74
x = 5;
y = 9;
cout<<AddNumbers(x,y);
return 0;
}
Program listing 7.1: subprogram example

This example will help you to understand the concepts that will be discussed below. It highlights
a good example of a subprogram. AddNumbers is a subprogram performing a specific task of
adding two numbers and return the sum.

6.3.3 Parameters
A subprogram can access the data outside by either parameter or non-local variables. The latter is
not as convenient as the former. Local variables are the variables declared inside a subprogram.
For example the variables a and b in the AddNumbers subprogram, the variable sum is a local
variable that is known only within that subprogram. The variables x and y in the main() are local,
ie only recognized inside the main().
In some cases a subprogram can be passed into another subprogram as a parameter for
programming flexibility. Given the program above

void AddNumbers (int a, int b)

the variables a and b are parameters. These are referred to as formal parameters. They are meant
to receive two integers, which the function calls a and b.
Keyword parameters map the actual parameters to formal ones by the names, and positional
parameters does it by the order actual parameters appear. Using keyword parameters requires the
knowledge of parameter names, but is more readable and reliable. Parameters may have default
values. They must appear last in the parameter list so that the compiler can determine the
mapping.

6.3.4 Passing Parameters by value and by Reference


In the function above, the arguments passed to the functions have been passed by value. This
means that when calling a function with parameters, what we have passed to the function were
copies of their values but never the variables themselves. For example, suppose that we called
our first function addition using the following code:

1 int x=5, y=3, z;


2 z = addition ( x , y );

What we did in this case was to call to function addition passing the values of x and y, i.e. 5 and

75
3 respectively, but not the variables x and y themselves.

This way, when the function addition is called, the value of its local variables a and b become 5
and 3 respectively, but any modification to either a or b within the function addition will not
have any effect in the values of x and y outside it, because variables x and y were not themselves
passed to the function, but only copies of their values at the moment the function was called.

But there might be some cases where you need to manipulate from inside a function the value of
an external variable. For that purpose we can use arguments passed by reference, as in the
function duplicate of the following example:

1 // passing parameters by reference x=2, y=6, z=14


2 #include <iostream>
3 using namespace std;
4
5 void duplicate (int& a, int& b, int& c)
6{
7 a*=2;
8 b*=2;
9 c*=2;
10 }
11
12 int main ()
13 {
14 int x=1, y=3, z=7;
15 duplicate (x, y, z);
16 cout << "x=" << x << ", y=" << y << ", z="
17 << z;
18 return 0;
}

The first thing that should call your attention is that in the declaration of duplicate the type of
each parameter was followed by an ampersand sign (&). This ampersand is what specifies that
their corresponding arguments are to be passed by reference instead of by value.

76
When a variable is passed by reference we are not passing a copy of its value, but we are
somehow passing the variable itself to the function and any modification that we do to the local
variables will have an effect in their counterpart variables passed as arguments in the call to the
function.

To explain it in another way, we associate a, b and c with the arguments passed on the function
call (x, y and z) and any change that we do on a within the function will affect the value of x
outside it. Any change that we do on b will affect y, and the same with c and z.

That is why our program's output, that shows the values stored in x, y and z after the call to
duplicate, shows the values of all the three variables of main doubled.

If when declaring the following function:

  void duplicate (int& a, int& b, int& c)

we had declared it this way:

  void duplicate (int a, int b, int c)

i.e., without the ampersand signs (&), we would have not passed the variables by reference, but a
copy of their values instead, and therefore, the output on screen of our program would have been
the values of x, y and z without having been modified.

Passing by reference is also an effective way to allow a function to return more than one value.
For example, here is a function that returns the previous and next numbers of the first parameter
passed. (Kent, 2004)

1 // more than one returning value Previous=99, Next=101


2 #include <iostream>
3 using namespace std;
4
5 void prevnext (int x, int& prev, int& next)
6{
7 prev = x-1;

77
8 next = x+1;
9}
10
11 int main ()
12 {
13 int x=100, y, z;
14 prevnext (x, y, z);
15 cout << "Previous=" << y << ", Next=" <<
16 z;
17 return 0;
}

UNIT SUMMARY

We have covered a number of things in this unit. The most important things are the following;

 A module is a separate software component. It can often be used in a variety of


applications and functions with other components of the system
 Modular programming is simply subdividing your program into separate subprograms
such as functions and subroutines.
 There are two types of subprograms; Procedure (which do not return a value after
executing) and Functions (which returns a value after executing)
 A subroutine call is the statement that invokes the subroutine
 Parameters are values passed to a subroutine. These can be passed either by reference or
by value.
 There are two levels of variable scope: local and global.
 Local variables are declared inside a subroutine. They are accessible only from inside the
subroutine where they are declared.
 Global variables are declared outside any subroutine and are accessible from anywhere in
the program

78
f

UNIT 8

79
DATA STRUCTURES- STORAGE AND ORGANISATION OF DATA

Resources: Computer, internet

You are advised to spend about 12 hour on this unit

8.0 What is a Data Structure?

A data structure is a particular way of storing and organizing data in a computer so that it can be
used efficiently. It can also be defined as a collection of data items, in addition a number of
operations are provided by the software to manipulate the data structure.

Different kinds of data structures are suited to different kinds of applications, and some are
highly specialized to specific tasks. For example, B-trees are particularly well-suited for
implementation of databases, while compiler implementations usually use hash tables to look up
identifiers.

Data structures provide a means to manage large amounts of data efficiently, such as large
databases and internet indexing services. Usually, efficient data structures are a key to designing
efficient algorithms. Some formal design methods and programming languages emphasize data
structures, rather than algorithms, as the key organizing factor in software design. Storing and
retrieving can be carried out on data stored in both main memory and in secondary memory.

8.1 Primitive data type

80
A primitive data type is either of the following:

1. basic type is a data type provided by a programming language as a basic building block.
Most languages allow more complicated composite types to be recursively constructed
starting from basic types.
2. built-in type is a data type for which the programming language provides built-in support.

In most programming languages, all basic data types are built-in. In addition, many languages
also provide a set of composite data types. Opinions vary as to whether a built-in type that is not
basic should be considered "primitive".

Depending on the language and its implementation, primitive data types may or may not have a
one-to-one correspondence with objects in the computer's memory. However, one usually
expects operations on basic primitive data types to be the fastest language constructs there are.
Integer addition, for example, can be performed as a single machine instruction, and some
processors offer specific instructions to process sequences of characters with a single instruction.
Most languages do not allow the behavior or capabilities of primitive (either built-in or basic)
data types to be modified by programs. Exceptions include Smalltalk, which permits all data
types to be extended within a program, adding to the operations that can be performed on them
or even redefining the built-in operations.

8.2 Composite data type

A composite data type is any data type which can be constructed in a program using its
programming language's primitive data types and other composite types. The act of constructing
a composite type is known as composition.

Examples of composite data types include records, classes, structures (c++)

8.3 Dynamic and Static data structures

8.3.1 Static Data Structure

With a static data structure, the size of the structure is fixed.

Static data structures are very good for storing a well-defined number of data items.

81
For example a programmer might be coding an 'Undo' function where the last 10 user actions are
kept in case they want to undo their actions. In this case the maximum allowed is 10 steps and so
he decides to form a 10 item data structure.

8.3.2 Dynamic Data Structure

There are many situations where the number of items to be stored is not known before hand.

In this case the programmer will consider using a dynamic data structure. This means the data
structure is allowed to grow and shrink as the demand for storage arises. The programmer should
also set a maximum size to help avoid memory collisions.

For example a programmer coding a print spooler will have to maintain a data structure to store
print jobs, but he cannot know before hand how many jobs there will be. The table 8.1 below
compared the two approaches.

Table 8.1 A comparison of dynamic and static data structures

Dynamic and Static data structures


DYNAMIC STATIC
Memory is allocated to the data structure Memory is allocated at compile time.
dynamically i.e. as the program executes. Fixed size.
Disadvantage: Because the memory Advantage: The memory allocation is
allocation is dynamic, it is possible for the fixed and so there will be no problem
structure to 'overflow' should it exceed its with adding and removing data items.
allowed limit. It can also 'underflow'
should it become empty.  
Advantage: Makes the most efficient use Disadvantage: Can be very inefficient
of memory as the data structure only uses as the memory for the data structure has
as much memory as it needs been set aside regardless of whether it
is needed or not whilst the program is
executing.
Disadvantage: Harder to program as the Advantage: Easier to program as there
software needs to keep track of its size and is no need to check on data structure
data item locations at all times size at any point.

8.4 Basic principles

82
Data structures are generally based on the ability of a computer to fetch and store data at any
place in its memory, specified by an address—a bit string that can be itself stored in memory and
manipulated by the program. Thus the record and array (examples of data structures) data
structures are based on computing the addresses of data items with arithmetic operations; while
the linked data structures are based on storing addresses of data items within the structure itself.
Many data structures use both principles.

8.5 Abstract data types

An abstract data type (ADT) is a mathematical model for a certain class of data structures that
have similar behavior; or for certain data types of one or more programming languages that have
similar semantics. An abstract data type is defined indirectly, only by the operations that may be
performed on it and by mathematical constraints on the effects (and possibly cost) of those
operations.

For example, an abstract stack could be defined by three operations: push, that inserts some data
item onto the structure, pop, that extracts an item from it (with the constraint that each pop
always returns the most recently pushed item that has not been popped yet), and peek, that allows
data on top of the structure to be examined without removal. When analyzing the efficiency of
algorithms that use stacks, one may also specify that all operations take the same time no matter
how many items have been pushed into the stack, and that the stack uses a constant amount of
storage for each element.

Abstract data types are purely theoretical entities, used (among other things) to simplify the
description of abstract algorithms, to classify and evaluate data structures, and to formally
describe the type systems of programming languages. However, an ADT may be implemented
by specific data types or data structures, in many ways and in many programming languages; or
described in a formal specification language. ADTs are often implemented as modules: the
module's interface declares procedures that correspond to the ADT operations, sometimes with
comments that describe the constraints. This information hiding strategy allows the
implementation of the module to be changed without disturbing the client programs. The
following are some examples of abstract data structures.

8.5.1 Queues

83
A queue is a particular kind of abstract data type or collection in which the entities in the
collection are kept in order and the principal (or only) operations on the collection are the
addition of entities to the rear terminal position, known as enqueue, and removal of entities from
the front terminal position, known as dequeue. This makes the queue a First-In-First-Out (FIFO)
data structure. In a FIFO data structure, the first element added to the queue will be the first one
to be removed. This is equivalent to the requirement that once a new element is added, all
elements that were added before have to be removed before the new element can be removed.
Often a peek or front operation is also implemented, returning the value of the front element
without dequeuing it. A queue is an example of a linear data structure, or more abstractly a
sequential collection.

Figure 8.1 Representation of a Queue with FIFO (First In First Out) property

Queues provide services in computer science, transport, and operations research where various
entities such as data, objects, persons, or events are stored and held to be processed later. In these
contexts, the queue performs the function of a buffer.

Queues are common in computer programs, where they are implemented as data structures
coupled with access routines, as an abstract data structure or in object-oriented languages as
classes. Common implementations are circular buffers and linked lists.

APPLICATION OF QUEUES

Queues are used for any situation where you want to efficiently maintain a First-in-first out order
on some entities. These situations arise literally in every type of software development.

Imagine you have a web-site which serves files to thousands of users. You cannot service all
requests, you can only handle say 100 at once. A fair policy would be first-come-first serve:
serve 100 at a time in order of arrival. A Queue would definitely be the most appropriate data
structure.

84
Similarly in a multitasking operating system, the CPU cannot run all jobs at once, so jobs must
be batched up and then scheduled according to some policy. Again, a queue might be a suitable
option in this case. The same applies for a printer which creates schedule of printing jobs on first
come first serve basis

8.5.2 Stack (abstract data type)

Figure 8.2 Simple representation of a stack (source: wikepedia)

A stack is a particular kind of abstract data type or collection in which the principal (or only)
operations on the collection are the addition of an entity to the collection, known as push and
removal of an entity, known as pop. The relation between the push and pop operations is such
that the stack is a Last-In-First-Out (LIFO) data structure. In a LIFO data structure, the last
element added to the structure must be the first one to be removed. This is equivalent to the
requirement that, considered as a linear data structure, or more abstractly a sequential collection,
the push and pop operations occur only at one end of the structure, referred to as the top of the
stack. Often a peek or top operation is also implemented, returning the value of the top element
without removing it.

A stack may be implemented to have a bounded capacity. If the stack is full and does not contain
enough space to accept an entity to be pushed, the stack is then considered to be in an overflow
state. The pop operation removes an item from the top of the stack. A pop either reveals
previously concealed items or results in an empty stack, but, if the stack is empty, it goes into
underflow state, which means no items are present in stack to be removed.

A stack is a restricted data structure, because only a small number of operations are performed
on it. The nature of the pop and push operations also means that stack elements have a natural
order. Elements are removed from the stack in the reverse order to the order of their addition.
Therefore, the lower elements are those that have been on the stack the longest.

85
Applications Of Stacks Data Structures

Stacks have numerous applications. We see stacks in everyday life, from the books in our library,
to the sheaf of papers that we keep in our printer tray. All of them follow the Last In First Out
(LIFO) logic, that is when we add a book to a pile of books, we add it to the top of the pile,
whereas when we remove a book from the pile, we generally remove it from the top of the pile.

Given below are a few applications of stacks in the world of computers:

Converting a decimal number into a binary number

To solve this problem, we use a stack. We make use of the LIFO property of the stack. Initially
we push the binary digit formed into the stack, instead of printing it directly. After the entire
number has been converted into the binary form, we pop one digit at a time from the stack and
print it. Therefore we get the decimal number converted into its proper binary form.

Towers of Hanoi

One of the most interesting applications of stacks can be found in solving a puzzle called Tower
of Hanoi. According to an old Brahmin story, the existence of the universe is calculated in terms
of the time taken by a number of monks, who are working all the time, to move 64 disks from
one pole to another. But there are some rules about how this should be done, which are:

1. move only one disk at a time.


2. for temporary storage, a third pole may be used.
3. a disk of larger diameter may not be placed on a disk of smaller diameter.[8]

Expression evaluation and syntax parsing

Calculators employing reverse Polish notation use a stack structure to hold values. Expressions
can be represented in prefix, postfix or infix notations and conversion from one form to another
may be accomplished using a stack. Many compilers use a stack for parsing the syntax of
expressions, program blocks etc. before translating into low level code. Most programming
languages are context-free languages, allowing them to be parsed with stack based machines.

86
Backtracking

Another important application of stacks is backtracking. Consider a simple example of finding


the correct path in a maze. There are a series of points, from the starting point to the destination.
We start from one point. To reach the final destination, there are several paths. Suppose we
choose a random path. After following a certain path, we realise that the path we have chosen is
wrong. So we need to find a way by which we can return back to the beginning of that path. This
can be done with the use of stacks. With the help of stacks, we remember the point where we
have reached. This is done by pushing that point into the stack. In case we end up on the wrong
path, we can pop the last point from the stack and thus return back to the last point and continue
our quest to find the right path. This is called backtracking.

Quicksort

Sorting means arranging the list of elements in a particular order. In case of numbers, it could be
in ascending order, or in the case of letters, alphabetic order.

This is done by using two stacks called LOWERBOUND and UPPERBOUND, to temporarily
store these partitions. The addresses of the first and last elements of the partitions are pushed into
the LOWERBOUND and UPPERBOUND stacks respectively. Now, the above reduction step is
applied to the partitions only after its boundary values are popped from the stack.

8.5.3 Trees (ADT)

A tree is a widely used abstract data type (ADT) or data structure that simulates a hierarchical
structure. A tree data structure can be defined recursively (locally) as a collection of nodes
(starting at a root node), where each node is a data structure consisting of a value, together with a
list of references to nodes (the "children"), with the constraints that no reference is duplicated,
and none points to the root.

Alternatively, a tree can be defined abstractly as a whole (globally) as an ordered tree, with a
value assigned to each node. Both these perspectives are useful: while a tree can be analyzed
mathematically as a whole, when actually represented as a data structure it is usually represented
and worked with separately by node (rather than as a list of nodes and an adjacency list of edges
between nodes, as one may represent a digraph, for instance). For example, looking at a tree as a
whole, one can talk about "the parent node" of a given node, but in general as a data structure a
given node only contains the list of its children, but does not contain a reference to its parent (if
any).

87
Figure 8.3 Binary tree data structure example

In figure 8.3, the node labeled 7 has two children, labeled 2 and 6, and one parent, labeled 2. The
root node (2), at the top, has no parent.

Binary Tree Terminology

A node is a structure which may contain a value or condition, or represent a separate data
structure (which could be a tree of its own). Each node in a tree has zero or more child nodes,
which are below it in the tree (by convention, trees are drawn growing downwards). A node that
has a child is called the child's parent node (or ancestor node, or superior). A node has at most
one parent.

The topmost node in a tree is called the root node. Depending on definition, a tree may be
required to have a root node (in which case all trees are non-empty), or may be allowed to be
empty, in which case it does not necessarily have a root node. Being the topmost node, the root
node will not have a parent.

All other nodes can be reached from it by following edges or links. (In the formal definition,
each such path is also unique.) In diagrams, the root node is conventionally drawn at the top. In
some trees, such as heaps, the root node has special properties. Every node in a tree can be seen
as the root node of the subtree rooted at that node.

The height of a node is the length of the longest downward path to a leaf from that node. The
height of the root is the height of the tree. The depth of a node is the length of the path to its root
(i.e., its root path).

88
A subtree of a tree T is a tree consisting of a node in T and all of its descendants in T. Nodes thus
correspond to subtrees (each node corresponds to the subtree of itself and all its descendants) –
the subtree corresponding to the root node is the entire tree, and each node is the root node of the
subtree it determines; the subtree corresponding to any other node is called a proper subtree (in
analogy to the term proper subset).

Traversal methods

Stepping through the items of a tree, by means of the connections between parents and children,
is called walking the tree, and the action is a walk of the tree. Often, an operation might be
performed when a pointer arrives at a particular node. A walk in which each parent node is
traversed before its children is called a pre-order walk; a walk in which the children are traversed
before their respective parents are traversed is called a post-order walk; a walk in which a node's
left subtree, then the node itself, and finally its right subtree are traversed is called an in-order
traversal. (This last scenario, referring to exactly two subtrees, a left subtree and a right subtree,
assumes specifically a binary tree.) A level-order walk effectively performs a breadth-first search
search over the entirety of a tree; nodes are traversed level by level, where the root node is
visited first, followed by its direct child nodes and their siblings, followed by its grandchild
nodes and their siblings, etc., until all nodes in the tree have been traversed.

Unlike linear data structures (Array, Linked List, Queues, Stacks, etc) which have only one
logical way to traverse them, trees can be traversed in different ways. Following are the
generally used ways for traversing trees.

Figure 8.4 Binary tree to demonstrate traversal

The following are depth First Traversals;


(a) Inorder

89
(b) Preorder
(c) Postorder

Inorder Traversal:

Algorithm Inorder(tree)
1. Traverse the left subtree, i.e., call Inorder(left-subtree)
2. Visit the root.
3. Traverse the right subtree, i.e., call Inorder(right-subtree)

Uses of Inorder
In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order. To
get nodes of BST in non-increasing order, a variation of Inorder traversal where Inorder
itraversal s reversed, can be used.
Example: Inorder traversal for the above given figure 8.4 is 4 2 5 1 3.

Preorder Traversal:

Algorithm Preorder(tree)
1. Visit the root.
2. Traverse the left subtree, i.e., call Preorder(left-subtree)
3. Traverse the right subtree, i.e., call Preorder(right-subtree)

Uses of Preorder
Preorder traversal is used to create a copy of the tree. Preorder traversal is also used to get prefix
expression on of an expression tree. Example: Preorder traversal for the above given figure 8.5 is
1 2 4 5 3.

Postorder Traversal:

Algorithm Postorder(tree)
1. Traverse the left subtree, i.e., call Postorder(left-subtree)
2. Traverse the right subtree, i.e., call Postorder(right-subtree)
3. Visit the root.

Uses of Postorder
Postorder traversal is used to delete the tree. Postorder traversal is also useful to get the postfix
expression of an expression tree.

90
Common Application Of Trees

 Representing hierarchical data


 Storing data in a way that makes it easily searchable
 Representing sorted lists of data
 As a workflow for compositing digital images for visual effects. Digital compositing is
the process of digitally assembling multiple images to make a final image, typically for
print, motion pictures or screen display. It is the evolution into the digital realm of optical
film compositing
 Routing algorithms

8.5.4 Linked lists

A linked list is a data structure consisting of a group of nodes which together represent a
sequence. Under the simplest form, each node is composed of a data and a reference (in other
words, a link) to the next node in the sequence; more complex variants add additional links. This
structure allows for efficient insertion or removal of elements from any position in the sequence.

Figure 8.6 Linked list data structure example (source: wikepedia)

Figure 8.6 shows a linked list whose nodes contain two fields: an integer value and a link to the
next node. The last node is linked to a terminator used to signify the end of the list.

Linked lists are among the simplest and most common data structures. They can be used to
implement several other common abstract data types, including lists (the abstract data type),
stacks, queues, associative arrays, and S-expressions, though it is not uncommon to implement
the other data structures directly without using a list as the basis of implementation.

The principal benefit of a linked list over a conventional array is that the list elements can easily
be inserted or removed without reallocation or reorganization of the entire structure because the
data items need not be stored contiguously in memory or on disk. Linked lists allow insertion

91
and removal of nodes at any point in the list, and can do so with a constant number of operations
if the link previous to the link being added or removed is maintained during list traversal.

On the other hand, simple linked lists by themselves do not allow random access to the data, or
any form of efficient indexing. Thus, many basic operations — such as obtaining the last node of
the list (assuming that the last node is not maintained as separate node reference in the list
structure), or finding a node that contains a given datum, or locating the place where a new node
should be inserted — may require scanning most or all of the list elements.

Singly linked list

Singly linked lists contain nodes which have a data field as well as a next field, which points to
the next node in the linked list.

Figure 8.7 singly linked list

Doubly linked list

In a doubly linked list, each node contains, besides the next-node link, a second link field
pointing to the previous node in the sequence. The two links may be called forward(s) and
backwards, or next and prev(ious).

Figure 8.8 Doubly linked list (source:wikepedia)

8.5.5 Arrays

92
An array is a series of elements of the same type placed in contiguous memory locations that can
be individually referenced by adding an index to a unique identifier. This can be illustrated by
the following diagram.

Figure 8.9 Array data structure representation

That means that, for example, we can store 5 values of type int in an array without having to
declare 5 different variables, each one with a different identifier. Instead of that, using an array
we can store 5 different values of the same type, int for example, with a unique identifier.

For example, an array to contain 5 integer values of type int called billy could be represented like
this:

where each blank panel represents an element of the array, that in this case are integer values of
type int. These elements are numbered from 0 to 4 since in arrays the first index is always 0,
independently of its length. (Kent, Arrays, 2004)

Like a regular variable, an array must be declared before it is used. A typical declaration for an
array in C++ is:

type name [elements];

where type is a valid type (like int, float...), name is a valid identifier and the elements field
(which is always enclosed in square brackets []), specifies how many of these elements the array
has to contain.

Therefore, in order to declare an array called billy as the one shown in the above diagram it is as
simple as:

  int billy [5];

NOTE: The elements field within brackets [] which represents the number of elements the array

93
is going to hold, must be a constant value, since arrays are blocks of non-dynamic memory
whose size must be determined before execution. In order to create arrays with a variable length
dynamic memory is needed, which is explained later in these tutorials.

Initializing Arrays

When declaring a regular array of local scope (within a function, for example), if we do not
specify otherwise, its elements will not be initialized to any value by default, so their content will
be undetermined until we store some value in them. The elements of global and static arrays, on
the other hand, are automatically initialized with their default values, which for all fundamental
types this means they are filled with zeros.

In both cases, local and global, when we declare an array, we have the possibility to assign initial
values to each one of its elements by enclosing the values in braces { }. For example:

  int billy [5] = { 16, 2, 77, 40, 12071 };

This declaration would have created an array like this:

The amount of values between braces { } must not be larger than the number of elements that we
declare for the array between square brackets [ ]. For example, in the example of array billy we
have declared that it has 5 elements and in the list of initial values within braces { } we have
specified 5 values, one for each element.

When an initialization of values is provided for an array, C++ allows the possibility of leaving
the square brackets empty [ ]. In this case, the compiler will assume a size for the array that
matches the number of values included between braces { }:

  int billy [] = { 16, 2, 77, 40, 12071 };

an array can also be of strings, floats or other datatypes. Take an example. The Declaration
below,

94
string Names[20];

declares an array containing 20 slots or indexes, which can be used to store 20 names. The other
option for this declaration can be as below.

Names[] = {“James”,”Mwape”,”Chibangu”,……..,”Chileshe”}

assuming that the Last name Chileshe is the 20th name In the array. This is basically a list of 20
names.

Accessing Values in an Array

In any point of a program in which an array is visible, we can access the value of any of its
elements individually as if it was a normal variable, thus being able to both read and modify its
value. The format is as simple as:

Array_name[index]

Following the previous examples in which billy had 5 elements and each of those elements was
of type int, the name which we can use to refer to each element is the following:

For example, to store the value 75 in the third element of billy, we could write the following
statement:

  billy[2] = 75;

and, for example, to pass the value of the third element of billy to a variable called a, we could
write:

  a = billy[2];

Therefore, the expression billy[2] is for all purposes like a variable of type int.
Notice that the third element of billy is specified billy[2], since the first one is billy[0], the
second one is billy[1], and therefore, the third one is billy[2]. By this same reason, its last
element is billy[4]. Therefore, if we write billy[5], we would be accessing the sixth element of
billy and therefore exceeding the size of the array. We can in the same manner access the values
stores in the Names array. For the example, the statement below displays the name “Chibangu”

95
cout<<Names[2]

In C++ it is syntactically correct to exceed the valid range of indices for an array. This can create
problems, since accessing out-of-range elements do not cause compilation errors but can cause
runtime errors.

What are Advantages and Disadvantages of arrays?


Advantages include the following; 

1. It is used to represent multiple data items of same type by using only single name.
2. It can be used to implement other data structures like linked lists, stacks, queues, trees,
graphs etc.
3. 2D arrays are used to represent matrices.
4. Data accessing is faster: Using arrays, we can access any data item efficiently just by
specifying the index of that item

Disadvantages include the following;

1. We must know in advance that how many elements are to be stored in array. They should
be predefined before we use them.
2. Array is static structure. It means that array is of fixed size. The memory which is
allocated to array cannot be increased or reduced.
3. Since array is of fixed size, if we allocate more memory than requirement then the
memory space will be wasted. And if we allocate less memory than requirement, then it
will create problem. In static allocation technique, a fixed amount of memory is allocated
before the start of execution for static arrays and during execution for dynamic arrays.
The memory required for most of the applications often cannot be predicted while writing
a program. If more memory is allocated and the application requires less memory, it
results in wastage of memory space. If less memory space is allocated and if the
applications require more memory space during execution, it is not possible to allocate
extra memory for arrays during execution.
4. The elements of array are stored in consecutive memory locations. So insertions and
deletions are very difficult and time consuming.

96
EXERCISE

1. Write brief and concise notes on the following

a) Trees
b) Queues
c) Stacks
d) Linked lists
e) Arrays

2. Compare Static and dynamic data structures

3. Given the following binary tree, write the results of traversing it in

a) Inorder
b) Preorder
c) Postorder

97
UNIT SUMMARY

We have covered the following points in this unit;


 A data structure is a particular way of storing and organizing data in a computer so that it
can be used efficiently.
 Static data structures have a fixed size which cannot grow or shrink while dynamic data
structures can grow or shrink in size.
 Primitive data types refers to the basic data types found in programming languages like
integers, strings
 Composite data structures are made up two or more primitive data types
 Stacks are abstract data structures that use the first in last out principle. Addition and
removal re both done on the same end.
 Queues are abstract data structures that use the first in first out data principle. Addition of
data is done at the back while removal is done from the front.
 Linked lists are abstract data structures made up of nodes linked together. The nodes
compose of data and a pointer or link to the next node
 An array is a sequence of data of the same type, in which the elements can be accessed
using an index

98
UNIT 9

DEBUGGING AND TESTING

Resources: Computer, internet

You are advised to spend about 8 hour on this unit

9.0 Introduction

Testing means verifying correct behavior. Testing can be done at all stages of module
development: requirements analysis, interface design, algorithm design, implementation, and
integration with other modules. In the following, attention will be directed at implementation
testing. Implementation testing is not restricted to execution testing. An implementation can also
be tested using correctness proofs, code tracing, and peer reviews, as described below.

Debugging is a cyclic activity involving execution testing and code correction. The testing that is
done during debugging has a different aim than final module testing. Final module testing aims
to demonstrate correctness, whereas testing during debugging is primarily aimed at locating
errors. This difference has a significant effect on the choice of testing strategies. It is quite
common to confuse the two terms. However, these are two different terms. While debugging
always has to do with code, it is not always the case with testing.

Let’s take a close look at the debugging and the techniques involved therein, then later we shall
look at testing.

99
9.1 Debugging

In order to carry out debugging properly, there are things which should be done first. We can
refer to these as preconditions. What do you think are some of these?

9.1.1Preconditions for Effective Debugging


In order to avoid excessive time spent on debugging, the programmer should be mentally
prepared for the effort. The following steps are useful to prepare for debugging.

 Understand the design and algorithm - If you are working on a module and you do not
understand its design or its algorithms, then debugging will be very difficult. If you don't
understand the design then you can't test the module because you do not know what it is
supposed to do. If you don't understand the algorithms then you will find it very difficult
to locate the errors that are revealed by testing. A second reason for the importance of
understanding algorithms is that you may need that understanding in order to construct
good test cases. This is especially true for algorithms for complex data structures.
 Check correctness - There are several methods for checking correctness of an
implementation prior to execution.
 Correctness proofs - One useful code check is to examine code using the logical methods
of correctness proofs.
 Code tracing - Often, errors can be detected by tracing through the execution of various
calls to module services, starting with a variety of initial conditions for the module. For
poorly understood psychological reasons, tracing works best if you are describing your
tracing to someone else. In order to be effective, tracing of a procedure or function should
be done assuming that calls to other procedures and functions work correctly, even if they
are recursive calls. it can enhance your understanding of algorithms.
 Peer reviews - A peer review involves having a peer examine your code for errors. To be
effective, the peer should either already be familiar with the algorithm, or should be given
the algorithm and code in advance. When the reviewer meets with the code writer, the
code writer should present the code with explanations of how it correctly implements the
algorithm. If the reviewer doesn't understand or disagrees with part of the
implementation, they discuss that part until both are in agreement about whether or not it
is an error. The reviewer's role is only as an aid to detecting errors. It is left to the
implementor to correct them.
 Anticipate errors - Unfortunately, humans make errors with correctness arguments and
sometimes miss cases in code tracing, and peers don't always catch errors either. So a
programmer should be prepared for some errors remaining in the code after the steps
listed above. Hopefully, there won't be too many.

If these have been fulfilled, what are the requirements for one to carry out proper debugging?

100
9.1.2 Debugging Aids

Aids built into programming language

 Assert statements - Some Pascal compilers and all C compilers that meet the ANSI
standard have assert procedures. The assert procedure has a single parameter, which is a
Boolean expression. When a call to assert is executed the expression is evaluated. If it
evaluates to true then nothing happens. If it evaluates to false then the program terminates
with an error message. The assert procedure can be used for detecting and reporting error
conditions.
 Tracebacks - Many Pascal compilers generate code that results in tracebacks whenever a
runtime error occurs. A traceback is a report of the sequence of subroutines that are
currently active. Sometimes a traceback will also indicate line numbers in the active
subroutines. If available, a traceback reveals where the runtime error occurred, but it is up
to the programmer to determine where the cause lies.
 General purpose debuggers - Many computer systems or compilers come with debugging
programs. Debugging programs provide capabilities for stepping through a program line-
by-line and running a program with breakpoints set by the user. When a line with a
breakpoint is about to be executed the program is interrupted so that the user can examine
or modify program data. Debugging programs also can provide tracebacks in case of run-
time errors. Debuggers are often difficult to learn to use effectively. If they are the only
tool used for debugging then it is likely that they will not save much time. For example,
debugging a data structure module with a debugger, but without a good test driver, will
likely result in spending a lot of time getting piecemeal information about errors.

9.1.3 Debugging Techniques


The following are techniques used in debugging;

 Incremental testing: In a good design for a complex module, the code is broken up into
numerous subroutines, most of which are no more than 10 to 15 lines long. For a module
designed in this way, incremental testing offers significant advantages.

 Sanity checks: Low level code in complex data structure is often written with the
assumption that the higher level code correctly implements the desired algorithm. For
example, the low level code may be written with the assumption that a certain variable or
parameter cannot be NULL. Even if that assumption is justified by the algorithm, it may
still be a good idea to put in a test to see if the condition is satisfied because the higher
level code may be implemented incorrectly. This kind of check is called a sanity check. If
an assert procedure is available then it can be used for the checks. The advantage of
sanity checks is that they give early detection of errors.
 Boolean constants for turning debugging code on or off: If debugging code is added to a
module then it is often profitable to enclose it in an if statement that is controlled by a
101
Boolean constant added to the module. By doing this, the debugging code can easily be
turned off, yet be readily available if needed later. Different constants should be used for
different stages of testing so that useless information is minimized.
 Error variables for controlling program behavior after errors: When debugging print
statements are added to code, there is the possibility of a tremendous explosion of useless
information. The problem is that a print statement by itself will be executed whether or
not there is an error.
 Traceback techniques: To obtain a traceback, use an error Boolean set by sanity checks.
At various places in the module add debug code controlled by the error variable that
prints the current position. Usually it is more economical to first run the code with a
terminating sanity check. Then you only need to add the controlled debug code at places
where the subroutine that contains the sanity check is called.

9.2 Software Testing: Types and Levels of Testing in Programming

Testing is an important step in software development life cycle. The process of testing takes
place at various stages of development in programming. This is a vital step in development life
cycle because the process of testing helps to identify the mistakes and sends the program for
correction.

Software testing is the process of evaluation a software item to detect differences between given
input and expected output. Also to assess the feature of A software item. Testing assesses the
quality of the product. Software testing is a process that should be done during the development
process. In other words software testing is a verification and validation process.

Rehman Zafar (2012) explains that Software testing is the process of evaluation a software item
to detect differences between given input and expected output. It is also done to assess the
feature of a software item. Testing assesses the quality of the product. Software testing is a
process that should be done during the development process. In other words software testing is a
verification and validation process.

102
 Verification: is the process to make sure the product satisfies the conditions imposed at
the start of the development phase. In other words, to make sure the product behaves the
way we want it to.
 Validation: is the process to make sure the product satisfies the specified requirements at
the end of the development phase. In other words, to make sure the product is built as per
customer requirements.

9.2.1 Basics of software testing

According to Rehman Zafar (2012), there are two basics of software testing: blackbox testing
and whitebox testing.

Black box testing is a testing technique that ignores the internal mechanism of the system and
focuses on the output generated against any input and execution of the system. It is also called
functional testing.

White box testing is a testing technique that takes into account the internal mechanism of a
system. It is also called structural testing and glass box testing.

Black box testing is often used for validation and white box testing is often used for verification. 

9.2.2 Types of testing

There are many types of testing. These can fall in either of the two categories ie Whitebox or
blackbox testing. The following are some examples.

 Unit Testing
 Integration Testing
 Functional Testing
 System Testing
 Stress Testing
 Performance Testing
 Usability Testing
 Acceptance Testing
 Regression Testing
 Beta Testing  
(Zafar, 2012)

103
Unit Testing

Unit testing is the testing of an individual unit or group of related units. It falls under the class of
white box testing. It is often done by the programmer to test that the unit he/she has implemented
is producing expected output against given input.

Integration Testing

Integration testing is testing in which a group of components are combined to produce output.
Also, the interaction between software and hardware is tested in integration testing if software
and hardware components have any relation. It may fall under both white box testing and black
box testing. 

Functional Testing

Functional testing is the testing to ensure that the specified functionality required in the system
requirements works. It falls under the class of black box testing.

System Testing

System testing is the testing to ensure that by putting the software in different environments (e.g.,
Operating Systems) it still works. System testing is done with full system implementation and
environment. It falls under the class of black box testing. 

Stress Testing

Stress testing is the testing to evaluate how system behaves under unfavorable conditions.
Testing is conducted at beyond limits of the specifications. It falls under the class of black box
testing. 

Performance Testing

Performance testing is the testing to assess the speed and effectiveness of the system and to make
sure it is generating results within a specified time as in performance requirements. It falls under
the class of black box testing. 

Usability Testing

Usability testing is performed to the perspective of the client, to evaluate how the GUI is user-
friendly? How easily can the client learn? After learning how to use, how proficiently can the
client perform? How pleasing is it to use its design? This falls under the class of black box
testing. (Anonymous, 2005)

104
Acceptance Testing

Acceptance testing is often done by the customer to ensure that the delivered product meets the
requirements and works as the customer expected. It falls under the class of black box testing.

Regression Testing

Regression testing is the testing after modification of a system, component, or a group of related
units to ensure that the modification is working correctly and is not damaging or imposing other
modules to produce unexpected results. It falls under the class of black box testing.

Beta Testing

Beta testing is the testing which is done by end users, a team outside development, or publicly
releasing full pre-version of the product which is known as beta version. The aim of beta testing
is to cover unexpected errors. It falls under the class of black box testing.

Check this link: http://www.softwaretestinghelp.com/types-of-software-testing/

EXERSISE

Answer the following queens giving sufficient explanation where necessary.

1. Differentiate between testing and debugging.

2. What role does testing and debugging play in the program (software) development life
cycle.

3. Explain three of the techniques that are used in debugging.

4. Discuss the following statement ‘testing does not always have to do with code’.

5. Explain 2 basic types of software testing.

105
6. Explain 8 types of software testing.

UNIT SUMMARY

We have covered the following points in this unit;


 Debugging in programming involved finding bugs or errors in the code
 Several debugging techniques are used to carry out debugging effectively. These are
sanity checks, Boolean constants, error variables, incremental testing, debuggers among
others
 Testing is a process if validation and verification carried out on a program before it can
be implemented. The major forms of testing are white box and black box testing. Other
 Other forms of testing under these two categories are regression testing, sanity testing,
function testing, unit testing, usability testing, stress testing, load testing among other.

106
APPENDIX I

Details Of Source Code Translation

Compiling a program does not really happen as simple as described above. It should be noted
that more is involved and this can be quite a complicated process. Here we will discuss two
process that are vital in program translation ie 1) tokenization and 2) Parsing.

2.8.1 What is Tokenization?


If a programming language is a (more) convenient language humans can use to describe tasks
and processes to computers, then tokenization is the process of turning a program’s raw program
text into words, or “tokens,” that the computer can understand. For example, consider this
simple Python program for the factorial function:

1 def factorial(n):

2      if n == 0:

3          return 1

4      else:

5          return n * factorial(n-1)

For this program text, the tokens would be: def, factorial, (, n, ), :, if, n, ==, and so on. You should
look at tokens as atomic units of program semantics — as opposed to characters. In a very real
sense, the tokenizer defines the vocabulary of the programming language.

How Tokenization Works


Just like there are different kinds of words — nouns, verbs, adjectives, etc. — there are different
kinds of tokens, like numbers, strings, and mathematical operators. Tokenizers are programs that
convert the characters of program text into tokens.

107
Tokenizers are very simple programs. Essentially, a tokenizer skips stuff that’s not a token, then
reads stuff that is a token until it can’t anymore, and repeats that over and over again until it runs
out of stuff.

In more detail, a tokenizer “sees” three different kinds of characters: (1) characters that cannot be
part of any token, like whitespace; (2) characters that are the initial character of a token; and (3)
characters that are non-initial characters of a token. A tokenizer reads program text character by
character. As it’s reading, it skips non-token characters, then inspects the first non-skippable
character it finds. If this character is a legal initial token character, it proceeds to read a series of
non-initial token characters until it has read the longest possible token, based on that initial
character; otherwise, it raises an error indicating that it has found an illegal character. This
approach works because the type of token to be read can be determined by inspecting the first
token character the tokenizer sees: a letter for a symbol, a digit for a number, and so on.

2.8.2 Parsing

In general, to parse someone's writing or speech simply means to interpret it. In computers, to
parse is to divide a computer language statement into parts that can be made useful for the
computer. A parser in a program compiler is a program that takes each program statement that a
developer has written and divides it into parts (for example, the main command, options, target
objects, their attributes, and so forth) that can then be used for developing further actions or for
creating the instructions that form an executable program.

Parsing is the problem of transforming a linear sequence of characters into a syntax tree.
Nowadays we are very good at parsing. In other words, we have many tools, such
as lex and yacc, for instance, that helps us in this task. However, in the early days of computer
science parsing was a very difficult problem. This was one of the first, and most fundamental
challenges that the first compiler writers had to face.
If the program text describes a syntactically valid program, then it is possible to convert this text
into a syntax tree. As an example, figure 1.1 contains different parsing trees for three different
programs written in our grammar of arithmetic expressions:

108
Figure 1.1 parsing results into parsing tree (source: wikepedia)
There are many algorithms to build a parsing tree from a sequence of characters. Some are
more powerful, others are more practical. Basically, these algorithms try to find a sequence of
applications of the production rules that end up generating the target string.

109
APPENDIX II
ADVANCED FLOWCHATS STRUCTURES

Nested loops (a repetition inside another repetition)


Many programs you might have to write may require that the repetition of a process be repeated.
Then we will have a loop inside a loop ie a repetition – being repeated.

110
Figure 2.1 Nested Loop Example

The nested while loop is shown here. This example is much simplified, it doesn’t show any
utilization of either of the loops, the outer loop doesn’t do any processing apart from the
processing the inner loop, neither loop shows any statements which will lead to the termination
of the loops.

Each single step through the outer loop will lead to the complete iteration of the outer loop.
Assume that the outer loop counts through 10 steps and the inner loop through 100 steps. The
sequence in the inner loop will be executed 10 * 100 times. Nested loops will do a lot of work.

111
Figure 2.2 Nested Loop

The repeat loop shown here, like the while loop example, is much simplified. It does show two
processes, sequence 1 and sequence 2, one process in the outer loop and one process in the
innner loop

Like the while loop the nested repeat loop will see a great deal of work done. If the outer loop
does a thousand iterations and the inner loops does a thousand iterations then sequence 2 will be
executed 1000 * 1000 times. This teaches you a simple fact a loop can be nested inside another
loop as can be do done even in programs and pseudocode

112
Using multiway selection in flow charts

Figure 2.3 Multiway selection

113
This demonstrates a simple fact that in flowcharting (just like in pseudocode or actual programs)
you may have to face situations where one decision leads to another, and another and so forth.
The flow chart form of multiway selection is shown here.

If decision 1 is true then sequence 1 is executed and the multiway selection is finished. If
decision 1 is false then decision 2 is tested, if this is true then sequence 2 is done and the
multiway selection is finished. If decision 2 is false, you get the picture.

APPENDIX III

RECURSION
Recursion means "defining a problem in terms of itself". This can be a very powerful tool in
writing algorithms. Recursion comes directly from Mathematics, where there are many examples
of expressions written in terms of themselves. For example, the Fibonacci sequence is defined as:
F(i) = F(i-1) + F(i-2)

Recursion is a method of solving problems based on the divide and conquer mentality. The basic
idea is that you take the original problem and divide it into smaller (more easily solved) instances
of itself, solve those smaller instances (usually by using the same algorithm again) and then
reassemble them into the final solution.

The canonical example is a routine to generate the Factorial of n. The Factorial of n is calculated
by multiplying all of the numbers between 1 and n. An iterative solution in C# looks like this:

public int Fact(int n)


{
int fact = 1;
for( int i = 2; i <= n; i++)
{
fact = fact * i;
}

114
return fact;
}
There's nothing surprising about the iterative solution and it should make sense to anyone
familiar with C#.

The recursive solution is found by recognising that the nth Factorial is n * Fact(n-1). Or to put it
another way, if you know what a particular Factorial number is you can calculate the next one.
Here is the recursive solution in C#:

public int FactRec(int n)


{
if( n < 2 )
{
return 1;
}
return n * FactRec( n - 1 );
}
The first part of this function is known as a Base Case (or sometimes Guard Clause) and is what
prevents the algorithm from running forever. It just returns the value 1 whenever the function is
called with a value of 1 or less. The second part is more interesting and is known as
the Recursive Step. Here we call the same method with a slightly modified parameter (we
decrement it by 1) and then multiply the result with our copy of n.
When first encountered this can be kind of confusing so it's instructive to examine how it works
when run. Imagine that we call FactRec(5). We enter the routine, are not picked up by the base
case and so we end up like this:

// In FactRec(5)
return 5 * FactRec( 5 - 1 );
// which is
return 5 * FactRec(4);
If we re-enter the method with the parameter 4 we are again not stopped by the guard clause and
so we end up at:

// In FactRec(4)
return 4 * FactRec(3);
If we substitute this return value into the return value above we get

// In FactRec(5)
return 5 * (4 * FactRec(3));
This should give you a clue as to how the final solution is arrived at so we'll fast track and show
each step on the way down:

115
return 5 * (4 * FactRec(3));
return 5 * (4 * (3 * FactRec(2)));
return 5 * (4 * (3 * (2 * FactRec(1))));
return 5 * (4 * (3 * (2 * (1))));
That final substitution happens when the base case is triggered. At this point we have a simple
algrebraic formula to solve which equates directly to the definition of Factorials in the first place.

It's instructive to note that every call into the method results in either a base case being triggered
or a call to the same method where the parameters are closer to a base case (often called a
recursive call). If this is not the case then the method will run forever.

FIBBONACI RECURSION

Fibonacci sequence is named after Leonardo Fibonacci. Fibonacci numbers starts with the first
two numbers 0 and 1, and each subsequent numbers takes as the sum of its previous two
numbers.

 Ex. 0, 1, 1, 2, 3, 5 
The first two numbers in the sequence are 0 and 1.
The 3rd number which is 1 is the sum of its previous two numbers - 0 and 1.
The 4th number which is 2 is the sum of its previous two numbers  - 1 and 1.
So on and so forth...

In mathematical equation, Fibonacci sequence can be represented as:

 Fn = F(n-1) + F(n-2) where F0 = 0, F1 = 1

The following program shows the Fibonacci sequence using recursion.

/*
Fibonacci series using Recursion
*/
#include <iostream>

using namespace std;


int fibonacci(int);

116
int main(void)
{
int count;
char waitInput;

cout << "How many numbers in the Fibonacci sequence do you want to show? ";
cin >> count;

for (int i = 0; i < count; i++)


{
cout << " " << fibonacci(i) << " ";
}

cin>>waitInput;

return 0;
}

//fibonacci function
int fibonacci(int num)
{
if (num == 1)
{
return 1;
}
else if (num == 0)
{
return 0;
}
else
{
return fibonacci(num - 1) + fibonacci(num - 2);
}
}

Iteration Vs. Recursion

 If a recursive method is called with a base case, the method returns a result. If a method is
called with a more complex problem, the method divides the problem into two or more
conceptual pieces: a piece that the method knows how to do and a slightly smaller
version of the original problem. Because this new problem looks like the original
problem, the method launches a recursive call to work on the smaller problem.
 For recursion to terminate, each time the recursion method calls itself with a slightly
simpler version of the original problem, the sequence of smaller and smaller problems
must converge on the base case. When the method recognizes the base case, the result is
returned to the previous method call and a sequence of returns ensures all the way up the
line until the original call of the method eventually returns the final result.

117
 Both iteration and recursion are based on a control structure: Iteration uses a repetition
structure; recursion uses a selection structure.
 Both iteration and recursion involve repetition: Iteration explicitly uses a repetition
structure; recursion achieves repetition through repeated method calls.
 Iteration and recursion each involve a termination test: Iteration terminates when the
loop-continuation condition fails; recursion terminates when a base case is recognized.
 Iteration and recursion can occur infinitely: An infinite loop occurs with iteration if the
loop-continuation test never becomes false; infinite recursion occurs if the recursion step
does not reduce the problem in a manner that converges on the base case.
 Recursion repeatedly invokes the mechanism, and consequently the overhead, of method
calls. This can be expensive in both processor time and memory space.

APPENDIX IV

Reconstructing a Tree From a Traversal List

Let us consider the below traversals:

Inorder sequence: D B E A F C
Preorder sequence: A B D E C F

In a Preorder sequence, leftmost element is the root of the tree. So we know ‘A’ is root for given
sequences. By searching ‘A’ in Inorder sequence, we can find out all elements on left side of ‘A’
are in left subtree and elements on right are in right subtree. So we know below structure now.

A
/ \
/ \
DBE FC

We recursively follow above steps and get the following tree.

A
/ \
/ \
B C
/\ /
/ \ /
D E F

118
What if we have been given an Inorder and Postorder traversal list, how can go about
constructing the tree?

Given the Inorder and Postorder Lists

Inorder is: 2 3 5 7 9 10 11 12
Postorder is: 2 5 3 9 11 12 10 7

Iterate the postorder array in reverse order and keep splitting the inorder array around where that
value is. Do this recursively and that will be your tree. For example:

current = 7, split inorder at 7: 2 3 5 | 9 10 11 12

Look familiar? What is on the left is the left subtree and what is on the right is the right subtree,
in a pseudo-random order as far as the BST structure is concerned. However, you now know
what your root is. Now do the same for the two halves. Find the first occurrence (from the end)
of an element from the left half in the postorder traversal. That will be 3. Split around 3:

current = 3, split inorder at 3: 2 | 5 ...


So you know your tree looks like this so far:

7
/
3
This is based on the facts that a value in the postorder traversal will always appear after its
children have appeared and that a value in the inorder traversal will appear between its children
values.

Check the link below for more information on reconstructing tree form the traversal list;

http://cs.stackexchange.com/questions/11015/constructing-a-binary-tree-with-given-traversals

http://www.geeksforgeeks.org/construct-tree-from-given-inorder-and-preorder-traversal/

Binary Search Trees

A binary search tree (BST) is a binary tree where each node has a Comparable key (and an
associated value) and satisfies the restriction that the key in any node is larger than the keys in all
nodes in that node's left subtree and smaller than the keys in all nodes in that node's right subtree.

119
REFERENCES

Algorithms. ( 2014, July 1). Retrieved March 19, 2015, from Tehtarget:
http://whatis.techtarget.com/definition/algorithm
Anonymous. (2005, March 1). Types of software Testing. Retrieved March 23, 2015, from Software
Testing Help: http://www.softwaretestinghelp.com/types-of-software-testing/

Beal, V. (1995). machine language. Retrieved March 19, 2015, from Webopedia:
http://www.webopedia.com/TERM/M/machine_language.html

Chow, F. (2013, November 22). Programming Languages - The Challenge of Cross-language


Interoperability. Retrieved May 26, 2015, from acmQueue: https://queue.acm.org/detail.cfm?id=2544374

Farrell, J. A. (1995, August). Anatomy Of a Compiler. Retrieved March 19, 2015, from
http://www.cs.man.ac.uk/~pjj/farrell/comp3.html

Gookin, D. (2010, January 12). How to Use the Switch-Case Structure for Multiple-Choice Decisions in
C Programming. Retrieved March 23, 2015, from tutorialspoint: http://www.dummies.com/how-
to/content/how-to-use-the-switchcase-structure-for-multiplech.html

Hemmendinger, D. (2015, January 27). computer-programming-language. Retrieved March 19, 2015,


from Encyclopedia Britanica.

Janssen, C. (2010, January 11). Structured Programming. Retrieved March 23, 2015, from Technopedia:
http://www.techopedia.com/definition/25972/modular-programming

Kent, J. (2004). C++ Demystified: A Self-Teaching Guide . In J. Kent, C++ Demystified: A Self-
Teaching Guide (p. chapter 9). Osborn: Mc-Graw Hill.

Kent, J. (2004). Arrays. In J. Kent, C++ Demystified: A Self-Teaching Guide (p. Chapter 10). Osborne:
McGraw-Hill.

120
Kent, J. (2004). Nested if Statements. In J. Kent, C++ Demystified: A Self-Teaching Guide (p. Chapter6).
Emeryville, California: McGraw-Hill/Osborne.

Stroustrup, B. (1997). The C++ Programming language Third Edition. Massachusetts: Addison Wesley
Longman, Inc.

Stroustrup, B. (1997). Variables and Data types. In B. Stroustrup, The C++ Programming Language (pp.
69-76). Murray Hill, New Jersey: Addison Wesley Longman, Inc.

Wikipedia. (2006, January 01). Structured Programming. Retrieved March 23, 2015, from Wikepedia:
http://en.wikipedia.org/wiki/Structured_programming

Zafar, R. (2012, March 20). What is software testing? What are the different types of testing? Retrieved
March 23, 2015, from CodeProject: http://www.codeproject.com/Tips/351122/What-is-software-testing-
What-are-the-different-ty

121

You might also like