You are on page 1of 177

UNIT 01

INTRODUCTION TO SOFTWARE
SYSTEM DEVELOPMENT

Introduction 2

Session 1 Software Systems for Engineers 3

Session 2 Evolution of Programming Paradigms 18

Session 3 Introduction to Software Engineering 33

Session 4 Requirement Elicitation and Documentation 45

Session 5 Requirement Analysis with Data Flow Diagram (DFD) and


Unified Modeling Language 53

Session 6 Structured Programming 66

Session 7 Function Oriented Design 83

1
Introduction

Nowadays software embedded devices and software simulation have become very
common in engineering design work and training programmes. At work places, you
may even be in the decision making body dealing with software companies on how to
get software systems developed and deployed, what software to buy, and what to
negotiate. To make such decisions you should know what activities are being done as
software development.

A software system is the product of many different activities carried out to solve a
problem or realize an idea. This set of activities is called „Software Life Cycle‟. Since
it describes the sequence of activities for the entire lifetime of a product it is also
called „Product Life Cycle‟. A product cycle covers everything from the initial
commercial idea until the final de-installation of the product after its use.

A software process model describes the sequence of activities carried out in the
Software Life Cycle, and the relative order of these activities. Generally, a process
model provides a fixed generic framework that can be tailored to a specific project.

In the first unit, we will discuss about Software systems and their importance,
software classifications, history and features of programming languages briefly and
different program paradigms. Furthermore, basic concepts related to structured
programming and software development life cycle also are discussed.

To develop a software system to solve a problem or realize an idea, the first task you
need to do is to gather requirements and then analyse them. As you saw from the
software life cycle, design can be done after requirements are analysed and the design
is needed to code the programs. Next we discuss requirement elicitation, analysis and
modelling. These sessions will help you understand how to collect the needs from the
stakeholders to develop a successful system and the process of collecting these
different types of requirements using diverse methods. You will learn the ways to
specify these requirements in the correct way, so the system developers will develop
software that actually meets the needs of the stakeholders.

Analysis emphasizes investigation of a problem rather than how a solution is found.


Design emphasizes a logical solution, and how the system fulfills the requirements.
Therefore, finally in this Unit we will briefly discuss function oriented design which
would be helpful to understand programming concepts in the next Unit.

Learning Outcomes
 Describe the evolution of software from inception to present
 Recognize the need for a disciplined approach to software system development
 Describe different approaches to determine requirements: analysis, prototyping,
simulation and modelling, human factors
 Apply requirements elicitation methods to discover requirements
 Design a solution for a given problem with functional design methods

2
Session 1
Software Systems for Engineers

Contents
Introduction, p 3
1.1 Importance of Software Systems, p 3
1.2. Software system, p 4
1.3 Software Classifications, p 4
1.4. Software Packages, p 9
1.5 Programming languages, p 9
1.6 Software used in Engineering, p 11
1.7 Software Licenses, p 14
Summary, p 17
Learning Outcomes:, p 17

Introduction
This session explains why a software system is very important for engineers, what are
the components of software systems, classifications of software, software packages,
and currently available popular software systems used in engineering. Another
important aspect of software is licensing. At the end of the session we will discuss
different types of licensing as it is very important when purchasing or using software.

1.1 Importance of Software Systems


As an engineering student you learn many new skills that are specific to your specific
field of engineering. However, skills in using software and writing simple programs
are important for all specialisations. Software has become an invisible thread tying all
fields of studies together. As an engineer, you may need to know the process of
software development for creating your own simple programs as well as for using
application software for analysing, designing and modeling of work in any other fields.
You need to know the fundamentals in order to work with software development
teams to get your applications built or when purchasing software systems.

For example, modern vehicles are designed to look very elegant and to travel in very
high speed safely with due consideration for aerodynamics and control features,
which also can be purchased at affordable price. How do engineers design and get this
type of vehicles manufactured within the required time? It is with the aid of computer-
based designing and manufacturing tools. Similarly, computer systems controlled by
software systems are playing a major role in the other fields of agriculture, civil,
electrical, communication, mechanical and textile.

3
In general, computer system includes both collections of hardware and software
systems. In this course, we discuss only about software systems. In the next session,
let us study about different components in a software system and how they are
classified.

1.2. Software system


A software system is a set of interrelated computer programs and configuration
software and files which are arranged in an organized way to achieve a specific goal
with system documentation, test results and user documentation. The above sentence
has four words which are computer programs, configuration programs and files,
system documentation, and user documentation. What do they mean? Let us discuss
them one by one in the following sections.

1.2.1. Computer program


A computer program or just a program is a set of instructions that tell what to do to
computer hardware. A program takes inputs, works with written instructions and gives
outputs.

1.2.2. Software
Software is a set of programs to perform a specific task. Software includes its
configuration programs and files.

1.2.3 Documentation
Documentation is an important part of any software system. Most of the time, it is
hard to see a software system as tangible product. It is system documentation and user
documentation that someone can see as the software product being purchased.

Software can be classified into two broad categories. They are system software and
application software which we will discuss in the next session.

1.3 Software Classifications


Software can be divided into two broad classes: System software and application
software. Relationships between user, application software and system software are
shown in Figure 1- 1 . System software is needed to maintain and work with hardware
of the computer. Application software is the general designation of computer
programs for performing user tasks. Application software may be general purpose
(word processing, web browsers, accounting).

4
Figure 1- 1 Relationship between user, application and system software

1.3.1 System Software


System software is a special type of a computer program. System software works
either between application programs and hardware or between user and hardware.
System software can be divided into five main categories. They are operating system
(OS), device drivers, firmware, programming language translators and utility software.

Operating Systems
OS is the most important software in a computer. All application software run on top
of an OS as shown in Figure 1- 2. OS manages all the resources in a computer. OS
gives facilities to communicate between hardware, system programs, and other
applications. Modern operating systems have two main user interfaces called
command line interface and Graphical User Interface.

Figure 1- 2 Relationship of the OS with hardware and application software

The operating system's tasks, in the most general sense, fall into six categories:
 Processor management
 Memory management

5
 Device management
 Storage management
 Application interface
 User interface

Mobile OS

Mobile operating systems are used in smart phones, tablets, smart watches, or other
mobile devices to run mobile application software and programs. Mobile OS
combines features of personal computers and other features useful for mobile devices
such as touch screen, cellular, blue tooth, Wi-Fi access Wi-Fi Global Positioning
System (GPS), video, pictures, cameras, speech recognition, voice recorder, music
player, near field communication, infrared blaster etc.

Mobile devices with mobile communication contain two mobile operating systems,
one as the main OS where user is interacting with and another, a low level proprietary
real time operating system which operates the radio and other hardware.

Activity 1.1

List down three (3) different mobile operating systems and their major differences.

Device Driver

Device driver is a software program that controls hardware attached to the computer
and allows communication with OS. Hard disk, monitor, key board, and all other
hardware need device drivers to communicate with OS. All operating systems are
bundled with device drivers for most commonly used hardware. If an OS does not
have a device driver for a particular hardware, it should be installed to get the
hardware work. Communication flow between the device and the device driver, OS
and application software are shown in Figure 1- 3.

Figure 1- 3 Device driver connected with device and operating system

6
Firmware
Firmware is a program code that is permanently stored in a chip. Programs that are
needed to control hardware with limited amount of controls can be permanently
programmed into a programmable chip called ROM and mounted to hardware. But
now, technology of firmware has evolved from ROM to flash memory to be able to
update easily.

Programming language Translators


High-level languages allow user to write programs in a machine-independent manner.
It lets the users be concerned primarily with the problems unique to their applications;
users are not even aware of any machine dependencies that may exist. It enables quick
programming process, makes programs transportable between systems of different
vendors and allows people to write useful applications systems without having to be
thoroughly familiar with the internal structure of a computer.

Programming language translator is software which can translate a program from a


higher-level programming language such as C, Java or Python to lower level language
such as assembler or machine code language. Computer can only understand
programs that are written in zeros and ones. Programming codes written in ones and
zeros are called machine language program codes. There are three types of
Programming language translators. They are: interpreter, compiler and assembler.

Interpreter
Interpreter converts each instruction of the program code to machine code. If there is
an error in an instruction, it displays when the instruction is interpreted. Relationship
of the interpreter with source code and machine code is shown in Figure 1- 4.

Figure 1- 4 Interpreter with source code and machine code

Compiler
Compiler converts all the instruction codes of the high-level programming language to
machine code and save it to a file. Source code is a text file which includes the high-
level program written though an editor. Compiler takes this source code as input and
analyse the source code and converts to another file which includes the machine code.
This machine code file is executable and can run on the OS without the compiler.
Compiler, source code and machine code are shown in Figure 1- 5.

Figure 1- 5 compiler compile complete source code to


machine code
7
Assembler
An assembler is a program that converts assembly language into machine code. It
takes the basic commands and operations from assembly code and converts them into
binary code that can be recognized by a specific type of processor.

Activity 1.2

Tabularise advantages and disadvantages of compilers and interpreters and write down 3
examples for each.

Integrated Development Environment (IDE)


An Integrated Development Environment (IDE) is a programming environment that
has been packaged as an application program, typically consisting of a code editor, a
compiler, a debugger, and a graphical user interface (GUI) builder.

For example, Microsoft Visual Studio is an IDE from Microsoft. It is used to develop
computer programs for Microsoft Windows, as well as web sites, web applications
and web services. Visual Studio uses Microsoft software development platforms such
as Windows API, Windows Forms, Windows Presentation Foundation, Windows
Store and Microsoft Silverlight. It can produce both native code and managed code.

Built-in languages in Visual studio include C, C++ and C++/CLI (via Visual C++),
VB.NET (via Visual Basic .NET), C# (via Visual C#), and F# (as of Visual Studio
2010). Support for other languages such as M, Python, and Ruby among others is
available via language services installed separately. It also supports XML/XSLT,
HTML/XHTML, JavaScript and CSS.

The integrated debugger works both as a source-level debugger and a machine-level


debugger. Other built-in tools include a form designer for building GUI applications,
web designer, class designer, and database schema designer. Microsoft provides
"Express" editions of its Visual Studio at no cost.

Utility Software
Utility software is designed to help analyse, configure, optimize or maintain a
computer. For example, you may want to compress a file to let you save it on to a
flash drive. For this task you would choose to use a file compression utility program.

1.3.2 Application software


Application software are also called end user programs. Application software runs
over the OS. Some application software come bundled with system software. For

8
example, Ubuntu with LibreOffice and Firefox web browser. Windows with Internet
explorer web browser.

Application software market can be categorized into two types, horizontal and vertical
market application software. Horizontal market software are the most commonly used
software such as word processing, spread sheet work, presentation software, etc.
Vertical market software is application software in a specific field, developed for a
specific industry or specific field such as music, engineering, etc. It is developed and
customized to support a specific business process and targets a smaller number of
users with specific skill set and job responsibilities within an organization.

Differences between horizontal and vertical software are shown in Table 1- 1.

Table 1- 1 Comparison of horizontal and vertical software

Horizontal Application Software Vertical application software


Provides solutions based on the Written for particular market or
common needs of many companies industry
Use of demo copy for entering few For performance tests, many days or
transactions can be an acceptable test. weeks can be needed.
Is not business specific and can be Used for large systems
used for small systems
Easy to use and maintain More complicated

1.4. Software Packages


A software package or packaged software is a set of software programs bundled
together and sold or distributed. Most of the time, a user who use one software may
require another software in the package to complete his/her task. For example,
Microsoft Office is packaged software, including multiple software programs used in
a home or office, such as Microsoft Word, Microsoft Excel, Microsoft PowerPoint.
Video and audio editing software may be available as packaged software as well, as
they may be used together for editing music and video files used in a movie.

1.5 Programming languages


We discussed that there are different types of software available in the world, but how
are these software developed? A software program is a set of instructions written in a
specific way in a computer related language. A program written such a way should be
executed in a computer to do whatever the work it was designed to do. Without a
program, a computer is a useless machine. There are several types of software
programming languages to develop software. A few of popular programming
languages are described below.

9
C language - is a very popular programming language in technical fields such as
electronic, communication, embedded systems etc. C is used to program most
microcontrollers.

It is a general-purpose programming language initially developed by Dennis Ritchie.


C has facilities for structured programming. Its design provides constructs that map
efficiently to typical machine instructions, and therefore it has found lasting use in
applications that had formerly been coded in assembly language, such as the Unix
operating system. C is one of the most widely used programming languages of all
time, and C compilers are available for the majority of computer architectures and
operating systems.

C++ - is a general-purpose programming language having object-oriented


programming features. It also provides the facilities for low level memory
manipulation.

It is designed with a bias for systems programming (e.g. embedded systems, operating
system kernels), with performance, efficiency and flexibility of use as its design
requirements. C++ has also been found useful in many other contexts, including
desktop applications, servers (e.g. e-commerce, web search, SQL), performance
critical applications (e.g. routers, space probes) and entertainment software, such as
video games.

Java - is a computer programming language that is concurrent, class-based, object-


oriented, and specifically designed to have very few implementation dependencies as
possible. It is intended to let application developers "write once, run anywhere"
(WORA), meaning that code that runs on one platform does not need to be recompiled
to run on another.

Java applications are typically compiled to byte code that can run on any Java virtual
machine (JVM) regardless of computer architecture. Java was originally developed by
James Gosling at Sun Microsystem‟s (which has since merged into Oracle
Corporation) and released in 1995 as a core component of Sun Microsystems' Java
platform. The language derives much of its syntax from C and C++, but it has fewer
low-level facilities than either of them.

Python - is a dynamic object-oriented programming language that can be compared


with Java and Microsoft's .NET-based languages. It is a general-purpose language
which can be used for different kinds of software development. It offers strong
support for integrating with other technologies, higher programmer productivity
throughout the development life cycle, and is particularly well suited for large or
complex projects with changing requirements.
Python is also being used in mission critical applications such as in stock exchange,
forms the basis for high end newspaper websites, runs on millions of cell phones, and
is used in industries as diverse as ship building, movie animation, and air traffic
control.

10
Python is supposed to be a rapidly growing open source programming language. It is
available for most operating systems, including Windows, UNIX, Linux, and Mac OS.

Hardware Description Language (HDL) - is a specialised computer language used to


program the structure, design and operation of electronic circuits, and most commonly,
digital logic circuits.

A hardware description language enables a precise, formal description of an electronic


circuit that allows for the automated analysis, simulation, and simulated testing of an
electronic circuit. It also allows for the compilation of an HDL program into a lower
level specification of physical electronic components, such as the set of masks used to
create an integrated circuit.

A hardware description language has many similarities to a programming language


such as C; it is a textual description consisting of expressions, statements and control
structures. One important difference between most programming languages and HDLs
is that HDLs explicitly include the notion of time. Two types of popular HDLs are
VHDL and Verilog HDL.

Prolog - is a general-purpose logic programming language associated with artificial


intelligence and computational linguistics.

VisiRule - is a graphical tool for designing, developing and delivering business rule
and decision support applications, using flowcharts that represent the decision logic.

1.6 Software used in Engineering


Engineers need horizontal application software like word processing software,
accounting software, database management systems and project management software
for everyday use. Common vertical application software used in engineering are
numerical computation software such as MATLAB and design software such as
OrCAD, AUTOCAD etc. Project management software is an essential software tool
when planning a particular engineering project.

Numerical computation software


MATLAB (MATrix LABoratory) - is a numerical computing environment. Using
MATLAB, you can do matrix manipulations, plot functions, create simulations,
implement algorithms, and interface with programs written in other languages, such as
C, C++, Java. MATLAB is a proprietary program.
GNU Octave - is a high-level interpreted language like developed for numerical
computations. It is used for solving linear and non-linear equations, numerical linear
algebra, statistical analysis and other numerical experiments. It is freely
redistributable software under the terms of GNU General Public License (GPL).

GNU Octave executes in a graphical user interface (GUI) and it works as an IDE
which includes a code editor, debugger and interpreter.
11
Scilab - is a programming language with numerical algorithms covering many aspects
of scientific computing problems.

Scilab is a free software and open source software. The software is distributed with
source code, so that the user has access to Scilab‟s most internal aspects. Users can
download and install a binary version of Scilab since the Scilab consortium provides
Windows, Linux and Mac OS executable versions.

Computer Aided Design (CAD) software


AutoCAD - is a commercial software application for 2D and 3D computer-aided
design (CAD) and drafting.

LibreCAD – is a free computer aided design application for 2D design. It works on


Linux, and Window OS.

OrCAD - is a proprietary software tool suite used primarily for electronic design
automation. This software is used mainly by electronic design engineers and
electronic technicians to create electronic schematics and electronic prints for
manufacturing printed circuit boards.

Project Management Software


Microsoft Project - is a project management software program, developed and sold
by Microsoft, which is designed to assist a project manager in developing a plan,
assigning resources to tasks, tracking progress, managing the budget, and analysing
workloads.

Planner – is open source project management software developed for Linux OS.

Electrical Engineering Software


As in other engineering disciplines, electrical engineers also essential to use
simulation software such as PSCAD, PSS/E, WASP, Power World, HOMER,
MESSAGE etc. in order to perform necessary power system simulations. Brief
introduction of some key electrical engineering software are given below.

PSCAD (Power Systems Computer Aided Design):


This is a time domain simulation tool for studying transient behavior of electrical
networks. The software developed by the Manitoba HVDC research center. PSCAD
enables the user to construct a circuit, run a simulation, analyze the results and
manage the data in a completely integrated, graphical environment and the software
package includes tested simulation models, control functions, electric machines,
protective devices, transmission lines and cables.

12
PSS/E (Power System Simulator for Engineering):
PSS/E is a comprehensive set of programs for study of power system transmission
network and generation performance in steady-state and dynamic conditions of
electrical power systems. The software can be utilized to facilitate calculations for
variety of analyses such as power flows, faults analysis, equivalency and switching
studies. Basically, PSS/E is very important for transmission planning in electric
utilities.

HOMER (Hybrid Optimization of Multiple Electric Renewables):


This software is used to design and evaluate technically and financially the options for
off-grid and on-grid power systems of micro grid (wind, solar, diesel etc.)
optimization applications. HOMER is developed by the National Renewable Energy
Laboratory in the United States. Using the model, optimized results for given micro
grids can be obtained as suitable energy generation methods and its operating times,
generators and battery performance, electric production, production cost and emission.

MESSAGE (Model for Energy Supply System Alternatives and their General
Environmental impacts):
MESSAGE is a software for setting up optimization models of energy supply systems
(coal, oil, gas, wind, etc.) to assess capacity expansion and energy production policies.
MESSAGE optimizes the system expansion and operation based on specified criterion
such as cost minimization and profit maximization. The software is developed by
International Institute for Applied Systems Analysis, Austria.

Simulation Software
Cisco Packet Tracer - It is a network simulation program that allows students to
create network topologies and experiment with network behavior. Packet Tracer
provides simulation, visualisation, authoring, assessment, and collaboration
capabilities and facilitates the teaching and learning of networking concepts.

Graphical Network Simulator-3 - is an open source software (GNU General Public


License) that simulates complex networks. You can visualise the way real networks
perform with this software without having dedicated network hardware such as
routers and switches.

Wireshark - is a free and open-source packet analyser. It is used for network


troubleshooting, analysis, software and communications protocol development, and
education purposes.

GNU Radio - is also a free and open-source software development toolkit that
provides signal processing blocks to implement software radios. It can be used with
readily- available low-cost external radio frequency hardware to create software-
defined radios, or a simulation-like environment. It is used in academic and
commercial environments to support both wireless communications research and real-
world radio systems.

13
GNU Radio is licensed under the GNU General Public License (GPL) version 3.

Data Base Management Systems (DBMS)


A database management system (DBMS) is a collection of programs that enables you
to store, modify, and extract information from a database. Typical examples of DBMS
use include accounting, human resources and customer support systems.

Some of the database management systems are:


Microsoft Access: is a database management system (DBMS) developed by
Microsoft. It stores data in its own format based on the Access Jet Database Engine. It
also has the facilities like importing or linking directly to data stored in other
databases and applications.

MySQL: is an open source database management system, one of the most popular
DBMS on the web. It is reliable, fast and also flexible.

Oracle: Developed by Oracle corporation, it is an object relational DBMS. The


original version of Oracle software was developed by Software Development
Laboratories (SDL). Oracle is regarded to be one of the safest DBMSs.

Microsoft SQL Server: Microsoft developed this relational database server. The
primary function of this software is to store and retrieve the data as requested by other
applications, whether those applications are on the same computer or running on other
computers across the network (including internet).

1.7 Software Licenses


As you have seen from the previous section, there are some software available to
download and use freely and some software are available for purchasing. Some
vendors allow download software freely for trial period only (e.g. about 30 days
period). Some vendors allow downloading software freely with limited features and
later you are required to pay to obtain the software with full features. Some software
including both software and source code which can be downloaded freely. All these
software have a license agreement. According to the given license, authors can go for
legal actions for illegal use.

Software license is a document which gives legally valid guidelines for the use and
distribution of software. Software licenses are broadly categorised as closed source
and open source software. Closed source software are considered as having a
copyright.

Reed stated the copyright as

“Copyright is a right given to authors or creators of „works‟ such as books, films or


computer programs to control the copying or other exploitations of such works.

14
Copyright begins automatically on the creation of a „work‟ without the need for
compliance with any formalities.”

Variation of licenses from trade secret to public domain is shown in Figure 1- 6.

Public Permissive Copyleft Freeware/ Proprietary Trade


domain FOSS FOSS Shareware/ licenses secret
License License Freemium
(eg. BSD (eg. GPL)
license

Figure 1- 6 Distribution of copyright of software

First box from the right side of Figure 1- 6 is a trade secret. Second box from the right-
hand side is a Proprietary License. Next boxes are freeware/shareware/ freemium,
copyleft FOSS (Free and Open Source Software) License, permissive FOSS License
and public domain.

1.7.1 Trade Secret


Trade secret is any information, including a formula pattern, compilation, a program,
a device, a method, a technique or a process that is maintained as a secret because it is
generally not known and has a commercial value, actual or potential. Proper way of
acquiring a trade secret is discovery by independent invention or discovery by
“reverse engineering,” that is, by starting with the known product and working
backward to find the method by which it was developed.

1.7.2 Proprietary License


These are computer programs that are exclusive property of their developers or
publishers and cannot be copied or distributed without complying with their licensing
agreements. Almost all commercial software are proprietary. Usually source code of
the software is copyrighted or has patent right. Sometimes, both the source code and
machine code are copyrighted. Some developers and vendors keep source code as a
trade secret and give machine code with a copyright license. Mostly, proprietary
software is commercial that can be bought, leased or licensed from its vendors or
developer. It can be purchased or licensed for a fee, but relicensing, distribution or
copying is prohibited.

1.7.3 Freeware/Shareware/Freemium
Freeware – can be obtained without any fee and can be used for unlimited period.
Source code is not provided to user by the developer and ownership is kept with the
developer. Developer can change future releases from freeware to paid software.

Shareware – is a demonstration of proprietary software for free but for a specific


evaluation period only, mostly 15-30 days. Software will be expired after the
evaluation period.

15
Freemium – Developer offer software for free of charge without the source code but
should pay for additional features. Actually, it is a business strategy to keep customers
and sell their products.
Copyleft FOSS license
All users under this license have unlimited freedom to use, study and privatively
modify the software. GNU General Public License (GPL) is the first copyleft license.
Under the GPL license, user has freedom to redistribute the software or any
modifications to it.

Copyleft mark is

Permissive FOSS license


This license gives user to use, study and privatively modify the software and includes
only minimal requirements on redistribution. User can take the code and use it as a
part of closed source software released under proprietary software license.

Public domain
Public-domain software has no ownership such as copyright, trademark or patent and
has been placed in the public domain. Software in the public domain can be modified,
distributed, or sold even without any attribution by anyone.

Activity 1.3

List an example of a software for each type of license in Figure 1- 6.

A Comparison of above software licenses is given in Table 1- 2.

16
Table 1- 2 Comparison of software licenses

Rights Public Permissive Copyleft Freeware/ Propriet Trade


granted domain FOSS FOSS Shareware/ ary secret
Freemium licenses
License License

Copy right No Yes Yes Yes Yes No


retained

Right to Yes Yes Yes Yes Yes No


perform

Right to Yes Yes Yes Yes Yes No


display

Right to Yes Yes Yes Often No No


copy

Right to Yes Yes Yes No No No


modify

Right to Yes Yes Yes, under Often No No


distribute same license

Right to Yes Yes Yes No No No


sub license

Summary
In this session we discussed characteristics and applications of different types of
software, components that an operating system consists of and different programming
languages. We further discussed software licenses and how license enables the use of
software.

Learning Outcomes:
After studying this session you should be able to,
 Identify different types of programming languages, packaged
software and Integrated Developing Environments.
 Describe the components of an operating system and their function
 Explain the differences of Proprietary, Open source and Free
software.
 Identify different type of software licenses available.
Reference
Reed, C. (2011), Computer law, OUP Oxford

17
Session 2
Evolution of Programming Paradigms

Contents
Introduction, p 18
2.1 Computer Program, p 18
2.2 History of Programming Languages, p 19
2.3 Features of High-Level Languages, p 22
2.4 Programming paradigms, p 25
Summary, p 32
Learning Outcomes:, p 32

Introduction
We give instructions to computers by means of programs. Programs translate
instructions from a human readable format to a computer readable format. In order to
develop programs, programming languages are being used. Since the evolution of
programming languages in 1940‟s, different programming languages were developed
to serve different purposes. Each language has its own special set of keywords and
syntax, which makes each programming language unique.

Initially programming languages were created by people in universities or in the


government and were used to carry out special functions.

This session will provide some background knowledge on programming and different
paradigms of programming languages in brief. It also introduces important
characteristics of programming languages.

2.1 Computer Program


A computer program is a collection of instructions that describe a task or set of tasks
to be carried out by a computer. Computer programs are normally designed for
problems that would be difficult or impossible to solve by other ways or to solve a
certain problem more efficiently and effectively. These programs can be simple or
very complex depending on the requirements. Programs can be developed for
straightforward calculations like adding two numbers or for more complicated
problems like guiding a satellite into the right orbit and handling the transmission of
data.
Almost every program performs 3 basic tasks in solving problems, irrespective of
whether it is simple or complex.

18
Manipulate data
Perform operations
Provide results

2.1.1 Manipulate Data


Programs manipulate data by accepting data from inputs (e.g., keyboard), creating
new data and storing them, or modifying existing data.
There are two fundamental forms of data that are facilitated by programming
languages.

 Textual data – Characters and strings


o Example 1.1: A person‟s name
 Numerical data - numbers.
o Example 1.2: A persons age
In addition to these types of data, C facilitates more complex data types, and these
will be discussed in detail in the sessions to come.

2.1.2 Perform Operations


In order to produce results from data, operations are being used. Programming
languages are used to give instructions to perform operations. A simple example of an
instruction would be „adding two numbers‟.

2.1.3 Provide results


After performing operations, results are generated, and it can be information or data to
another operation. It can be displayed on a screen, stored in databases, used to
produce reports or it can be transmitted to another computer.

2.2 History of Programming Languages


Earlier the computer programs were written in the actual language of the computer.
Nowadays the programmer writes his/her program in a programming language which
is relatively easy to learn and error free. This program is translated into the language
of the machine before being used for operational purposes. As you may have seen in
the last session, this translation is done by the computer.
Programming languages are said to be “lower” or “higher”, depending on whether
they are closer to the language the computer itself uses; 0s and 1s - are called low or
more English-like languages are called high. These languages can be considered as;

o Machine language
o Assembly language
o High-level language
Now, let us look at each of these categories.

19
2.2.1 Machine language
Humans do not like to deal with numbers alone, they prefer letters and words. But
strictly speaking, numbers are what machine language is. This lowest level of
language, machine language, represents information as 1s and 0s - binary digits
corresponding to the “on” and “off” electrical states in the computer.
An example of machine language is shown below;
FD 71 431F 4153
F3 63 4267 4321
96 F0 426D
F9 10 41F3 438A
47 40 40DA
47 F0 4050

Machine language execution


In order to follow though the discussion of machine language to its natural conclusion
the following details of machine execution are presented here: -

 The instructions are automatically executed in the sequence in which they


occur in main storage.

 When its turn comes, each instruction is fetched from main storage by the
control unit and placed in a register. Then the control unit interprets the
instruction and causes its execution by controlling the actions of the
appropriate hardware.

 Some instructions prompt the control unit to switch to some other point in the
instruction sequence for the next fetch, and thereby give a mechanism for the
next selecting or repeating particular sequences of instructions.
 There are five basic type of machine instruction:

* Input/Output – which control the transfer of data between


peripherals and the processor.
*Arithmetic- which perform additions, subtractions, etc.
*Branch – which control repetitions and selections
*Logic- which match and compare data items
*Data handling – which move and manipulate data
Writing in machine language is a tedious business and not done nowadays
except on very few small computers. Just consider what it means for the
programmer.

 All the machine‟s operation codes have to be memorized.


 He/she would need to assign all memory addresses and keep a very careful
track on them.
 Instructions have to be written as they will eventually be obeyed, in sequence.
Thus, any instructions or deletions would entail the relocation of all
succeeding instructions.
 Subsequent revision of a completed program would be so impracticable as to
almost require a complete rewrite.

20
The whole process is very time-consuming and inefficient.

2.2.2 Assembly languages


Today assembly languages are considered fairly low-level, i.e. they are not as
convenient for people to use as more recent languages. At the time they were
developed, however, they were considered a great leap forward. Rather than using
simply 1s and 0s, assembly language uses abbreviations or mnemonic codes to replace
the numbers: A for “Add”, C for “Compare”, MP for “Multiply”, and so on. Although
these codes were not English words, they were still from the standpoint of human
convenience - preferable to numbers alone.
The programmer who uses an assembly language requires a translator to convert his
or her assembly language program into machine language. A translator is needed
because machine language is the only language that a computer can actually execute.
The translator is an assembler program, also referred to as an “assembler”. It takes
programs written in assembly language and turns them into machine language. A
programmer need not worry about the translating aspect; he or she need only write
programs in assembly language. The translation is taken care of by the computer
system.
Although assembly languages represent a step forward, they still have many
disadvantages. One is that the assembly language varies according to the type of
computer. An assembler for one type of IBM computer, for instance, will not run on a
different type of IBM computer.
Another disadvantage of assembly language is the one-to-one relation between the
assembly language and machine-language. For every command in assembly language
there is one command in machine language. Assembly language may be easier to read
than machine language, but not very clear.

2.2.3 High-Level Languages


The invention of high-level languages in the mid 1950s transformed programming
into something quite different from what it had been. The programs could solve much
more complex problems. At the same time, they were written in English-like manner,
thus making them more convenient to use. As a result of these changes, the
programmer could accomplish more with less effort.
High level languages move away from machine dependence and are generally more
problem oriented.

Activity 2.1

Compare and contrast the 3 different levels of programming languages.


Machine language
Assembly language
High-level language

21
2.3 Features of High-Level Languages
Here are a few distinct features of high-level languages;

 They have an extensive vocabulary of words, symbols and sentences.


 Programs are written in the language and whole statements are translated in to
many sometimes hundreds, of machine code instructions.
 Libraries of macros and sub-routines can be incorporated.
 As they are problem oriented the programmer is able to work at least to some
extent independently of the machine.
 A set of rules must be obeyed when writing the source program, similar to
rules of grammar in writing English.

2.3.1 Characteristics in high level languages


High level languages are characterised by the use of following features: identifiers,
variables, constants, assignment and expressions.

Identifiers and Variables


Identifiers are descriptive names that are mapped to locations in the computer's
memory. Once a memory location is given a specific name, we can refer to that
location using the identifier rather than the numeric address in the computer memory.
For example, write a simple program to calculate the sales price of a book after a
discount is given.

PriceOfBook = 440
DISCOUNT_RATE = 0.2
SalesPriceOfBook = PriceOfBook – (DISCOUNT_RATE * PriceOfBook)
(calculation: Sales price is calculated after the discount is subtracted from
the actual price of the book.)

SalesPriceOf Book, PriceOfBook and DISCOUNT_RATE are identifiers. This


system of associating a name with a memory location allows us to choose names that
give a meaning to the contents of the memory location.
If you need to compute sales price of another book, all you need to do is change the
value that is stored in the memory location named PriceOfBook. You can use the
same memory location and identifier but vary the value that is stored. Memory
locations that are used in this way are called variables.
What is the difference between identifiers and variables? Identifiers are only the
names given to variables, i.e. variable names, but variables are the actual memory
locations used to store data.

Constants
We can also use identifiers to name other things in programming languages beside
variables. Another important use for identifiers is giving names to values that remain
the same throughout a program. These values are called constants. A good example of
a value that can be used as a constant is
DISCOUNT_RATE.

22
Why do you think we need to give a name to the value for sales DISCOUNT_RATE?
Why not simply use the value 0.2? The answer is that by using constants, we can
easily modify our program to run under different conditions. For example, when
paying cash, the DISCOUNT_RATE may be .2 and when paying by credit card it
may be .15. Now whenever we need the value for the discount rate, we can use the
name DISCOUNT_RATE to refer to it.

Another advantage of using constants is that they make our programs more readable.
The identifier DISCOUNT_RATE is much more readily understood than the number
0.2.
The Table 2- 1 below compares variables and constants to highlight their different
roles.

Table 2- 1 Variables and Constants

Variables Constants
Definition A named memory location A named value
Use Value can change while a Value always remains the same while
program is running a program is running
Purpose allows data to be stored in allows programs to be easily modified
computer memory
In most programming languages, identifiers are required to conform to a certain
format. For example, the identifiers in this session all began with letters and were
composed only of letters and numbers. None of the identifiers included spaces, and
constants were written in UPPERCASE letters. This is a typical format for identifiers.

Assignment
How do we tell the computer the value, that a variable or a constant contain should be
represented? This is accomplished through the assignment operation.
In many high-level languages like C++ and Java, the assignment operation is done by
placing an equal sign between a value and a variable. On the left side of the
assignment operator is the name of a variable or constant while the right side has the
value to be assigned.

PriceOfBook = 440

In some other languages like Pascal, the assignment operator is a colon with an equal
sign like this:
DISCOUNT_RATE := 0.2

Some more examples of assignment operations;


Difference := 24 -30
Average := Sum/NoOfStudents
SalesPriceOfBook = PriceOfBook – ( DISCOUNT_RATE * PriceOfBook)

23
Expressions
Expressions are mathematical combinations of numbers, variables, and constants.
Usually the result of an expression is stored in another variable. You can think of
expressions as being very similar to equations in mathematics. A typical equation
might look like this:
SalesPriceOfBook = PriceOfBook – (DISCOUNT_RATE * PriceOfBook)

What happens when we try to construct a longer expression like the following one?
Result = 8 +10/2 – 3*3
How do we know which operations in the expression to calculate first? The answer to
this question is solved by the rules of operator precedence in a programming language.
These rules define which operations must be performed first. In mathematics, the
multiplication and division operations are performed first and then addition and
subtraction are performed. Using this rule, the value stored in result would be 3.
Result = 8 + 5 – 9
= 13 -9
=4
However, we can change the order of operations by enclosing a part of the expression
in parentheses like this;
Result = (8+10)/2 – 3*3
=9–9
=0
The parentheses tell us to compute the value of (8+ 10) before we perform the
division by 2. With this change, the value stored in result is now 0. By using
parentheses, we can override the normal order of operations in our expressions.

Boolean Expressions
We can also have expressions that represent values which are either true or false.
These expressions are called Boolean expressions. Usually such expressions involve
the comparison of values with the following operators: > (greater than), < (less than),
and = (equals). For example, consider the following three Boolean expressions:
5>7 5>5 5 == 7 5<7

false false False true


We can also have some boolean expressions with two operators that compare relative
size and equality. These two operators are >= (greater than or equal to) and <= (less
than or equal to).
5 >= 7 5 >= 5 5 <= 7

false false True


Since these are Boolean expressions, each statement is either true or false. Of course,
the answers are quite easy to determine because we know the relationship between 5
and 7. However, Boolean expressions can also be constructed from variables like the
following one:
Count < 50 ???

24
Without knowing the value of the variable count we cannot determine the value of the
Boolean expression. Quite often an expression like this is used to control a repetitive
action. Each time the action is performed, the value of count increases until the
expression eventually becomes false. We will see more about this kind of control in a
later session.
Boolean expressions can be joined together to form longer expressions using three
logical operators: AND, OR, and NOT. Suppose we want to test our count variable to
determine if the count is between 0 and 50. We can write a Boolean expression using
the AND operator to do this.
(Count > 0) AND (Count < 50)

Activity 2. 2

 Please select a group in Moodle class to complete your online activities.


 To do that first enter the Moodle Class, read the „Start here‟ page and go to the link that
says „Select your group for on-line activities‟. There, select a group for yourself.
 Then, according to your group, go to the Wiki created for „Evolution of Programming
languages‟.
 There, see whether somebody has answered following 2 questions. If not answer them.
You can modify the answer to improve if necessary and go to question iii.
1. What is meant by an identifier?
2. What is the use of having Constants in a programming language?
3. Write the name of a programming language of your choice and explain how variables are
defined for that language.

2.4 Programming paradigms


A computer program is set of instructions that are arranged in a structured way to
perform a specific task when executed by a computer. Stored program concept was
introduced with the Von Neumann computer architecture, which is the inception of
modern computers. Initially, all programs were written in machine language using
only zeros and ones (0 and 1) which can be directly understood by a computer. As we
discussed earlier, with the expansions of user‟s needs, writing with the machine
language became very difficult task. Then the assembly language emerged, but the
programmer needs to have a deep knowledge about hardware and a considerable time
when writing programs using assembly language. It is very difficult to debug
programs written in assembly language. Therefore, writing programs of large software
is very difficult task.

2.4.1 Paradigm
Long ago, people thought that the center of the universe is earth, but later people
knew earth is not the center of universe and learned the solar system. Earth centered
concept is one paradigm and solar system concept is another paradigm. Here, the earth
centered paradigm is shifted to solar system paradigm. Paradigm is a set of theories,

25
perceptions, concepts, and practices within the community about a subject at a
particular time. It is a set of generally accepted scientific achievements and models
that defines how to look problems and how to solve them. After some time,
community starts to criticize it and emerge a new paradigm. This process is called
paradigm shift. This shifting takes long time because minds, concepts, attitude of
people need to be change with understanding drawbacks of exiting system. In the
above example, paradigm shift from earth centered to solar system paradigm.
Likewise, programing also has a lot of paradigm and their shifts.

2.4.2 Emerging of Programming paradigms


Higher level programing languages emerged to solve the problems of lower level
languages. Very soon, developers faced other types of problems when they tried to
find software solutions for complex problem solving. Then software development
methodologies emerged. As a result, lots of software programming paradigms
emerged.
Programming paradigm is a way of classifying programming languages according to
their features and way of achieving goals. There are 2 main different Paradigms are
emerged for programming languages in different time periods. They are Imperative
programming paradigm and declarative programming paradigm.

Imperative programming paradigm


This is the oldest and most traditional programming paradigm. This paradigm is
developed with emergence of machine and assembly language which is suitable for
stored program concept of Von Neumann computer architecture.
Main feature of this paradigm is sequence of explicit commands. Final result of the
program is achieved by written commands or instructions sequentially from begin to
end of the program. User must write the command correctly and feed into the
computer to achieve the desired result. Imperative paradigm can be abstract to the
phrase

First do this and next do that

For example in C, following program has 3 commands, first print “Welcome” next
command is print “to” and finally, next command is print “C”.

#include<stdio.h>
int main()
{
printf("Welcome\n");
printf("to\n");
printf("C\n");
return 0;
}

26
Usually, in this paradigm, commands can be grouped and a name can be given for the
group. This is called sub program or sub routine. For example, if a program needs 2
delays for different times, we can write a delay subroutine (sub group) and can send
needed time.

void delay(int x)
{
int i;
for(i=1; i <=x; i++);
printf("Delay is %d\n", x);
}
int main(void)
{
delay(2);
delay(100);
return 0;
}

Another feature is the variable and value of the variable located in a memory location.
Values of the variable can be changed by the user.
There are many programming languages under the imperative programming paradigm
such as C, Pascal etc.

Declarative programming paradigm


Declarative programing paradigm can be divided into two types. They are called
functional and functional logic programming.

Functional programming paradigm


In mathematics, function is a rule, expression or law that has a specific output with
one or more inputs. For example, circumference of a circle is given by the function

Here, “r” is an independent variable and “c” is dependent on “r”. 2 and are
constants. “c” depends only on the “r”. We cannot change “c” as we want.
In imperative paradigm, output variable of a function can be changed explicitly but in
functional programming paradigm, output cannot be changed explicitly.
Another feature of functional programming is abstraction. Abstraction is hiding the
inside implementation details codes. This can be reused in another place.

Functional logic programing language


Functional logic programing paradigm includes both functional and logical concepts.
Best example of functional logic programing language in this paradigm is Prolog.
Following program describes the Prolog functions and rules.
bigger(elephant, horse).
bigger(horse, donkey).
bigger(donkey, dog).
bigger(donkey, monkey).

27
is_bigger(X, Y) :- bigger(X, Y).
is_bigger(X, Y) :- bigger(X, Z), is_bigger(Z, Y).

In the above program, line no 1 is “bigger(elephant, horse).” which means “elephant


is bigger than horse”. Here, “bigger” is the name of the function. When you run the
above program and if you type the query “?- bigger(elephant, horse).”
in Prolog prompt, it will give the answer as . But if you want to obtain the answer
“? - bigger(elephant, monkey).” You should write rules as shown in the last two lines.

2.4.3 Database management language Paradigm


Database management language is a type of declarative programming language for
creating and controlling database systems. Mainly, there are two paradigms of
database management languages. They are structured Query Language (SQL) and
NoSQL.

Structured Query Language (SQL)


SQL is used to manage relational database management systems. Relational database
includes tables, relations between tables and schemas. Few examples for the SQL
languages are MySQL, MS SQL server, Oracle. Example for a relational table is
shown in figure 2- 1.

figure 2- 1 An example of a relational database

For example, SQL command to retrieve registration number and name of the students
in the student table is as follows
SELECT st_reg_no, st_name FROM student;

28
NoSQL
NoSQL is used to manage document-oriented databases. Collection of NoSQL is

figure 2- 2 A document collection

equivalent to a table in a relational database. Document relates to a row and field


relates to a column of a relational database. NoSQL has dynamic schema for
unstructured data, and data is stored in many ways: it can be column-oriented,
document-oriented, graph-based or organized as a KeyValue store. You can see it in
figure 2- 2. First document has id, Address and Date of birth while second document
has id, name and Address.
Following NoSQL command can be given to display all the documents in a collection.
db.getCollection('student').find({})
Following NoSQL gives the output of “Address=Mahara”
db.getCollection('student').find({"Address":"Mahara"})
Output for the above NoSQL command is shown in figure 2- 3.

figure 2- 3 Example of an output of NoSQL command

NoSQL has following flexibilities.

o can create documents without having to first define their structure


o each document has its own unique structure
o the syntax can vary from database to database, and
o you can add fields as you go

29
2.4.4 Object Oriented programming (OOP) paradigm
Object oriented programming paradigm is derived from imperative paradigm and
OOP concepts. OOP concept is writing computer programs considering objects and
their relationships. For example, a car is manufactured by combining several relevant
components such as engine, gear box, wheels, lights and many more. And it has
several actions such as going, turning, accelerating, decelerating, breaking etc. These
components are called attributes and actions are called methods. Template for an
object in a program is called class.

Following picture shows a class called „person‟. Its attributes are name, surname, birth
date, address, telephone, and email. It has only one method named age(). It converts
the date of birth entered into age.

Following python program described the how to program the class Person, its
attributes and the method age().

import datetime # we will use this for date objects


class Person:
def __init__(self, name, surname, birthdate, address, telephone, email):
self.name = name
self.surname = surname
self.birthdate = birthdate
self.address = address
self.telephone = telephone
self.email = email
def age(self):
today = datetime.date.today()
age = today.year - self.birthdate.year
return age-
person = Person("Jane",
"Doe",
datetime.date(1992, 3, 12),
"No. 12 Short Street, Greenville",
"555 456 0987",
"jane.doe@example.com"
)
print(person.name)
print(person.email)
print(person.age())

30
2.4.5 Parallel Programming
In current market, processors of smart phones and computers include more than one
core, usually, five (5) or more. These cores can process programs separately and in
parallel. Running programs simultaneously with multi-processor has less processing
time than running programs with single processor. You can see the difference of
processing time, by comparing time to process with multi processors, and time to
process with single processor. According to the figure 2- 4, the time to call the
function f() 4 times with multi-processor is, and with
single processor is, .

figure 2- 4 An example of parallel processing

Activity 2.3

List down different types of programming paradigms and give examples for each.

31
Summary
In this session we discussed the evolution of programming languages from the
inception, different paradigms of programming languages and the features of high-
level languages.
A programming language is the key to communicating with the computer and it has
certain definite characteristics. It has a limited vocabulary or a set of keywords. Each
keyword has a precise meaning. There is also a set of rules or syntax to organize the
instructions in a program. Even though a programming language is limited in
keywords, it can still be used, in step-by-step fashion, to solve complex problems.

Learning Outcomes:
After studying this session you should be able to,
 Describe evolution of programming languages from machine
language to high level languages
 Explain features of high-level languages like identifiers, variable,
constants, assignment and expressions
 Identify different types of programming paradigms

32
Session 3
Introduction to Software Engineering

Contents
Introduction, p 33
3.1 Software and Software Engineering, p 33
3.2 The Product Life-Cycle, p 34
3.3 Hardware/Software Differences, p 35
3.4 The Software Life-Cycle, p 36
3.5 Verification and validation, p 38
3.6 Requirement Elicitation, p 38
3.7 Stages of the Software life cycle, p 39
3.8 Waterfall Life Cycle Model, p 40
3.9 Prototyping, p 43
Summary, p 43
Learning Outcomes:, p 44

Introduction
In this session you will be exploring how the term „software engineering‟ emerged
and learn the phases in software life cycle. You will also see the differences between
hardware and software.

3.1 Software and Software Engineering


Contrary to the popular belief, Software is not just 'a set of programs' and
development of software is not just 'writing programs'. Software comprises of more
than 'programs', and developing software involves many activities in addition to
writing programs or coding. Software also includes the data structures that enable the
programs to hold the data and manipulate it, and the documents that describe the
system and the use of the programs.

The institute of Electrical and Electronics Engineers Inc. (IEEE), in its standard
610.12-1990, defines software as “computer programs, procedures, and possibly
associated documentation and data pertaining to the operation of a computer system”.

33
What we all know is, that a software system is made to solve a certain problem.
Making software therefore begins with understanding the problem and then designing
and constructing the software system to solve the problem.

To understand the software process, we must recognize that a systematic approach is


required to proceed through the various stages in making a software system. These
activities are regarded as engineering activities which need to be supported by a set of
management activities that overlay the entire process.

IEEE, in its standard 610.12-1990, defines software engineering as:


1. the application of a systematic, disciplined, quantifiable approach to the
development, operation and maintenance of software; that is, the application
of engineering to software.
2. the study of approaches as in (1).

Software engineering as a discipline provides us with structured technical means of


developing as well as maintaining software. It provides methods to perform the tasks
that requires in developing any software such as; analyzing the requirements,
designing the system, coding, maintaining the system, etc. Software engineering tools
are used to support these tasks by automating the tasks or parts of the tasks.

3.2 The Product Life-Cycle


Any product goes through a life-cycle similar to living things. For example a butterfly,
which starts life as an egg, hatches as a caterpillar, then becomes a pupa, and finally
comes out as a flying creature to mate and die.
In the field of engineering, the same term is used to denote the sequence of phases
through which any product passes. In general, these stages can be listed as follows:
 Concept and feasibility study: Someone has a good idea, but will it
work?

 Requirements definition: They find out that it can be done and


decide to go ahead. Now they must define what exactly the product
will do, and the level of quality needed for it to be viable.

 High level design: What are the main elements or subsystems of


the product? How is each element required to function so as to
meet the overall product requirement? What quality is needed in
each element as to meet the quality requirements of the overall
product?

 Low level design: Each main element is broken down into its basic
components. Their functional requirements and quality
requirements are also defined relative to the requirements for the
element or subsystem. Depending on the size and complexity of the
product being designed, there may be many levels of design. The
process of breaking a complex system down progressively into

34
smaller chunks is referred to as hierarchical decomposition. At the
lowest level of design, the specified components are simple enough
to be manufactured or bought in from an outside supplier without
further design work.

 Construct and test a prototype. Proto is a prefix taken from the


Greek, meaning "sole" or "only". Initially, only a very few (and
sometimes only one) examples of a new design are constructed.
These early constructed designs are called “prototypes”. These
prototypes are tested, and any faults discovered in them are
corrected before production begins.

 Manufacture: Many copies (also referred to as "examples", or


"serials", since each one usually has a "serial number") are
produced and sold. The total sales revenue obtained must cover
both the cost of manufacture and the cost of the preceding design
process for the manufacturer to make a profit.

 Maintenance: As nothing lasts forever, hardware wears out and


must be replaced. The manufacturer will set up a maintenance
operation so that customers can have their machines repaired.
Sometimes design faults will be discovered after a product has
been on sale for a while. It is then necessary to correct the design
for later releases and in the worst cases (where the design fault
makes the product dangerous, for example) it is necessary to recall
the samples already sold.

 Obsolescence and decommissioning: Eventually it will be decided


that the present model is no longer useful or successful, and the
whole life cycle is repeated for a new, improved, design.

It is clear to see that the above life-cycle describes quite well what happens when a
new car is designed and manufactured though the actual sequence of events may vary.
A life-cycle should be regarded as a conceptual model of the process of development
and manufacturing, rather than a fixed sequence of events that must be followed. It is
an abstraction of the real process, and is useful as a tool for reasoning, in order to
plan, estimate resources, and measure the progress.

3.3 Hardware/Software Differences


Since software differs from hardware in certain essential aspects, the software life-
cycle differs substantially from the general product life-cycle. The differences can be
summarized as follows,
 Hardware is designed once, and then many copies are
manufactured. Due to variations in the manufacturing process,
these copies may differ slightly from one another, and in particular,
faults may be introduced during manufacture (e.g., due to machine
tools inaccurately set up, substandard components being used, etc.).

35
 The process of developing software consists of a series of
transformations of the design into more detailed representations
until executable code is obtained. Many copies can then be made
and released to customers. But the copying process is not the
equivalent of hardware manufacture since for all practical purpose
it is perfect, and yields identical copies. (An exception to this could
be the inclusion of an incorrect version of a module.) In this sense,
every software product is a prototype. It is only made once, even
though many copies can be distributed.
 Typically, when a hardware component breaks, the system goes
down and ceases to work until it has been repaired. Corrective
maintenance of hardware usually consists of replacing a worn or
broken part with a new part, and this restores the system to its
previous working state.
 Hardware maintenance requires the movement of resource persons
and materials. Either the machine must be brought to a workshop,
as when a car is taken to a garage, or service staff must visit the
machine, as when a thermostat in an air-conditioning system needs
to be replaced.

 Most software failures are design failures: corrective maintenance


of software improves the system design by removing faults that
were introduced during development.

 Software failures are also often transient: if the conditions that


caused the failure are removed, the system can be brought back
„up‟ immediately, and the diagnosis and repair of the underlying
fault can take place „off-line‟.

 Changing software design is easy compared to modifying a


hardware design. Part of the code is rewritten, or new modules are
added, and the software is recompiled and reissued.

 Software maintenance requires the movement of information.


Typically when evidence of a failure is given to the customer
support team, they deduce the nature and location of the design
fault and sends a „patch‟, or a corrected version of the software,
back to the customer. It is often unnecessary for an engineer to visit
the customer's site.

3.4 The Software Life-Cycle


Due to the differences between hardware and software, the software life cycle differs
from the general product life cycle. Many software life cycle models have been
proposed to represent the various approaches to software development.

Most of them include the following stages, however, although the order in which they
are carried out may vary:

36
 Concept and feasibility: Identify a marketing opportunity, or an
organisational need. On the basis of an outline of the requirements
and a first estimate of the resources needed to develop such a
system, can assess if it should be built.

 Requirements capture: Agree on what functions the system is to


perform, in consultation with the customer.

 Requirements specification: Write a detailed document including


functional requirements (What will the system do?) and non-
functional requirements (What level of quality must it have? What
constraints are there on its design and implementation?). This
document is usually the basis for the signing of a contract (for a
product which is to be developed for an external customer) or for
an agreement on what will constitute a satisfactory delivery.
 High-level design: How will the system meet its requirements?
The overall architecture is defined and the main subsystems are
identified and their functions specified.

 Low-level design: The hierarchical decomposition of the system is


continued until individual modules can be defined.

 Implementation: Individual modules are written in source code,


complied and integrated to build the complete system. User
documentation is written.

 Testing: First individual modules and then progressively larger


subsystems are tested to verify that they meet their own
specifications.

 Trial: The complete system is operated in a realistic environment


to validate that it meets its original requirements.

 Deployment: Release to customers and installation on site.

 Operation and Maintenance: The system may need to have faults


corrected, be adapted to new circumstances, or be enhanced to
perform new functions.

 Obsolescence: Retire and replace.

Activity 3.1

What does the term software engineering means to you?

37
3.5 Verification and validation
During the development of a software system (as for any other product), the manager
must continually make measurements to assure that the end product will perform as
required.

There are two main aspects to this assurance:


 Verification: "Are we building the product right?"
 Validation: "Are we building the right product?"
These simple statements capture the essence of two separate ways of assessing what is
being developed. The differences between them are of vital importance.

The quality of software is another vital factor, where software may perform correctly
but not satisfactorily due to environmental factors such as complex data structure
manipulation, voluminous sorts and communication hangs-ups.

3.6 Requirement Elicitation


The requirements capture and requirements specification phases of the life cycle
result in a detailed written description of what the delivered product is to do, and the
level of quality it must have.

The hierarchical decomposition during the following development phases defines


how the product will meet its requirements. Each phase takes an input product (e.g., a
specification) and transforms it into an output product (e.g., a more detailed
specification, or source code). The final system that is delivered to the customer is the
end product, and the input and output products of the earlier phases are referred to as
intermediate products.

However, it is possible that the requirement specification is less than perfect. Either
requirements capture failed to capture the real world requirements of the customer, or
the requirement specification did not accurately represent these. In this case, we might
end up delivering a product which has been verified as being correct all the way
through the life cycle, but which fails in operation because it does not do what the
customers requires or reasonably expects.

Therefore, Validation requires that the system undergoes a trial: a period of operation
under conditions which are as close as possible to those it will encounter in live use.
The actual staff from the customer's organisation must operate it and the workload
must be as heavy as the worst case likely to be experienced. This is the only way we
can ascertain that software products will work as expected when exposed to reality.

38
3.7 Stages of the Software life cycle
The classic lifecycle is divided in to four major stages as illustrated in Figure 3- 1.

Figure 3- 1 Four phases of software life cycle

3.7.1 Analysis
Analysis phase includes investigation of the current system in i.e. the problem domain,
to find out the requirements of the proposed system, and whether it is feasible to
implement a solution to satisfy the identified requirements. In this investigative
process (see Figure 3- 2) current bottlenecks, constraints and performance statistics
would be made known.

Figure 3- 2 Analysis phase

The requirement specification, which is a high level specification of the users‟


identifiable needs and the financial or other constraints applicable, is the major output
from the analysis phase. Management has to decide on the basis of the study results,
whether it is feasible or not to proceed with the design and construction of the system.

3.7.2 Design
The next phase is the design of the proposed system. Where the analysis of the
problem domain is best undertaken by a business consultant with the knowledge of
the application area concerned, the design process is best undertaken by a systems
analyst with expertise in design, building and implementing in computer based
information systems.

The system specification document is usually the basis of the contract undertaken to
build the system as per the requirement specification. Thus, it is an extremely
39
important document, encompassing the software and hardware architecture, the
database and data structures proposed and the procedures for manipulating the
database in order to produce the required output.

The design process, in fact, as Figure 3- 3 illustrates, translates the user requirements
into system components which interact to provide these requirements. As in any
architectural procedure, the system specification is the precise document of the design
process and is the basis of the construction phase. It is, therefore, a vital component of
the software configuration of the system. Each component identified by the
specification can be estimated in terms of resource requirement for building it or in
terms of purchase finance, and the entire system can be budgeted for both its hardware
and software components. The design document is written in a natural language but is
accompanied by a variety of graphical forms, such as a structure charts/flow diagrams,
screen and report designs/formats. Sometimes the design may be expressed in a
design language, particularly where reverse engineering is envisaged.

Figure 3- 3 Design Phase

3.7.3 Development and Testing


In the traditional lifecycle model, the next phase is development i.e. the writing of a
set of program specification and the construction of programming language code for
each specification.

Programming or coding individual modules is a parallel activity, where the program


team responsible for each module will encode, compile, test and debug each function
in parallel with other teams performing the same activities with their respective
functional modules.

When all the modules have been compiled error free and tested individually and
comprehensively on test data beds, the modules are interlinked and a series of system
test are performed.

3.8 Waterfall Life Cycle Model


Early versions of software life cycle models can be classified as the Waterfall life
cycle model. This is a linear model, where the tasks that go into making a software
system are performed sequentially, in predefined phases. The life cycle model shown
in Figure 3- 4 is a version of the waterfall life cycle model, with six phases. A phase in

40
the waterfall life cycle model can start only after all tasks in the previous phase are
complete. The waterfall life cycle model assumes that activities of a previous phase
need not be repeated after the next phase starts.

Early software developers did not develop software using life cycle models. In the
first few years, software development was essentially seen as a „programming' activity
followed by the 'implementation' activity, with other tasks seen as an extension of the
programming and implementation.

This led to considerable amount of bug fixing during implementation, resulting in


delays and cost overruns. To overcome these problems, developers started performing
'testing' as an activity between the programming and implementation. Over time,
requirements, design and deployment were identified as important activities and
converted into phases. The waterfall life cycle model which evolved with time, puts
together all of these in their natural sequence.

Figure 3- 4 Traditional Waterfall life cycle model

Phases in the Waterfall life cycle model can be briefly described as follows:
 Requirements is the phase where the 'what' of the software system
is defined. It involves extensive user participation to gather user
requirements and ends with an approved set of requirements
documented in a Software Requirements Specifications (SRS)
document. These Software Requirements Specifications form the
basis of all further work in the project.

 'How the system to be built' is defined in the design phase. Here,


the problem definition specified in the Software Requirements
Specifications is translated into a design which will solve the
problem. The design phase is a bridge between 'what' the user

41
wants and the code that will be created to satisfy the requirements.
Some versions of the waterfall life cycle model split the design
phase into architectural design and detailed design phases.

 The code is written during the construction phase. Compared to


the earlier phases, this phase is typically executed by a larger team.
The User Manual is also usually written in this phase.

 The code that is developed is tested during the testing phase. This
involves unit testing for the lowest level components, integration
testing for groups of components and testing of the system as a
whole. The last activity in testing is usually that of acceptance
testing. Acceptance testing validates that the system fulfills the
'user's needs' and requires considerable user involvement.

 The system is finally made operational in the deployment phase.


Main activities in this phase include training of the users,
installation of the system; switch over from the existing (manual,
semi-automated or automated) system to the new system.

 The system thereafter rolls into the operations and maintenance


phase. During this phase leftover defects are corrected, if required,
the system is made more efficient, new requirements are added and
existing functionality and features modified to meet the ever-
changing business needs.

The waterfall life cycle model has the following advantages:


 The model has well-defined phases with well-defined outputs.
 It recognizes the sequence of software engineering activities that
shall result in a software product.
The main disadvantages of this life cycle model are:
 The model assumes that requirements are clearly specified at the
beginning of the project. The model has no mechanism to handle
changes to the requirements that are identified because of design
and construction activities, or user feedback.
 The model reduces the users' involvement between the design and
testing phases of the project. This creates a gap and reduces users'
feeling of 'ownership' as the model provides no forum for active
participation from the users during the intermediate phases of the
life cycle.
 User feedback is not taken as the system is started built. In actual
projects, often the requirements become clear once the users get a
chance to see and use the software in operation.
 For large projects, the users have to wait a long time for the
delivery of the system. Requirements may change and systems may
even become redundant by the time they are delivered.
 Developers have very little interaction with the users and the
tendency to add features that are not really needed, is resulting in
higher duration and cost for features that were not required.

42
 The assumption that all requirements have to be known at the
beginning in sufficient detail leads to premature decisions.
 The waterfall life cycle model is essentially inflexible. It assumes
that software creation activities can be compartmentalized.

3.9 Prototyping
Prototyping is a software engineering technique that has asserted itself very rapidly,
mainly due to the increasing costs of software maintenance. It is a way of ensuring
that the specification and design model are correct before construction which
procedure generally assists in ironing out any incompatibilities between requirements
and the deliverables. The prototype serves as the “initial test system”.

The idea of a prototype is a quick off-the-shelf construction to demonstrate certain


essential features of the proposed final product. It can then be used and evaluated by
the user, which serves to give feedback to the requirements specification and design
phases. It can be iteratively tuned to mirror the user‟s requirements. It helps the
developer better understand the user‟s psychology i.e. what is important and what is
not.

3.9.1 Problems of Prototyping


There is a problem associated with prototyping through lack of understanding. The
user does not realize this is a quickly put together job and only contains what is
visible to the user. It is constructed using available tools, program fragments lying
around and a rigged database. The user however, assumes that the prototype is a
miniature working system and now only needs enhancement to become the real
system. User would not believe that the system still has to be built up literally from
scratch.

Design for prototyping ignores the functions, internal procedures involved and
focuses instead on top-level architectural structure and on data analysis and design.

Activity 3.2

Briefly describe phases of the Waterfall cycle.


What is the use of prototyping?

Summary
In this session we discussed that developing software involves many activities in
addition to coding programs and how software development has been transformed
into an engineering discipline.

43
The classic model of the conventional system engineering cycle has a sequential flow
of phases such as requirement elicitation, requirement analysis, design, coding, testing
and maintenance. This sequential flow has given rise to many problems when
developing software.
After reading this session you should be able to achieve the following outcomes.

Learning Outcomes:
On completion of this session, the learners will be able to,
 recognize the need for a disciplined approach to software system
development
 identify the key attributes of a software product
 describe the software life-cycle
 explain the importance of prototyping in software development

44
Session 4
Requirement Elicitation and Documentation

Contents
Introduction, p 45
4.1 Requirements Elicitation, p 45
4.2 Resolving Ambiguities, Platitudes and Omissions, p 47
4.3 How to Resolve Functional and Non-functional Requirements?, p 49
Summary, p 51
Learning Outcomes, p 51
Review Questions, p 52

Introduction
In the software development process the first step is to conduct a feasibility study to
see whether it is really worth developing a new system. We will not discuss feasibility
study in this course. If it is decided to develop a new system after a feasibility study,
the next step is to gather requirements from the stakeholders of the software system.
In this session, we will first discuss different methods of requirement elicitation and
resolving ambiguities, platitude, and omissions in the gathered requirements. Then,
we will differentiate requirements to be functional or non-functional. Finally, you will
see the factors that needed to be considered when making a requirement document. A
requirement document is mainly read by managers, clients and system end-users.

4.1 Requirements Elicitation


In order to gather requirements, you must identify the stakeholders of the system first.
That is who are users, administrators and beneficiaries of the system. For example, a
student detail management system at a university will have students as beneficiaries
who would see their time schedules, marks, financial information etc, lecturers and
administration staff as users who input course details, marks, financial status etc to the
system and the IT staff as administrators.

A stakeholder‟s perception of the system's behaviour depends on the his/her


experience and background knowledge, and the environment within which the system
is embedded. Therefore it is necessary to consider information about application
domain as well. Application domain could be as varying as personal data management,
accounting, insurance, scheduling (aircraft landing), ticket reservation or scientific
modelling. Domain knowledge is necessary to enable the analyst to reach a common
ground for understanding the user world. During requirement elicitation all such
knowledge must be obtained.

45
Let us now discuss few elicitation methods which are based on commonly accepted
social activities and behaviours.

Interviews: Interview can be questionnaire based or open-ended. Questionnaire


interviews consist of a pre-determined set of questions that the analyst has drafted to
get the user responses recorded. Questionnaire interviews may limit the topics of
investigation to those raised by the questions unless they facilitate unplanned issues to
be raised.
Open-ended interviews allow the participants to relate what they expect as a problem
solution. Interviews are useful in allowing domain knowledge to be identified.
However, interviews depend on the ability of the interviewees to express their
concerns adequately. They usually articulate their needs as they perceive them, and
may fail to explain their needs from a detached and global perspective. Furthermore, it
is observed that interviewees are often unable to explain necessary tacit knowledge
satisfactorily.

Use of focus groups: Focus groups are similar to interviews, but with a carefully
selected smaller group of stakeholders. Here, the analyst sets a topic of interest and
lets the group discuss it openly. An important factor in the success of focus groups is
the choice of participants. The analyst must take into consideration the positions of
the participants within the organization, their authorities and abilities to discuss
matters of concern.

Observation: This is the process where information is gathered about tasks, by


observing users engaged in performing the tasks. However, users can experience
difficulty in describing satisfactorily about the work they carry out.

Prototyping: In prototyping, a software prototype is produced and presented to the


user for evaluation. It will provide first-hand experience to the users of how the
software system will behave. Prototyping is very useful when establishing
requirements for user interfaces. Moreover, shortcomings in the systems
functionalities can also be identified early and corresponding improvements can be
carried out until the user is satisfied.

During the development of a software prototype, design decisions are often made
early in the software development process, and considerable effort from the software
developers are required. However, a "throw-away" prototype (designed to be
discarded after use), can be used, with care, to validate some functionalities of the
software system. One disadvantage is that, users may draw incorrect conclusions
about other characteristics of the software, based on their evaluation of the prototype
presented to them. Hence the exact purpose of the use of the prototype needs to be
clearly established and understood by both the software developer and the users.

Animation: During animation, features of the software that are difficult to specify are
"role-played" by human beings. Animation has been proposed to resolve some of the
problems associated with software prototype, and specially to reduce their

46
development effort. Since animation emphasizes the effects and the relationships
between processes, instead of how the results are achieved, it is more appropriate for
early requirements elicitation purpose.

Scenario analysis: Used together with prototyping and animation, scenario analysis
allows the software developer to investigate system responses to various conditions.
The user is required to answer when scenarios are given in "IF condition THEN
response" manner. In this way the user has to elicit the behaviours of the system in
specific situations. By appropriate choice of scenarios, the functional requirements of
the software can be comprehensively identified.

Introspection: In this process, the software developer imagines the tasks that the
system would perform. Though introspection has obvious limitations, it is can be
used when there are software features that the user may have little experience with,
such as the user interface. Prototypes can be used for validation of such assumed
features.

Thus extracted, requirements are usually compiled to make a requirement document


which needs to be further refined.

Functional requirements are basically the service that the proposed system should
provide whereas non-functional requirements are the concerns of the system
properties such as reliability, storage occupancy and response time. The requirement
document contains both functional and non-functional requirements, so let us see how
we can differentiate them in the next section.

4.2 Resolving Ambiguities, Platitudes and Omissions


To understand further about requirement elicitation for a new system, let us consider a
simple problem solution for automating a vehicle service system in a small garage.
Consider the following initial statement of requirements for a system ordered by the
owner of a small garage.

KGF Requirements
Kumudu Garage Follow-up (KGF) system will keep records of customers and their vehicles.
It will send reminders to customers whose vehicles are due for a service in the following
week. When a vehicle is booked in for servicing, it will print a job sheet for the mechanic,
describing the work to be done. When the job is completed, the time spent and the prices of
the spare parts fitted will be added up and an invoice will be sent to the customer. At the end
of the month, it will print a list of all unpaid invoices, and reminders to be posted to all
customers whose invoices have not been paid for some time.
The prices of spare parts will be taken from the garage's existing stock control
database, which is not actually a part of KGF, though it will need to be updated when
spares are taken out of the stores. KGF must run on the garage's existing personal
computer, which is networked with the stock control database, and it must be easy to
use.

47
End of KGF Requirements

Any requirement document made by the user or the business analyst may contain
ambiguities and platitudes. There could be omissions as well. Usually, functional
requirements are mixed up with various types of non-functional requirements. What
questions would you (as the developer of KGF) ask in order to clarify the
requirements?

Here you have been given a suggested set of general questions that should always be
asked. You have also been given certain categories of things that can be wrong with a
requirement definition, which should prompt more specific questions.

General questions and answers


1. Why is KGF needed? To improve customer relations, increase number of
customers returning for service, improve control of debtors, etc.
2. What are the main functions of KGF? See section on functional requirements.
3. What is the scope of the KGF system, and where will it be used? It includes
use of early data stores. It excludes salary calculation of employees and
inventory system. However, it should have an interface to inventory system to
acquire prices of parts used when compiling invoices. System will be used on
the existing personal computer at the garage.
4. What are the elements and subsystems of KGF? Physically, it consists of the
components of the PC and a printer. The software may consist of different
modules to perform the listed functions.
5. How is KGF controlled? Various possible answers, including automatic
generation of certain periodic reports, user commands to initiate other
functions (e.g., book-in and sign-out, etc.)
6. Who are the users of KUMGAR? The receptionist, who books in vehicles for
servicing, the manager, who checks the invoice and overdue accounts. The
mechanics, who receive job sheets informing them of work to be done, will use
the output of the system, but will not be direct users.
7. When is KGF required? 6 months from now (for example).
8. What are the government taxes that should be considered for this business?
Some indication of maximum price of contract should be given.

Clarify platitudes
1. What does "easy to use" mean? No staff training required. Use of menus, help
screens, etc.
2. What customer data are stored? Name, address, customer number, phone
numbers, etc.
3. What vehicle data are stored? Registration no., make, model, owner NIC.
4. What job data are stored? Date/time of booking in, mechanic, vehicle reg.,
time, hourly rate, parts used, part prices, total cost.
5. What invoice details are stored? Customer, address, date, amount, status (paid,
unpaid, overdue, taken to court, etc.), date of payment (if paid), dates of
reminders sent, etc.

48
Resolve ambiguities
1. What does "in the following week" mean? Obviously, if the vehicle's service is
due on a Monday, there is no point in sending a reminder on the previous
Friday. The reminder must be timed so that there are 5 working days between
the reminder and the due date.
2. What does "when the job is completed" mean? The time spent and parts used
will be recorded by the receptionist after the mechanic has returned the
completed job sheet, with these details filled in. Invoices will be printed at the
end of the working day on which the job is completed, for posting on the
following day.
3. What does "at the end of the month" mean? The last working day of each
calendar month.
4. What does "for some time" mean? Any invoice which has not been marked as
"paid" one full month after the date of posting will be followed up by a polite
reminding letter. After 2 months, a stronger letter will follow.
5. Will the stock control database be updated by KGF? No, the existing stock
control database has been working for some time, and the store-keeper
updates it when a mechanic draws a part out of store. KGF will only need to
obtain the current price of spares used from the other database.

Include omissions
1. How are reminder letters composed? For all levels of reminder, the necessary
information will be extracted from the invoice file and inserted automatically
in the appropriate standard letter.
2. Should the list of unpaid invoices include the date sent, and date and type of
any reminders? Yes.
3. How is time priced? The mechanic fills in the actual hours worked, and these
are multiplied by our standard rate when calculating the price.
4. When is VAT included? The price of all spares is added to the time price to
give the net total, and VAT is added at the current rate?
5. What if current VAT rate changes? Obviously it can happen, and the software
should accommodate for that
6. Are other types of regular servicing required? Yes. The receptionist will check
the date of the next regular service due, taken from the log-book.

Activity 4.1

Write a list of more questions that you would ask the garage owner and provide
reasonable answers. To give the answers, you will have to change roles and
pretend to be the customer.

4.3 How to Resolve Functional and Non-functional


Requirements?

A non-functional requirement specifies criteria that can be used to judge the operation
of a system, rather than specific behaviors. In general, functional requirements define
what a system is supposed to do whereas non-functional requirements define how a
system is supposed to be.
49
Non-functional requirements can be divided into two main categories:

1. Execution qualities, such as security and usability, which are observable at run
time.
2. Evolution qualities, such as testability, maintainability, extensibility and
scalability, which are embodied in the static structure of the software system.

Here are a few questions that can be used to extract non-functional requirements.
1. The system must be "easy to use": how easy? Our existing staff (receptionist
and myself, the owner) are used to our existing salary package. We have no
specialised computing or programming knowledge. So, KGF must be usable
by either of us with no further training than reading your user manual and
referring to on-line help if absolutely necessary (e.g., for infrequent operations,
such as changing the VAT rate). For all day-to-day operations, KGF must be
capable of being driven solely by menus.
2. Are there any other quality requirements, e.g., reliability? Yes, of course. I do
not expect the system to crash at all in use, and miscalculations of finances, or
sending unjustified reminders.
3. What is your existing hardware? PC with ...etc., etc.
4. Are you prepared to upgrade the PC to run KGF ? No! I want the new system
to run on the existing machine as it is, without affecting our existing work, and
with no additional hard-ware purchase. (.. and so on. The point is that the
contractor must clarify the hardware constraints which the software must
operate.)

Non-functional requirements cannot be left ambiguous. They must be stated in a way


that is quantifiable. Otherwise there is no way to validate whether these requirements
are met or not.

For example, if the user says system should be „very fast‟, the business analyst and the
user must come to an agreement to define how fast is „very fast‟. It could be written as
a database with 36,000 records should respond to a simple query in 20 ms.

Activity 4.2

a) Re-write the following requirements so that they may be objectively validated.


You may make reasonable assumptions about the requirements.
i. In case the software system goes down, it will be able to
recover with minimum delay.
ii. Response time of the system will be very quick.
b) List any more non-functional requirements that could be related to the
proposed system.

50
Using the information you have acquired, how do you develop the requirement
document to the next level of detail? First, separate functional and non-functional
requirements clearly and give a brief description of each function to be performed.
This is not expected to be a fully-detailed requirements specification, and you need
only provide a brief statement for each function.

Activity 4.3

a) Define the term „stakeholder‟ in the context of a software system. Name three
possible stakeholders of a „student data management system‟ of a University
with few faculties and more than 2000 students.

b) What is the possibility of arising conflicting requirements among above


mentioned stakeholders.

c) Identify three non-functional requirements of the „student data management


system‟ described in (b).

In the next session we will see how to analyse the gathered requirements before
making the Software Requirement Specification (SRS). SRS is the most
comprehensive document that would be made out of the requirement elicitation and
analysis phase.

Summary
Requirement elicitation practices include various methods such as interviews,
questionnaires, user observation, workshops, brain storming, role playing and
prototyping.

There are two major types of requirements; functional and non-functional. Functional
requirements define what a system is supposed to do, i.e. all functions expected from
the system, whereas non-functional requirements define how a system is supposed
behave in terms of usability, reliability, performance, security etc.

Learning Outcomes
On completion of the session, the learners will be able to:
o Describe the strengths and weaknesses of different approaches to requirements
elicitation
o Identify ambiguities, platitude and omissions in user‟s requirement document
(or statements)
o Categorize requirements into functional and non-functional
o Apply requirements elicitation methods to discover requirements

51
Review Questions
o Discuss how tradeoffs between different system requirements might be
necessary for a proposed computer-based system design. ??
o Describe the importance of feasibility and economic considerations
o Describe different approaches to determine requirements: interviews,
prototyping, role playing, animation
o Identify functional and non-functional requirements
o Explain the quantification issue in non-functional requirements

52
Session 5
Requirement Analysis with Data Flow
Diagram (DFD) and Unified Modeling
Language (UML)

Contents
Introduction, p 53
5.1 Illustrating Requirements with a Data Flow Diagram (DFD), p 53
5.2 User-Centered Development and Use-Case Modeling, p 55
5.3 Modelling Requirements with Use Cases, p 58
5.4 Advanced Use Case Modelling Concepts, p 60
5.5 Illustrating requirements with a Use case diagram, p 61
5.6 Writing a Use case Narrative, p 63
Summary, p 65
Learning Outcomes, p 65

Introduction
In this session we will discuss how to analyze requirements with the use of data flow
diagrams and use case diagrams.

Without going into detail of Unified Modelling Language (UML), we will discuss
basic features of a Use Case diagram in order to apply it to analyze requirements. Use
case narrative is a description to further elaborate what is depicted in a use case
diagram. We will see one example of a Use case narrative also here. When writing a
Software Requirement Specification (SRS), you will have to use one of these
techniques, a DFD or a Use case diagram to illustrate requirements in detail.

5.1 Illustrating Requirements with a Data Flow Diagram (DFD)


A DFD is a graphical technique for depicting information flow through a system.
DFDs are used to analyze the problem domain with a view to identify the data flow
through the domain and the operations being performed on the data at different points.
The view of overall system or the zeroth level of a DFD is called the context diagram.
The next level of detail will be in the Level 1 of the diagram, which depicts the
overall problem solution. Each of the functions/processes shown inside a circle can be
taken out and decomposed into a set of second level DFDs. This process can continue
to few more levels as necessary.

53
Now let us draw the context diagram for the Kumudu Garage Follow-up system based
on the details we know.

Figure 5- 1 Context diagram

Since we haven‟t analyzed all the functional requirements, it is difficult to draw a


Level 1 DFD here. However, here you can see a part of a level 1 DFD.

The flow of information through a system, as represented by a DFD is fairly easy to


follow. It is also easy for the analyst to structure his/her analysis of the information
domain through DFD‟s. However, our problem with DFD‟s is that there is no explicit
indication of the temporal order of events. Which precedes which and happens before
what?

54
Figure 5- 2 Data Flow Diagram (Level -1)

5.2 User-Centered Development and Use-Case Modeling


One of the major challenges in a system design process is finding out the correct
system requirements from the stakeholders and specifying them in a manner
understandable to them. This is very important so that those requirements can be
verified and validated.

User-centered development approach is proposed in order to reduce the problems


faced in software development projects. It is a process of system development based
on understanding the needs of the user and the reasons why the system should be
developed.

Use-case modeling is the process of modeling a system‟s functions in terms of


business events: who initiated the events, and how the system responds to those
events. Therefore, Use cases facilitate user-centered development. A use case diagram
is an effective tool for communication as well as for requirement validation.

What is a Use Case? A use case represents a single goal of a system and describes a
sequence of activities and user interactions in trying to accomplish the goal. It is
actually a description of system functions from the view of external users.

55
Figure 5- 3 Actors and business processes

Example tasks that can be documented using use cases,


 Opening a bank account
 Buy a soft drink from a vending machine
 Place an order for a book

Use-Case Modelling Tools - Use cases are documented using use case diagrams and
use case narratives.

Use-case diagrams – Depict the interactions between the system and external systems
and users. These diagrams graphically describe who will use the system and in what
ways the user expects to interact with the system.

Use-case narratives – Describe in text about business events and how users will
interact with the system to accomplish tasks.

When is Use-Case Modelling Done?


 Use cases are initially defined during requirements analysis – to model (at a
high level) the functionality of the proposed system.
 They are refined during design to show how users will actually use the system.
 They aid in programming and testing during coding.
 They also are the basis for preparing user documentation and training during
implementation.

56
Use-Case Symbols

Figure 5- 4 Use case symbols Actor and Use case

Symbols used to draw use case are shown in Figure 5- 4.


Actor – Actor symbol is shown in (a) of the Figure 5- 4. Actor is anything that needs
to interact with the system to exchange information. It could be a human, an
organization, another information system, an external device, or even time.

Use case – Symbol for the use case is shown in (b) of the Figure 5- 4. It a subset of
the overall system functionality. It is represented graphically by a horizontal ellipse
with the name of the use case appearing above, below, or inside the ellipse.

Temporal event – a system event triggered by time. Here the actor is time.

Types of Actors – There are four types of Actors

1. Primary business actor - Stakeholder that primarily benefits from the


execution of the use case. e.g. employee receiving a pay cheque
2. Primary system actor - Stakeholder that directly interfaces with the system to
initiate or trigger the business or system event. e.g. bank teller entering deposit
information
3. External server actor - Stakeholder that responds to a request from the use case.
e.g. bank authorizing a credit card charge
4. External receiver actor - Stakeholder that is not the primary actor but receives
something of value from the use case. e.g. the warehouse receiving a packing
slip

Use Case Association Relationship


Association – a relationship between an actor and a use case in which an interaction
occurs between them.
Association is modelled as a solid line connecting the actor and the use case. If an
arrowhead touches the use case it means that the use case was initiated by the actor.
An association without an arrowhead indicates a receiver actor. The association could
be bidirectional or unidirectional.

57
Figure 5- 5 Relationship between the actor and the use case

5.3 Modelling Requirements with Use Cases


The objective of this exercise is to elicit and analyze enough requirements information
to develop a model that shows what is required from a user perspective. It should be
free of specific details about how the system will be implemented.\

However, to effectively estimate and schedule a project, you may need to include
preliminary “system implementation assumptions.”

Steps in developing the Use Case model.


1. Identify business actors.
2. Identify business use cases.
3. Construct a use case modeled diagram
4. Document business requirements use case narratives

Step 1: Identify Business Actors


 When looking for actors, ask the following questions:
 Who or what provides inputs to the system?
 Who or what receives outputs from the system?
 Are interfaces required to other systems?
 Are there events that are automatically triggered at a predetermined time?
 Who will maintain information in the system?
 A sample list of Actors for a book club
Term Description
Club member An individual who has joined the club
Marketing Department responsible for promotion
of goods and generating sales
Warehouse Place where inventory is kept and
processes customer shipments and
returns
Accounts Organization responsible for processing
receivable customer payments and billing
Time Actor concept triggering temporal
events

58
Step 2: Identify Business Requirements Use Cases

During requirements analysis, try to identify and document only the most critical,
complex, and important use cases, often called essential use cases.

When looking for use cases, ask the following questions:


 What are the main tasks of the actor?
 What information does the actor need from the system?
 What information does the actor provide to the system?
 Does the system need to inform the actor of any changes or events that have
occurred?
 Does the actor need to inform the system of any changes or events that have
occurred?

The primary inputs that trigger business events are all use cases.
Use cases that are temporal events are identified by analysing the key outputs of a
system - i.e. anything generated on the basis of time or date. Since a use case depicts
an action, name of a use case must denote an action.

Note: a context diagram is an excellent source for identifying actors and finding
potential use cases.

Use-case model can drive the entire development effort. Project manager or systems
analyst uses business requirements use cases to plan (estimate and schedule) the build
cycles of the project. Build cycles are scoped on the basis of the importance of the use
case and the time it takes to implement the use case.

Use-case ranking and evaluation matrix is created to determine the importance of use
cases.

Table 5.1 Use-case ranking and evaluation matrix


Use case name Ranking criteria, 1-5 Total Priority Build
score cycle
Submit subscription 5 5 5 4 5 24 high 1
order
Place new order 4 4 5 4 5 22 high 2
Make Product 1 1 1 1 1 5 low 3
inquiry
Establish new 4 4 5 3 5 21 high 1
member subscription
services
Revise order 2 2 3 3 3 13 medium 2

59
5.4 Advanced Use Case Modelling Concepts
Extension use case
A use case consisting of steps extracted from a more complex use case in order to
simplify the original case is called an extension use case.

The relationship between the extension use case and the original use case it is
extending is called an extends relationship.
It is represented as an arrow-headed line beginning at the extension use case and point
to the use case it is extending. The relationship line is labelled “<<extends>>.”

Figure 5- 6 Extension use case

Abstract use case


Abstract use case reduces redundancy among two or more other use cases by
combining the common steps found in those cases. An abstract case is available for
use by any other use case that requires its functionality.

 The relationship between the abstract use case and the use case that uses it, is
called a uses (or includes) relationship.
 It is depicted as an arrow-headed line beginning at the original use case and
pointing to the use case it is using. Each relationship line is labelled
“<<uses>>.”

Abstract Use
Place New Member Case
Order

<<Uses>>
Revise Postal
Address
<<Uses>>
Submit Change Of
Postal Address

Figure 5- 7 Abstraction use case

60
Depends On
A use case relationship that specifies which other use cases must be performed before
the current use case. It can help determine the sequence in which use cases need to be
developed.

It is depicted as an arrow-headed line beginning at one use case and pointing to


a use case it is dependent on. Each „depends on‟ relationship line is labelled
“<<depends on>>.”

Use case dependency diagram

A use case dependency diagram graphically depicts the dependencies among use
cases.
It provides the following benefits:
A graphical depiction of the system‟s events and their states enhances understanding
of system functionality.
Helps identify missing use cases.
Helps facilitate project management by depicting which use cases are more critical.
(a)

(b)

5.5 Illustrating requirements with a Use case diagram


Let us consider the exercise explained above on Kumudu Garage Follow-up system .
In this exercise you have to first identify the actors and business processes as stated in
the requirement document.

61
Actors could be
Receptionist
manager
Stock control system

Business processes could be


Registering the vehicle with the garage
Book in vehicle
Get stock level changes
Update job details
Generate reminders
Generate invoice etc

62
Figure 5- 8 Use case Diagram for Kumudu garage follow up system

5.6 Writing a Use case Narrative


A Use case narrative consists of a pre-defined form which requires to be filled for
each business process in the Use case diagram. To uniquely identify the Use case
narrative a Use case ID is given together with the name.

63
Sample High level use case narrative

Book in vehicle
Author(s):_________________ Date: ______
Version:
Use Case Name: Book in vehicle Use-Case
Use Case ID MSS-BUC002.00 Type
Business
Priority High
Requirements:
Source: Requirement - MSS-R1.00
Primary Business Actor: Receptionist
Other participating Actors: customer (external sender)
Other interested Mechanic - Interested in booking vehicles
stockholders: in order to plan his jobs
Store keeper - Interested in sales activity in
order to replenish inventory.

Management-Interested in Booking rates of


vehicles in order to evaluate company
performance and customer (member)
satisfaction.
Description: This use case describes the event of a
registered customer booking in a vehicle to
service. The customer's demographic
information is validated. Once the necessary
products are verified as being in stock, a job
card is raised to prepare service. For any
product not in stock, a back order is created.
On successful completion of the booking,
the customer will be sent a confirmation

Precondition: The party (individual or company) booking


a vehicle to repair must be a registered
customer.
Trigger: This use case is initiated when the clerk
notify that a vehicle is brought in.

64
Summary
DFD is a technique to illustrate a business process with the flow of data going in-
between the main functions of the system. Zeroth Level DFD illustrates the overview
of a business scenario. DFDs can be further refined to few levels to depict the
necessary levels of details surrounding each function.

Use-case diagrams depict the main business process of the system and external
entities when requirements are analysed as objects in a domain. Use-case narratives
describe in text about business events and how users will interact with the system to
accomplish tasks. For the same requirement document, we examined how to draw a
use case diagram and how to write the use case narrative for a one business process in
the Use case diagram.

Learning Outcomes
 Draw a data flow diagram for a given scenario up to adequate level of detail
 Describe the types of relationships that can appear on a use case diagram
 Construct a use case model diagram
 Prepare a use case narrative
 Analyze requirements to identify the conflicts among them

65
Session 6
Structured Programming

Contents
Introduction, p 66
6.1 The Shift to Software, p 66
6.2 Definitions, p 67
6.3 Control constructs, p 68
6.4 Standardized Module Format and Hierarchical Organization, p 71
6.5 Program control structure, p 72
6.6 Documentation, p 73
6.7 Structured Programming Methodologies, p 76
6.8 Choosing a Development Approach, p 81
Summary, p 82
Learning Outcomes:, p 82

Introduction
By the late 1960s it has become obvious that software systems were complex. They
were difficult to design, to write, and to test and virtually impossible to understand
and to maintain. Advances in software technologies lagged far behind those in
hardware technologies. Installations that brought the latest computers continued to use
ad hoc programming methods from the 1950s and early 1960s.

Programming has evolved from rather ad-hoc, egoistic art to a more controlled,
definable science. Namely in order of historical evolution, following are few theories
that explain how to program:
 Structured programming
 Top- Down programming
 Step-wise refinement

In this session we learn importance of structured programming to overcome the


difficulties faced by programmers as well as users, and how to write programs
adhering to structured programming rules.

6.1 The Shift to Software


Earlier emphasis on improving hardware shifted to software in late 1960s. It became
evident that the task of programming could no longer be viewed as trivial. As the
famous computer scientist Niklaus Wirth explained,

66
“The true challenge does not consist in pushing computers to their limits by saving bits and
micro seconds, but in being capable of organizing large and complex programs, and
assuring that they specify a process that for all admitted inputs produces the desired
results.”

There was a critical need for improved software technology and this need became so
severe that it becomes referred to as the “Software Crisis.” The serious shortcomings
of software technologies were discussed at the 1968 NATO conference on Software
Engineering. With such understanding research for software development
methodologies have been carried on. Structured programming evolved as a solution to
ad hoc programming practices that made maintenance of software a nightmare.

The main objective of structured programming was to solve the software crisis by
providing a programming discipline to accomplish the following:
 Improve program reliability
 Improve program efficiency
 Minimize program complexity
 Simplify program maintenance
 Increase programmer productivity
 Provide a discipline program methodology

6.2 Definitions
Rather than one generally accepted definition, there are several schools of thought on
what structured programming is;
 In the narrowest sense, the concept of structured programming is
concerned with only the program from the coding process. It is a set of
conventions that the programmer can follow to produce structured
code. The coding rule imposed restrictions on the use of control
constructs, data structures, module composition and documentation.

In a broader sense, structured programming addresses programming


methods as well as program form. Structured programming implies
following a structured methodology to carry out program design and
implementation such as:
* Modular programming
* Stepwise refinement
* Level of abstraction
* Top-down and bottom-up programming

In its broadest sense, the concept of structured programming encompasses the entire
programming process. It imposes a discipline on each stage of the creation of software
system and the organization of programmers. Structured programming includes ideas
such as:
 Analytic verification of algorithm correctness to ensure program
reliability

67
 Systemization of the programming process
 Relating the programming task to the program design structure and
the programming team structure
 Application of management techniques to the programming process
 Systematic use of abstraction to control a mass of detail and to
produce meaningful documentation

We can say that Structured programming is a methodology that lends structure and
discipline to the program form, program design, program coding, and program testing.
It is a program methodology for constructing hierarchically ordered, modular program
using standard control constructs.

6.3 Control constructs


The three basic control constructs identified by Bohm and Jacopini in their famous
paper published in 1966, became the basic constructs for building structured programs,
namely:
 Sequence
 Selection
 Iteration

6.3.1 Sequence
When sequence is used to control program execution, statements are executed in the
same order as they appear in the source code Figure 6- 1 illustrates the sequence
construct.

Figure 6- 1 Sequence

6.3.2 Selection
The selection, iteration and branch structures are used to alter program execution flow
from its normal sequential statement order.

68
When the selection structure is used a condition is tested. Then depending on whether
the test is true or false one of two alternative sets of instructions is executed. Figure 6-
2 illustrates the selection structure.

Figure 6- 2 Selection

Iteration
The iteration structure is used to execute a set of instructions repeatedly, that is to
build a loop. There are two basic forms for the iteration structure: DO UNTIL and DO
WHILE. Either form can be used to create a program loop in a structured program.

Figure 6- 3 iteration with Do-until loop

DO-UNTIL: Flow chart for DO UNTIL loop is shown in Figure 6- 3. A block of


instructions is executed. Then a loop termination condition is tested. If the condition is
true, the loop is terminated and execution continues with the next sequential
instruction. If the condition is false, the instruction block is executed again. Note that
the DO-UNTIL loop is always executed at least once.

69
Figure 6- 4 iteration with Do-while loop

DO-WHILE: Flow chart for DO WHILE loop is shown in Figure 6- 4. A termination


condition is tested. If the condition is false, the loop is terminated and execution
continues with the next sequential instruction. If the condition is true, a block of
instructions is executed and the condition is tested again. Note that if the condition is
initially false, the loop will not be executed at all.

Usually the restriction to allow only these three control constructs in a structured
program is relaxed to include extensions such as the nested IF, the case statement and
the escape. Allowing these extensions makes the program easier to code and maintain.

Nested If
The selection structure has the following basic format:
IF condition
Statement -1
ELSE
Statement -2

Here the statement-1 is executed when the condition is true, and statement-2 is
executed when the condition is false. When statement-1 of selection structure contains
another selection structure, it is called a nested IF. At each level of nesting,
indentation is suggested to make the next level more obvious.

In a structured program, at most three levels of nesting are allowed. The purpose of
this restriction is to control reliability. Beyond three levels of nested IFs, it becomes
difficult for most programs to understand the code.

70
Case Statement
In the case statement n–way branch, the selection structure is extended so that a
choice is made from more than two alternative sets of code depending on a condition
test. In some languages it is implemented using the IF-THEN-ELSE structure or a
special case structure. An example of an n-way branch code using the Pascal is given
below.

case operator of
'*' : result:= number1 * number2;
'/' : result:= number1 / number2;
'+' : result:= number1 + number2;
'-' : result:= number1 - number2;
otherwise invalid_operator := 1
end;

6.4 Standardized Module Format and Hierarchical


Organization
A structured program is a modular program. But in addition to the basic
modularization rules, module form is further restricted in the structured program.
Strict format rules for constructing a structured module are another means of
simplifying the program structure. This allows the programmers to concentrate on the
program meaning rather than on the form of the program.
The rules for constructing a structured module are as follows:
 A module has one unique entry point and one unique exit point
 A module is a self–contained structure
 It performs one logical task in the program.
 It is bounded by its entry point and its exit point. The exit point
must follow the entry point in the code, with no other module entry
point or exit point intervening or considering.
 Legal control construct are restricted to sequence, selection (with
accepted extensions), iteration and escape to the module exit point.
71
Modules in a structured program are hierarchically ordered. Although hierarchical
organization is usually considered as an inherent part of modular programming, it is
possible to organize a modular program in a non-hierarchical manner. For example, a
simple modular program containing only a few modules that can be organized
sequentially. One module is executed after another. When the last module in the
sequence has been executed, program execution stops.
Since sequential organisation is not an effective means of controlling program
complexity as a program grows in size, a structured program is not sequentially
ordered. It is always hierarchically ordered in the following manner.
 Level 1 of the hierarchy contains one module. This module, called
the root module, represents the overall program function at its
highest level.
 Level 2 of the hierarchy contains modules that further define the
function of the root module.
 In general, each successive level of modules in the hierarchy
provides a more detail functional description of what the program
codes.

Figure 6- 5 shows the hierarchical arrangement for the modules in a Master-file


Update program. Level 1 contains the root module, UPDATE MASTER FILE. The
function of UPDATE MASTER FILE is defined by three functions, GET VALID
TRANSACTION, FETCH MASTER RECORED, and UPDATE MASTER
RECORED. The definitions of these functions are further explained by the modules at
level 3.

Figure 6- 5 Hierarchical organizations of modules

6.5 Program control structure


An invocation relationship exists between two modules, A and B in a structured
program if module A requires module B in the order to perform its function (). From a
view point of the program control structure, this means that module A (called father
module) invokes module B (which is called son). When module A invokes module B,
program control is passed from module A to module B. The code in module B is then

72
executed. When module B has computed its execution, it passes control back to
module A. Program control always enters a module from its entry point and leaves the
module from its exit point.

Figure 6- 6 Invocation relationship

The rules of program control flow in a structured program are summarized in the box
below. The smallest structured program consists of only a root module. All other
structured program contain one root module and one or more sub-modules.

6.5.1 Rules for program control flow in a structured program


 There is one and only one root module in a structured program.
 Program execution must begin with the root module.
 A module is executed if and only if it is invoked by its father.
 Only a father can invoke a son. A son cannot invoke its father, nor can a module
invoke itself.
 Program control must enter a module at its entry point and must leave at its exit
point.
 Control always return to the invoking module when the invoke module completes
execution

6.5.2 Program paths


Restricting the organization of modules and the invocation relationship between
modules are very powerful techniques for controlling complexity, especially in large
programs. By imposing a simple module-invocation system, the total number of
possible program paths is reduced. By requiring the flow of program control to return
to the invoking module it is easy to trace each program path. By restricting the set of
allowable control constructs, path patterns are reduced. Thus a programmer can use
one standard road map to follow the logic through any structured program, regardless
of its complexity. Because of the hierarchical organization of modules, the
programmer can understand a structured program in degrees, dealing with the next
level of detail only when necessary.

6.6 Documentation
Documentation is an integral part of a well–structured program. It addresses three
levels of program understanding.
 Overview
 Program organization

73
 Program instruction comments
Each successive level provides a more detailed view of the program. All three levels
are necessary to the understanding and maintenance of the program.

6.6.1 Overview Documentation


Overview documentation introduces the program to its readers. The need for this first
level of program documentation has often been overlooked. But it is essential to all
levels of program understanding. If one must choose among the three levels of
program documentation, overview documentation is the most fundamental and
therefore the most essential. Also, it is the easiest to provide and the most stable.
Throughout the life of the program, overview documentation is the least likely to
require changes. Although the program may be modified frequently to meet changing
user requirements, the overall function is likely to remain unchanged.

6.6.2 Overview documentation items


 An overall function summery defining the basic functional components and their
relationship to one another
 An overall database summery showing the role of data in the total system,
including major files, major data structures, and major clusters
 A brief explanation of the underlying design philosophy and the programming
style used; the portion of a logical data model used, with logical access maps
drawn on it
 Pointers to historic documentation, including design notes, problem reports,
version descriptions, new release notices, and error statistics.
 Pointers to more detailed levels of internal program documentation, operating
instructions, and user manuals.

6.6.3 Program Organization Documentation


Program organization documentation serves as the program table of contents, defining
the name, location, and function of the procedural components. Two types of program
organization documentations are suggested for a structured program:
 Graphic documentation represents the program procedural, data,
and control structures
 Program comments introducing each program module and data
structure.

6.6.4 Module comment – block items


 Module purpose (one or two sentences explaining what the module does)
 Effective date (last revision)
 Limitations, restrictions, and algorithmic idiosyncrasies
 Accuracy requirements
 Input/Output
 Assumptions
 Error recovery types and procedures
 Information explaining the impact of changes on the other portions of the program,
especially in the case of common modules.

74
A comment block precedes each program module in a structured program. Its purpose
is to introduce the module to the reader by describing what the module does. How the
module works is not described. This is best ascertained by actually reading the code.

6.6.5 Program Instruction Comments


Instruction-level comments rarely should be used in a structured program. Good
documentation does not imply that a source comment is required for each program
instruction. This sort of documentation is useless. If the instruction is clear as well as
correct, the comment is probably not necessary. But the instruction is not correct; the
comment may read the reader to believe, mistakenly, that the instruction correct and
in this way make and error more difficult to detect.

Instruction-level comments should be used only in exceptional circumstances, such as


explaining an unusual or complex algorithm or highlighting error-prone program
segment and potential ambiguities. Instead, meaningful procedure and variable names,
standardized control constructs, and a consistent coding style should be emphasized to
make a structured program more readable.

6.6.6 Indentation

The rules for writing a conventional language include paragraphing, spacing and
indenting guidelines to improve readability. Similar guidelines for writing structured
programs are used to improve program readability. A basic principle of structured
programming is that the standardized program form will improve readability.

Structured coding rules typically include the following;


 Do not code more than one statement per line.
If statement requires multiple lines, indent all continuation lines.
Indent the true and false portions of the selection structure to identify
its scope more clearly.
Use an indentation scheme that accentuates the control structures used
to direct statement execution order.

Activity 6.1

Briefly describe five benefits of documentation.

75
6.7 Structured Programming Methodologies
Programs can be developed from the top down or from the bottom up. Both of these
are adaptations of Wirth‟s programming by stepwise refinement and Dijkstras‟s
programming by levels of abstraction.

When a system is built bottom up, the designer creates the components first, makes
each component work well, and then fits the components together.

When a designer works top down, he/she first create the overall structure, defining but
not yet building the components. As the design progresses, he/she fills in the details
by building the lower level components.

Top-down and bottom-up designs are practiced in many fields of engineering other
than programming. On complex projects, a combination of top-down and bottom-up
design is usually required.

6.7.1 Top-down programming


Top-down programming is an orderly method of designing, coding, and testing a
program in progressive steps. Top down programming produces a hierarchically
structured, modular program. The top-level modules in the hierarchy represent the
overall function of the program. Lower-level modules represent sub-functions that
define the program tasks in greater detail.

In top-down programming, the order of the design, coding and testing steps is
different from traditional program development. In traditional program development,
first the entire program is designed, then the program is coded, and finally it is tested.
The three steps are performed separately and sequentially. This is called the phased
approach.

In contrast, the three steps in top-down development are performed in parallel (see
Figure 6- 7). This is called the incremental approach or the step-by-step-approach.
First one module is designed, coded, and tested. Then another module is designed,
coded and tested, until all modules in the program are finished. As part of the testing
step, each newly coded module is integrated and tested with all modules completed to
that point. The program grows gradually, one module at a time. Integration is done in
steps instead of in big chunks at the end of the project as is done in the phased
approach.

In practice, the traditional phased approach has not been very successful. It tends to
delay the discovery of serious problems and the need for project resources, such as
personnel and computer time, until late in the project. Furthermore, problems are
likely to spill over into the maintenance phase, making the program a costly
nightmare to maintain.

76
Figure 6- 7 Program development

In phase program development (Figure 6- 8), serious problems and resource needs
often build up enormously as the projects nears its planned completion point.

The top-down approach can avoid many of these problems. It has the advantage of
beginning testing earlier in the development process. In this way integration problems
can be discovered and corrected earlier and at a lower cost.

Figure 6- 8 Relationship between resources need and time in phased approach

77
A second advantage is that the need for resources can be more evenly described
throughout the development process. Finally, a skeleton of the program exists from
the early development steps, giving the user a partial version of the program long
before the entire program is completed.

6.7.2 Top- Down Program Development


Top-down program development follows the logical structure of the program,
beginning with the highest-level module and proceeding to lower-level modules in
well ordered steps. The steps are as follows:

Step 1: Begin with the examination of the problem and then propose a solution, given
as the general structure of the program. Express the solution as an outline that
identifies the general procedural and data components of the program. At this point
the contents of the components are not defined in detail. The outline is obtained by
cutting the problem into logical pieces reflecting the functional tasks the program
must perform to accomplish its objective. (e.g., calculate gross pay, select screen
format).

Step 2-n: Expand the program outline into the complete program in steps. The
expansion process follows the rules of the refinement process. Program components
are refined into subcomponents, and then the subcomponents are refined, and so on.
The process stops when the program is described as a set of components that can be
directly expressed in the programming language.

As shown in Figure 6- 9, top-down development begins with module A after the


general program hierarchical structure has been outlined. Modules B, C and D are
represented as dummy modules called stubs. Usually a stub can be coded as an
“empty” module containing only an entry point and an exit point. When a stub is
invoked, it simply returns control to the invoking module. If necessary, it can return a
constant value if some output is expected. Stubs stand in as place holders until they
are replaced by the actual modules in later refinement steps.

After module A has been designed, coded, and tested, top-down development moves
down to modules in level 2. In steps, the stubs for modules B, C, and D are replaced
by the actual modules. The process continuous in downward direction until program
development is complete.

6.7.3 Bottom- up verses Top-down Programming


Although top-down programming is usually considered a better method for
developing a structured program, bottom-up programming is sometimes a viable
alternative. Both methods share the same objectives:
 To systematize the programming process
 To provide a framework for problem solving
To produce a modular program

78
Figure 6- 9 Top down programming

Both are compatible with the structured programming methodology. However, they
approach program development from the opposite direction. The construction
technique for program development in top-down programming is decomposition.
Program functions are decomposed into sub-functions and so on until the whole
program can be defined in term of components from the programming language. As
shown in Figure 6- 9, the development direction is from an abstract, high-level
solution to the actual programming environment. In bottom-up programming, the
opposite development direction is followed. The program is built by combining
simple, atomic component to form more abstract, higher-level components. The
construction technique is concatenation.

Figure 6- 10 Top-down and bottom-up programming approach program development from opposite directions

79
6.7.4 Bottom-up Programming
Bottom-up programming develops a program in steps. Just as in top-down
programming, the process can be divided in to two parts. First and initial solution for
the program is proposed. Then the detail components of the program are developed.

Step 1: Begin with an outline of the proposed program. This outline includes the
general functional and data components of the program.

Step 2-n: In explicit steps, develop the program by combining low-level components
to form high-level components. This process is called the concatenation process. The
concatenation process stops when a set of program functions and data structures that
are able to solve the programming problem have been constructed from the elements
available in the actual programming environment.

As shown in Figure 6- 11, bottom up program developments begins with module E.


Following module E, module F is designed, coded and tested. Then module E and F
are combined and tested. Since module C does not yet exist, its function must be
simulated by a test driver. A test driver is usually just a skeleton modal of the module
to be built in a later development step. Development proceeds up the program
structure module by module until the entire program has been designed, coded and
tested.

Figure 6- 11 The bottom-up method for developing a program

The development direction moves from the lowest-level modules to the highest- level
module in the steps. Test drivers are used to represent higher-level modules that will
be developed in later steps.

6.7.5 The concatenation process


The concatenation process moves upward instep from low-level programming
language components to a high-level program solution. This is illustrated in Error!
eference source not found.. Note that the concatenation process proceeds in the
direction opposite the refinement process, from low–level components to a solution.

80
Figure 6- 12 The concatenation process

Activity 6.2

Compare and contrast Top-down and Bottom-up programming methodologies with real world
examples (examples of programming solutions/problem domains)

6.8 Choosing a Development Approach


Top-down and bottom-up programming attempts to order the program development
process. The result of either approach is a hierarchically structured, modular program.
How well the process work in practice depends on the skill of the developers, the
computing and personal recourses available, and the nature of the programming
problem. Both methods can offer only a framework for structuring the development
steps. They do not give developer answers to design questions.

For particular problems, one approach may be preferred over another. Top-down is
preferred when decisions concerning data representations must be delayed. On the
other hand, a bottom-up approach allows a large number of programs to work in
parallel on bottom-level modules. However, following a pure top-down or bottom-up
approach can cause problems. For example, when following a top-down approach,
common functions may not be recognized, or the development process may require
too much time, especially for a large program. Following a pure bottom –up approach
may result in undefined data and poorly tested module interfaces.

A combination approach is often more practical than following a strict top-down and
bottom-up approach. For example, it may be desirable to implement utility or
common modules bottom up since they will be invoked in more than one part of the
program. The rest of the program can be developed top down. This is simpler than
creating a stub everywhere in the program where the utility module is invoked.

81
Summary
In this session we discussed how structured programming emerged and the basic
control constructs.
The concepts of structured programming are based on writing programs using:
 Sequence
 Selection
 Repetition or iteration
We also discussed various documentation types used in software development process
and structured programming methodologies.

Learning Outcomes:
After studying this session you should be able to,
 list the objectives of structured programming
explain the 3 basic control constructs
explain the importance of documentation of software projects
apply structured programming methodologies for solving programing
problems

82
Session 7
Function Oriented Design

Contents
Introduction, p 83
7.1 Structured Software Systems Development, p 83
7.2 N-S Chart, p 84
7.3 Data Flow Diagram, p 86
7.4 The System Model, p 92
Learning Outcomes p 94

Introduction
The function oriented model shows how the in-coming data in combination with the
stored, static data can be transformed into the output data that is required by the
system. This transformation is performed by a series of functions.

This session discusses about how and why software design has progressed from early
ad-hoc art into a set of formalized techniques which has become the base for the
function oriented design. Here we also learn to represent a design using three function
oriented design techniques - structure charts, N-S charts and Data Flow Diagrams.

7.1 Structured Software Systems Development


In this section we will consider the work done by Michael Jackson in the development
of the Jackson System Development (JSD) method, which is used for program design.
JSD is concerned with the actual information domain -the information which
constitutes the total subject matter of the system, and the actions that needs to be
performed by the system.
JSD concerns itself with, primarily:
 Extracting the entities comprising the system from the textual
description of the system, and those actions which affect these
entities.
 The entity history is the total impact of actions upon that entity
over time. Actions can either be sequential as part of a selection
criteria or as an iteration.

83
Figure 7- 1 Components of a structure chart

Figure 7- 1 shows the components of a structure chart. Sequence, selection and


iteration of a structure chart is shown in (a), (b) and (c) in Figure 7- 1.

Developing a system to run on a computer as a program consists of translating the


design of the system in to a set of programmable functions or procedures. The coding
step, traditionally, begins with the detailed description of a system design.

7.2 N-S Chart


The flowchart has always been a widely used method to illustrate a problem solution.
However, there are certain domains where flowcharts cannot be used to illustrate a
problem solution very well. A structured flow chart called the N-S chart, improved the
flowcharting technique to handle file maintenance in commercial systems.

When depicting a design using N-S charts, control structures such as sequence,
selection and iteration are illustrated as shown in (a), (b) and (c) of Figure 7- 2.

Figure 7- 2 Control constructs in a N-S Chart

Example: Depicting a merge algorithm using a N-S chart.

84
Firstly, here is a problem definition for a merge problem domain:
Given two files A and B, both sorted in ascending order of key values, it is
required to create an output file C, constituting A merged with B, in ascending
order of key value.

Figure 7- 3 Merge operation

Figure 7- 3 shows the basic merge operation. Figure 7- 4 gives the solution in the
form of a structured flowchart.
In Figure 7- 4, consider A-KEY, B-KEY and C-KEY as the values of the key
fields of files A, B and C. The procedure Read-and-Compare is required to read
the keyfields from A and B, compare then and write the one with the lower key
into C.

Figure 7- 4 N-S Chart

Obviously, the above is insufficient as a full solution domain to Read-and-


compare.

Can you guess why?

85
Because each time either A-record or B-record is written into C, it is upto you now to
fill in the remaining tasks within the procedure Copy-Remainder. That is to copy the
remaining records from the non-empty file into C after which control will be passed to
the last procedure whose function is to close all three files.

Activity 7.1

Read the given scenario below and draw a N-S chart to represent the solution.
“To calculate the loan deduction from the salary of an employee, you need to open the
Employee file. Read each record and if loan field is indicated as „yes‟, then read loan
settlement amount and deduct it from the basic salary. After loan deduction, net pay should
be calculated and printed on a report. After reading all the records the file should be closed.
You may make reasonable assumptions about other fields of the Employee file.”

7.3 Data Flow Diagram


A Data–Flow Diagram (DFD) is a graphical technique for depicting information flow
through a system. DFDs are used to analyze the problem domain with a view to
identify the data flow through the domain and the operations being performed on the
data at different points. The view of overall system or the zeroth level of a DFD is
called the context diagram. Context diagram is shown in Figure 7- 5.

Figure 7- 5 Context diagram of DFD

As data is input to a computer based system, it undergoes a series of transformations.


Input can be in any form. Through an optical scanner, a graphics screen, a control
signal from a transducer, a set of digits from a stored computer based file or a packet
of information transmitted via a network from another computer based system.
Output can similarly be in many forms.

Example of a simple DFD is shown in Figure 7- 6. External entities are customer and
company. Customer gives voice and numeric data to the Telephone call system.
Therefore it becomes a source. Company receives necessary messages from the
system. Therefore it becomes a sink to the system.

86
Figure 7- 6 Example of a simple DFD

7.3.1 Components of a DFD


Figure 7- 7 shows the components of a DFD and their formal representation. They are
entity process, data flow and data store. Such representations have been commonly
used by Demarco („Structured Analysis and System Specification‟, 1979) and
Yourdon (Structured Design‟, 1978) and, as can be seen by dates of publication, are
quite well tried. It is a primary modeling tool for structured analysis. DFDs can be
decomposed to lower levels and the requirements of the bottom–level processes are
defined by process specifications.

Figure 7- 7 Components of DFD

7.3.2. Levels of DFD


Context diagram can be divided in smaller processes as levels. Level next to the
context diagram is level 1. Each level 1 process can be divided into other simple
processes. They become level 2. Normally, a process can be divided into maximum of
7 smaller processes in a level. Dividing context diagram into smaller processes and
level 0 to 1 and 2 is shown in Figure 7- 8.

87
Figure 7- 8 Process breaking down into levels

DFD for ordering process of books is shown in Figure 7- 9. It has three (3) processors
called 1. Order processing, 2. Ship books, 3. Collect payments. There are two external
entities called customer and warehouse. There are three data stores called orders,
invoice and customers. There are several flowing data to processes and from
processes. Data flow identifiers are written among the data flow arrows.

Figure 7- 9 A DFD for books ordering system

88
Typically, each of the data flow identifiers such as „customer details‟ would be clearly
annotated as follows:
Customer Details = Customer- name,
Customer- address,
telephone-number.
And
Invoice Details = invoice- no,
Customer- name,
Customer- address,
(book- code, book –name, amount)*,
total –amount
Where * implies iteration over the number of books being purchased i.e. Detail
invoice lines.

Closer to home, we can look at the Open University‟s procedures in respect of student
examinations. Figure 7- 10 shows a section of the procedures involved.

Figure 7- 10 Level 1 of DFD for student examination of Open University

89
The flow of information through a system, as represented by a DFD is fairly easy to
follow. It is also easy for the analyst to structure his analysis of the information
domain through DFD‟s. However, our problem with DFD‟s is that there is no explicit
indication of the temporal order of events. Which precedes which and happens
before what?

If you look at Figure 7- 10 again you will notice that the student receives the
time-table and the venue as well as the notification of results of exam
processing. But of course, the time table will precede the results which can
only happen after the answer scripts have been received back. A better way to
represent this would have been as depicted in Figure 7- 11.

Figure 7- 11 Examination process illustrated in a different way

Another example is illustrated in the process „Determine Total Sales commission” in


Figure 7- 12. It is a level 1 DFD. This level 1 DFD is divided into 3 processes. They
are numbered as 1.1, 1.2 and 1.3. So, they are in level 2. It is depicted in Figure 7- 13.

90
Figure 7- 12 A part of Level 1 DFD for determining sales commission

Figure 7- 13 Corresponding part of the Level 2 DFD for determining sales commission

91
Now when we consider the module 1.2, it is named as “Calculate commission”. This
module can be written by a simple algorithm as follows because it is very simple
manageable module. Actually, context diagram breaks down until they become simple
manageable modules.
Process 1.2
CALCULATE commission
Begin
Do while there are more Commissionable–sales amounts
Find salesman–Commissionable-Level from Salesman – File using
Salesman–Code
If Commissionable–Sales–Amount >= Salesman
–Commissionable-Level
Apply Percentage–figure to Commissionable–Sales–Amount
Add to Commission–Amount
End If
End Do
End

7.4 The System Model


“A system model is a miniature representation of a complex reality” (Demarco –
“Controlling Software Projects”, 1982 – Yourdon Publications).

Its essential feature is that it provides a methodology for studying complex systems, in
part or in whole, particularly what we think are the essential attributes of the system.
Such attributes defined as being essential are:

1. System behaviour – i.e. Given a set of inputs how a set of outputs are
generated via the internalized functions - This behaviour is highlighted by a
specification which states what the user wants or expects from the system.
2. System internal functions – those processes which are essential in the system
in order to provide the behavioural transformations required. This is embodied
in the design.
3. The project organization – the criteria and constraints involved in the system‟s
life cycle which is embodied in the project plan.

This logical model, a resultant of the analysis and design phase, must now be
converted into a physical solution that will be implemented on a particular
configuration and tools required. This is of course, a function of availability,
capability and finance.
 Is such configuration available?
 Is the project team capable of implementing the solution or that
configuration using the tools available?
 Do we have the budget for the proposed project?
Along with providing these questions to which we formulate the answer dependent on
our estimate of resources.

92
Clearly modularity (breaking up a big problem into little, manageable pieces) and
structures (proposing a hierarchy of modules) are guidelines to the modeling process.
Generally modeling is a top–down process. We arrive at our final model by logically
partitioning the problem domain (i.e. information domain) and then partitioning it still
further and further till all the resultant pieces are manageable. Figure 7- 14 shows
level 1 partitioning and Figure 7- 15 shows level 2 partitioning.

Figure 7- 14 Level 1 partitioning

Figure 7- 15 Level 2 partitioning

93
Activity 7.2

Read the given scenario below and draw 0th and 1st level of DFDs to represent the solution.
“Problem area – Library Information System (LIS)

Modules needed – file maintenance (to add a new record, delete and update an existing record),
search for books, borrow, return, pay over-dues, and generate reports.
To browse, user is asked which master file to use. Master files are ‘books’ and ‘members’. There
are number of different reports needed.”

Learning Outcomes
On completion of this session the learners will be able to;
 construct a structured chart to depict a for a simple problem
solution
 draw a N-S chart illustrate a given problem solution
 draw a data flow diagram (DFD) for a given scenario up to
adequate level of detail to illustrate a problem solution

Reference
For structure charts: http://www.smartdraw.com/resources/tutorials/Introduction-to-
DFD#/resources/tutorials/Introduction-to-JSD
For N-S charts: http://www.smartdraw.com/resources/tutorials/Introduction-to-
DFD#/resources/tutorials/Introduction-to-Nassi-Shneiderman
For Data Flow Diagrams:
http://www.smartdraw.com/resources/tutorials/Introduction-to-
DFD#/resources/tutorials/Introduction-to-DFD

94
UNIT 2
INTRODUCTION TO PROGRAMMING

Introduction 95

Session 8 Algorithms 96

Session 9 Programming with C Language 105

Session 10 Data Types and Variables in C 112

Session 11 C Operators and Expressions 121

Session 12 Control Structures in C 131

Session 13 Basic Input Output 141

Session 14 Functions in C 146

Session 15 Data Structures 159

Session 16 Dynamic Data Structures 168

95
Introduction
At the end of Unit 1, we discussed basic software engineering concepts. A program
created according to structured concepts where the flow of processes is emphasised, is
called procedure-oriented or function-oriented. Here a problem is broken down into
parts and each part is then broken down into further parts. All these parts are known
as modules. They are separate but work together when needed and a main program
centrally controls all modules. C language is widely used to create function oriented
programs.

In this Unit, we discuss how to arrive at a solution for a problem using an algorithm
and then how to code the algorithm in C language while following structured
programming concepts.

Learning Outcomes:

After studying this unit, you should be able to


 design an algorithm for a simple problem
 develop a C-program to implement the designed algorithm

96
Session 8
Algorithms

Contents
Introduction, p 97
8.1 What is an Algorithm?, p 97
8.2 Representation of Algorithms, p 100
8.3 Non-uniqueness of Algorithms p 103
Summary, p 104
Learning Outcomes:104

Introduction
In this session we will discuss how to solve a problem with an algorithm. Here you
will learn the characteristics of an algorithm, differences in representing algorithms in
normal English and structured English, and two formal methods of representing
algorithms. As the two formal methods we will discuss the use of pseudo code and
flowcharts.

Learning to write an algorithm to solve a problem is very important when you learn
programming. You will be also given a task in the Assignment #1 with algorithms and
supporting animations are given in the on-line class.

8.1 What is an Algorithm?


We can say in simple terms that „An algorithm is a set of step by step instructions for
solving a problem to achieve a result‟. Algorithms are especially important to
computers because computers are general purpose machines for solving problems. In
order for a computer to be useful, we must give it a problem to solve and a technique
for solving the problem. Writing a computer program is actually describing the
solution in a computer language. Once you have got the proper solution it is easy to
convert it to a programming language, but formulating the proper solution is the
difficult part.

For example, can you describe someone else how to make a cup of tea? You need to
give step by step instructions how to do that.

Here is one possible method.

97
o First you boil water. Then put 1 teaspoon of tea leaves to the teapot
and pour boiling water into the teapot. Let it stand for 3 minutes. Put
2 teaspoons of milk powder and 1 teaspoon of sugar to a cup.
o Pour some tea and stir the content in the cup with a spoon. See
whether the cup is full, and if not, pour tea until the cup is full.
o Taste and see whether sugar is enough. If sugar is not enough add
another ½ teaspoon of sugar.

Another example for an algorithm is a recipe to make a cake or the set of instructions
that says how to tune a new TV set for the available channels.
When writing algorithms, we have several choices to specify the operations in our
algorithm. Most simple option you may see is to write the algorithm using plain
English as the above example of making a cup of tea. Although plain English may
seem like a good way to write an algorithm, it has many problems. First, plain English
is too wordy. When we write in plain English, we must include many words that
contribute to correct grammar or style but do nothing to help communicate the
algorithm. Second, plain English is too ambiguous. Often an English sentence can be
interpreted in many different ways.

To make the instructions clear and unambiguous we can write the same sequence of
steps in Structured English like what is given below.
o Boil water
o Put 1 teaspoon of tea leaves to the tea pot
o Pour boiling water into the teapot
o Let it stand for 3 minutes
o Put 2 teaspoons of milk powder to a cup
o Add 1 teaspoon of sugar to the cup
o Pour some tea into the cup
o Stir the content in the cup with a spoon until content is dissolved
o See whether the cup is full, and if not pour tea until the cup is full
o Taste and see whether sugar is enough
o If sugar is not enough add another ½ teaspoon of sugar

Activity 8.1

Write an algorithm to calculate the area of a rectangle in structured English.

Note: area of an rectangle = width of the rectangle * height of the rectangle

There is no generally accepted single formal definition for an algorithm. Here is one
definition.

98
An algorithm is a well-ordered collection of unambiguous and effectively computable
operations that when executed produces a result and halts in a finite amount of time.
(Schneider and Gersting 1995)

Though the algorithm given to illustrate „how to make a cup of tea‟ seems alright for
us, undoubtedly it is too ambiguous for a computer. In order for an algorithm to be
applicable to a computer, it must have certain characteristics. According to the formal
definition given above, there are five important characteristics of an algorithm as
stated below.

 An algorithm is well-ordered.
 An algorithm has unambiguous operations.
 An algorithm has effectively computable operations.
 An algorithm produces a result.
 An algorithm halts in a finite amount of time.

8.1.1 An algorithm is well-ordered


Since an algorithm is a collection of operations or instructions, we must know the
correct order in which to execute these instructions. If the order is not clear, we may
perform the wrong instruction, or we may be uncertain which instruction should be
performed next. This characteristic is very important when working with computers as
a computer can execute an algorithm only if it knows the exact order of steps to
perform.

8.1.2 An algorithm has unambiguous operations (Definiteness)


Each operation in an algorithm must be sufficiently clear so that it does not need to be
simplified. If the instruction is clear it allows only one interpretation.

Given a list of numbers, you can easily order them from largest to smallest with the
simple instruction "Sort these numbers." A computer, however, needs more detail to
carry out such a task. It must be told how to search for the smallest number, how to
compare two numbers together, etc. The operation "Sort these numbers" is ambiguous
to a computer because the computer has no basic operations for sorting. Basic
operations used for writing algorithms are known as primitive operations (primitives).
When an algorithm is written in computer primitives, the algorithm is unambiguous
and the computer can execute it.

8.1.3 Algorithms have effectively computable operations


Each operation in an algorithm must be doable, that is, the operation must be
something that is possible to do. For example assume that you were given an
algorithm for planting a garden where the first step instruct you to remove all large
stones from the soil. This instruction may not be possible carry out if the particular

99
plot of land is sand without stones. For computers, many mathematical operations
such as division by zero or finding the square root of a negative number are also
impossible. Operations which are not effectively computable cannot be used in
writing algorithms.

8.1.4 An algorithm produces a result


Unless an algorithm produces some result, we can never be certain whether the given
solution is correct. Have you ever given a command to a computer and discovered that
nothing changed? Without some visible change, we have no way of determining the
effect of our command. The same is true with algorithms. Only algorithms which
produce results can be verified as either right or wrong.

8.1.5 Algorithms halt in a finite amount of time (Finiteness)


Algorithms should be composed of a finite number of operations and they should
complete their execution in a finite amount of time. Suppose we wanted to write an
algorithm to print all the integers greater than 1. Our steps might look something like
this:
Print the number 2.
Print the number 3.
Print the number 4.
……

While our algorithm seems to be very clear, there are two problems. First, the
algorithm must have an infinite number of steps because there are an infinite number
of integers greater than one. Second, the algorithm will run forever trying to count to
infinity. These problems violate our definition that an algorithm must halt in a finite
amount of time. Every algorithm must reach some operation that tells it to stop.

8.2 Representation of Algorithms


An algorithm can be formally represented either graphically as a flowchart or with a
textual method like pseudo code. Pseudo code is more concise and clear than
structured English. Representing your problem solution with a flow chart or pseudo
code, allows you to concentrate on the logic of the solution without worrying about
the programming language syntax.

8.2.1 Flow Charts


We can use a flow chart to describe an algorithm by showing how problem solution
proceeds step by step. Here we use standard symbols that depicts a process, a decision,
input/output etc.
There is a start symbol to indicate the beginning of the process and an end symbol to
indicate the end. It is assumed that the sequence of steps in the process go from top to
bottom. Major symbols (Process (a), Sub process (b), terminator (c) decision (d) and
input/output (e)) for flow chart drawing are shown in Figure 8- 1.

100
Figure 8- 1 Flow charting symbols

Figure 8- 2 shows how the solution to the problem of making a cup of tea is
represented with a flowchart.

Activity 8.2

Draw a flow chart to illustrate an algorithm to calculate the area of a rectangle.

Note: area of an rectangle = width of the rectangle * height of the rectangle

101
Figure 8- 2 Flow chart for making a cup of tea

After writing the algorithm in pseudo code, translation to any programming language
is straightforward.

Example.
write an algorithm for adding all even numbers between 2 and 1000 to the Sum-
Even-numbers

In structured English

 Initialize Sum-of-Even-numbers
 Intialize an index
 Repeat Until index is 1000
 Increment the index by 2;
 Add index to Sum-of-Even-numbers

102
In Pseudo code
Sum-of-Even-numbers = 0
Number = 0
Repeat
Number = Number +2
Sum-of-Even-numbers = Sum-of-Even-numbers + Number
Until Number == 10

Activity 8.3

Write an algorithm to calculate the area of a rectangle in pseudo code.

Note: area of an rectangle = width of the rectangle * height of the rectangle

8.3 Non-uniqueness of Algorithms


For any given problem, it is quite possible that there is more than one algorithm that
represents a correct solution. It means that algorithms are not usually unique. A good
example of this is the problem of sorting. There are so many different algorithms
written to solve this problem. e.g. bubble sort, insertion sort, selection sort, quick sort,
merge sort etc.

Activity 8.4

Find out an algorithm to sort the following numbers in ascending order.


8, 7, 9, 5, 2, 1, 6
Represent your algorithm in
i. Structured English,
ii. Psuedo code,
iii. Flow-chart

103
Summary
In this session we started by defining what an algorithm is. In our definition, we saw
five important characteristics that an algorithm must have:
 An algorithm is well-ordered.
An algorithm has unambiguous operations.
Algorithms have effectively computable operations.
An algorithm produces a result.
An algorithm halts in a finite amount of time.

We discussed four different ways to represent algorithms: plain English, structured


English, pseudo code and flow charts. We found that plain English was too wordy and
ambiguous for specifying algorithms. Other three methods are better suited for the
purpose.
However, the usefulness of computers as problem solving machines is limited because
there are some problems whose solution cannot be given in an algorithm.

Learning Outcomes:
After studying this session you should be able to,
 explain what an algorithm is
 describe characteristics of an algorithm
 represent a simple algorithm with pseudo code
 represent a simple algorithm with a flowchart

104
Session 9
Programming with C Language

Contents
Introduction, p 105
9.1 Compiling and Executing a C Program, p 105
9.2 Compile Errors, p 108
9.3 Case Sensitivity in C, p 109
9.4 Structured coding standards, p 110
Summary, p 110
Learning Outcomes:, p 111

Introduction
From this session onwards, we will start programing with C language. This session
introduces step by step procedures needed to follow in order to develop a simple C
program. It also shows the common programming errors, how to locate them and
correct them to run a program successfully.

9.1 Compiling and Executing a C Program


C is considered as a high-level programming language. Statements in C are English-
like and closer to human language, which is easy to read and write. Since the
computer can understand only the machine language, a program that is written using
C needs to be translated into the machine language before executing. The first step of
this translation is performed by a compiler.

A programmer can write the program in C using any editor and save the file. The
program that is written is called the source code, hence for the compiler, the input is
the source code and the output is object code. In fact the object code cannot be run in
the computer as it is. Therefore, we need another program called a linker, which is
invoked by the compiler, in order to translate the object file into an executable
program. Only an executable program can be run in the computer.

Here, the compiled object file is also linked with a function library in order to produce
the executable program. A library is a collection of linkable files, which can be linked
to a program. Many libraries are supplied with the C compiler but a progammer can
also create his/her own set of libraries to be linked with the program.

105
For example, a source file saved as hello.c, when compiled generates both the object
file (hello.obj) and the executable file (hello.exe). When the programmer run the
program the executable file is loaded and executed.

1 /* My first program in C */
2 #include <stdio.h>
3 /* function main begins program execution */
4 int main( void )
5 {
6 printf( "Welcome to C!\n" );
7 return 0; /* indicate that program ended successfully */
8 } /* end function main */

Output: Welcome to C!

Note: Most of the programs in this book contain line numbers on the left. These
numbers are only for reference within the book and should not be included in your
program.

9.1.1 Program explanation


Though this is a simple program, it illustrates several important features of the C
language.
/* My first program in C */
Lines 1 begin with /* and end with */ indicating that this line is a comment. You
insert comments to document programs and improve program readability. Comments
do not cause the computer to perform any action when the program is run. Comments
are actually ignored by the C compiler and do not cause any machine-language object
code to be generated.

#include < stdio.h> - (line 2)


Lines beginning with # are processed by the pre-processor before the program is
compiled. #include <stdio.h> tells the C compiler's pre-processor to include the stdio
standard header file in the program. The „.h‟ extension stands for the word 'header‟.
This stdio header file includes the declarations of the basic standard input-output
library in C. Header files will be discussed later in detail.

int main (void) - (line 3)


Any C program contains one or more functions, one of which must be main.
Independent of its location within the source code, „main‟ function will always be the
first one to be executed in any C program.

106
Functions can return information. The keyword int to the left of main indicates that
main “returns” an integer (whole number) value. (What it means for a function to
“return a value” will be discussed in a later session). Functions also can receive
information when they are called upon to execute. The void in parentheses here means
that main does not receive any information.

Curly braces ({}) shows the body of the main function. What is contained within these
braces is what the function does when it is executed. (Here line 6 and 7 is the body of
the main function which is contained within the braces in line 5 and 8)

printf( "Welcome to C!\n" ); -( Line 6)


This line is a C statement. It instructs the computer to perform an action, namely to
print on the screen the string of characters marked by the quotation marks. “printf” is
declared in the „stdio‟ standard file which we have included at the beginning of the
program.

This statement generates the visible effect that we can see as the output, „Welcome to
C!‟
The backslash (\) is called an escape character. It indicates that “printf” is supposed to
do something out of the ordinary. When a backslash in a string is seen, the compiler
looks ahead at the next character and combines it with the backslash to form an escape
sequence. The escape sequence \n means new line. When a new line appears in the
string output by a “printf”, the new line causes the cursor to position to the beginning
of the next line on the screen.

Some common escape sequences are listed in Table 9- 1.

Table 9- 1 Escape characters in C

\n New line Position the cursor at the beginning of the next


line.
\t Horizontal tab Move the cursor to the next tab stop.
\a Alert Sound the system bell
\\ Backslash Insert a backslash character in a string
\" Double quote Insert a double-quote character in a string

return 0;
The keyword return is one of several means that we use to exit a function. When the
return statement is used at the end of main as shown here, the value 0 indicates that
the program has terminated successfully.

107
Semicolon character (;)
In line 6 and 7 the statements end with a semicolon character (;). This character is
used to mark the end of the statement and it is essential to include this at the end of all
expression statements in C programs.

9.2 Compile Errors


Compile errors occur during the compilation process of a program. Compile-time
errors can occur either due to errors from the compiler itself or more likely syntax
errors in the code.
Nowadays, new compilers highlight the errors in a programme, and also point out the
exact place in the code where the mistake is. The program given below demonstrates
compile errors.

1 /* My first program in C */
2 #include <stdio.h>
3 /* function main begins program execution */
4 int main( void )
5 {
6 printf( "Welcome to C!\n" );
7 return 0; /* indicate that program ended successfully */

In the above program the closing parenthesis ( }) of the main function is missing.
Hence the compiler will generate a compile error like:
Error welcome.c, line 7: Compound statement missing }

welcome.c is the file name and it shows the line number and also the problem.

Compiler assists in finding most of the common compile errors but sometimes the
compiler finds it unable to report complex user errors. In addition, in every identified
compile error it doesn‟t show the correct line numbers. So it is the programmer‟s
responsibility to locate the errors and correct them.

Activity 9.1

1.Write a program as follows and observe the output.

1 /* My second program in C */
2 #include <stdio.h>
3 /* function main begins program execution */
4 int main( void )

108
5 {
6 printf( "Welcome" );
7 printf( " toC!\n" );
8 return 0; /* indicate that program ended successfully */

9.3 Case Sensitivity in C


C is a case sensitive language. Hence, uppercase and lowercase letters are considered
to be different. All keywords in C are in lowercase.

Example 9.1: In declaring variable names the word „age‟ is different from „Age‟,
and both are different from „AGE‟. (The concept „Variables‟ will be discussed
again in the next session)

Therefore, the programmer should be cautious about this factor and use correct
uppercase and lowercase letters when writing C programs.

Activity 9.2

Correcting errors in a program


This activity is intended to locate the compile errors that the C editor produce, and find the location
and the nature of the error and correct them in order to provide an executable program. First, type
the program given below directly into your editor, exactly as shown and then compile the program.

/* My third program in C */
#include <stdio.h>
/* function main begins program execution */
int main( void )
{
printf( "Learning Programming with C-");
printf( " Session 9 ----);
printf( " My third Program!!!")
return 0; /* indicate that program ended successfully */
}

You will get number of compile error statements. Read the compilation errors carefully and fix the
errors and run the program.

109
9.4 Structured coding standards
Structured programs are expected to conform to a set of structured programming
standards. A general list of structuring rules representative of those typically
suggested for high-level, procedure-oriented languages such as C and Pasacal are
given below.
 Any program is divided into independent parts called modules. A
module is a self-contained unit whose code is physically and
logically separate from the code of any other module in the
program.
 A module represents one unique logical program function. The size
of a module should not exceed 100 instructions.
 A module is bounded by one entry point and exit point. During
execution, program control can enter a module only at its entry
point and can leave the module only from its exit point.
 Modules are related to one another by a hierarchical control
structure. Each level in the control structure represents a more
detailed functional description of what the program does. It also
dictates the transfer of program control from module to module
during execution.
 Each module should begin with a comment block explaining the
function that the module performs, the values passed to the module,
the values returned, the modules that call this module, and the
modules that this module calls.
 All comment should be meaningful (i.e., should not repeat
information that is obvious from the code).
 All variable and module names should be meaningful. Module
name should suggest the logical function they perform (e.g.,
Calculate_Average), and variable names should suggest their
purpose in the program (e.g., CalAv_mark1).
 Names of local variable (i.e., used only in the module) should
begin with the same prefix.
 No more than one instruction is coded on a line. If an instruction
requires more than one line, successive lines are indented.
 IF statement should not be nested more than three levels.

Summary
 A programming language translates instructions from human
readable format to a computer readable format.
 A computer program is a collection of instructions that describe a
task or set of tasks to be carried out by a computer. Every program
has 3 basic tasks.
o Manipulate data
o Perform operations
o Provide results
 To create an executable C program you should,
o Create a source file, with a .c extension.

110
o Compile the source file. (The compiler creates a file with an .obj
extension)

o Run the program. (Linker link the .obj file with any needed
libraries to produce an executable program)

 Compile errors occur during the complication process in a program.


The programmer should locate them and correct them in order to
successfully run the program.
 C is case sensitive.
 Programmers should always conform to structured programming
standards when coding with C language.

Learning Outcomes:
After studying this session you should be able to,
 to edit, compile, link, and run a given C program.
 find out the compile errors in a simple C program and correct them

111
Session 10
Data Types and Variables in C

Contents
Introduction, p 112
10.1 What are Data?, p 112
10.2 Variable Types in C, p 113
10.3 Constants in C, p 117
10.4 Finding the Size of Variable Types, p 119
Summary, p 120
Learning Outcomes:, p 120

Introduction
In the previous session we developed a simple C program which displayed a certain
text. In this session we introduce the concepts of „variables‟ and „data types‟ available
in C. Variables are used to store data and retrieve them later in order to perform
operations. This session also covers basic data types in C and their technical details
such as their sizes and ranges. In addition, this session explains Constants.

Both variables and constants offer various ways to represent and manipulate data in C
applications. When applications are developed it is important to choose the proper
data type in defining variables and constants. Values should be assigned to the
variables and constants according to their data types. Failing to do so will result in
compile errors, unexpected and incorrect outputs. Hence this session provides
guidance to take the right decision to choose the proper data types and to assign
correct values to them. The sizeof operator introduced in this session assist in finding
the size of these data types and even the size of any data item.

10.1 What are Data?


Data are simply values or sets of values. A data item refers to a single unit with a
value. The data items that can be divided into sub-items are called group items. Those
items that cannot be divided in to sub-items are called elementary items.

10.1.1 Computer store


Computer memory is a bank of fixed sized cells (storage locations) each capable of
handling a pattern of binary digits (bits), typically 8 bit per cell.

112
Each distinct piece of information (e.g. A number or a character) inside a computer
has to be coded into a pattern of bits of the given cell size, or if more bits are required
than that can fit into a single cell, some suitable multiple of size required.
8 bits

cell 0
cell 1
cell 2
.
. .
. .
. .

Current personal computers have memory sizes in Giga bits .

10.1.2 Preliminary Types of Data


Different types of data that usually need to be stored are;
integer numbers,
floating point (real) numbers
characters
logical (Boolean) items
machine instructions

10.2 Variable Types in C


In defining variables to store data first we have to define which type of data we want
to store. The data type will have characteristics such as the range of values that can be
stored and the operations that can be performed on variables of that type.

In defining variables, each variable takes up a fixed amount of space in the


computer‟s memory. The Table 10- 1 illustrates the data types used in C and their size
and range.
Table 10- 1 Basic data types in C

Type Description
Char Typically a single octet (one byte). This is integer type.
int integer
float A single-precision floating point value
double A double-precision floating point value
void denotes the absence of a type.

113
In defining variables, each variable takes up a fixed amount of space in the
computer‟s memory. The Table 10- 2 illustrates the data types used in C and their size
and range.
Table 10- 2 Data types in C with their size and usage

Name Description Size* Range*


Character or small signed: -128 to 127
char 1 byte
integer unsigned: 0 to 255
signed short int /
Short integer 2 bytes -32768 to 32767
short int
Unsigned short
unsigned short int 2 bytes 0 to 65535
integer
-2147483648 to
signed int Integer 4 bytes
2147483647
unsigned int Unsigned integer 4 bytes 0 to 4294967295
-2147483648 to
long int Long integer 4 bytes
2147483647
Unsigned long
unsigned long int 4 bytes 0 to 4294967295
integer
Floating point 1.2E-38 to
float 4 bytes
number 3.4E+38 (7 digits)
Double precision 2.3E-308 to
double floating 8 bytes 1.7E+308 (15
point number digits)
Long double 3.4E-4932 to
long double precision floating 8 bytes 1.1E+4932(19
point number. digits)

*Note: The values of the columns „Size‟ and „Range‟ depend on the architecture of
the system where the program is compiled and executed.

10.2.1 Declaration of variables


In order to create a variable in C, you must declare its type followed by the name of
the variable. The variable type can be specified according to the type of data that are
going to be used in the program. Variable names can be declared using any
combination of letters, without any spaces between the letters. In general, meaningful
and expressive names are being used in defining variable names in order to easily
understand the flow of the program. Once the variables are declared they can be used
within the rest of the program.

Example 10.1: Suppose Mathematics marks of a student needs to be stored. In


general, marks are positive values without decimal points. Hence the variable can
be declared as below.
int marks;
Example 10.2: Suppose average mark of a student needs to be stored. As it can
have a decimal value it can be declared as:
float average;

114
Example 10.3: Character variables can be used to store characters as shown
below.
char name;

Example 10.4: In order to declare more than one variable of the same type, it can
be declared as separate statements or in a single statement as shown below. In the
three variables mark1, mark2 and mark3, marks of three subjects can be stored.
int mark1;
int mark2;
int mark3;
int mark1, mark2, mark3;

Example 10.5: Variables without the word "unsigned" are assumed to be signed.
Hence both declarations given below are the same.
signed int mySalary;
int mySalary;

Example 10.6: An exception to this general rule is the char type, as we can
declare variables to store even numeric values. Here it is necessary to use either
signed or unsigned keyword in declaring char-sized variable.
unsigned char total;
signed char value;

Example 10.7: In declaring short and long variables, we assume that short is
equivalent to short int and long is equivalent to long int.
short month; is as same as short int month;

10.2.2 Assigning values to variables


Depending on the data type of the variable, a value can be assigned to it using the
assignment (=) operator. Variables can be defined and initialized separately or both
steps can be done in one sentence.
int age;
age=25;
or
int age=25;

Assigning values to integer variables


 signed int salary = 25750; signed int temperature = -10; unsigned int start = 0;
 As integers comes in short and long values:
 short int lastValue = 175; long int Total = 25000;
 unsigned long bigValue = 22411; signed short smallValue= -5;

115
Assigning values to float variables
 float interestRate = 0.05;
 float calculation= -99.99 double Fahrenheit = 99.876;
 long double Balance = 50899.90;

Assigning values to char variables


 When assigning a character to a char variable, it is enclosed within single
quotes.
 char letter = 'k'; char user_input = '7';
 As numeric values also can be assigned to variables of character type:
 char value = 89;
 We can declare signed and unsigned characters as well.
 signed char firstValue = 110; signed char myKey = -25;
 unsigned char start = 500;
 Note: Plain „char‟, is neither signed nor unsigned:

Assigning values to Boolean variables


 bool correct_name = false; bool password = true;

In C language, values of a declared variable type cannot be changed. Therefore it is


called a strongly „typed‟ language.

A Program using variables


/* My program using variables */
#include <stdio.h>
void main()
{
int workDays=5;
float workHours=8.5;
float payRate=1200.50;
float weeklyPay=workDays*workHours*payRate;
printf(“Weekly pay = Rs. %f",weeklyPay);
Return 0;
}

Activity 10.1

Are these expressions correct if number is defined as int number; ?


number = 5.5;
number = „a‟;
number = 5987;

116
Activity 10.2

Working with variables


Using a suitable variable declaration, write a program which calculates the area of a triangle and
displays the following output.

Use the data and the formula given below in writing your program:
Height of the triangle is 11 and the base of the triangle is 5.
Area = 0.5 * height * base

10.3 Constants in C
Like variables, constants are data storage locations, but once a value is being
initialized to a constant it cannot be changed later in the programme. There are two
types of constants in C named literal and symbolic.

10.3.1 Literal constants


A literal constant is a value typed directly into the program.

Example 10.8: int maximum_temperature = 100;


Here, maximum_temperature is assigned to value 100 and it is a constant fixed
value. In the variable maximum_temperature the value will be always 100. Hence
it is a literal constant.

10.3.2 Symbolic constants


A symbolic constant is a constant that is represented by a name, just like variables are
represented, but once a symbolic constant is assigned it cannot be changed. After
assigning a value to a constant in a programme, it cannot be reassigned. If you try to
do so the compiler gives an error message.

There are two ways to declare a symbolic constant in C using the #define keyword
and the const keyword.

#define keyword

Example 10.9: #define maximum 99;


Note that the variable „maximum‟ doesn‟t have a specific type (int, float or char
etc)

117
const keyword
In defining a constant with the use of const keyword, a type needs to be
specified.

Example 10.10: const int minimum_age = 18;


This is a better way to define constants, as it makes it easier to maintain the code
as well as it prevents errors that can happen.

Constants in programs

/* My program with constants */


#include <stdio.h>
void main()
{
const int FUTURE = 2050;
int year_of_birth, age_in_2050;
Printf("Enter your year of birth:");
Scanf( %d, & year_of_birth);
age_in_2050 = FUTURE - year_of_birth;
Printf(“\n In 2050 you will be %d”,age_in_2050, “ years old.";);
Return 0
}

Output:
Enter your year of birth: 2010
In 2050 you will be 40 years old.

The main advantage in using symbolic constants is, if a certain value needs to be
changed, it can be done efficiently and effectively as there‟s no need to make a
change in every place that the value is being used.

Example 10.11: Suppose in the above program that you need to calculate your
age in 2070.Here if you change the constant to const int FUTURE = 2070, it will
be effective though out the whole program.

This is more effective in larger programs where the programmers do not have to go
through all the coding thus saving time and minimizing errors that can occur.

118
10.4 Finding the Size of Variable Types
Every data type has a size (in bytes) depending on the architecture of the computer. C
language provides a useful operator called sizeof for calculating the size of any data
item or type. It takes a single operand which may be a type name or an expression and
returns the size of the data type in bytes.

A demonstration of the „sizeof‟ operator


#include <stdio.h>
#include <limits.h>

int main()
{
printf("Storage size for int : %d \n", sizeof(int));
return 0;
}

Output:
Storage size for int = 4

Activity 10.3

i. If „Pi‟ is defined as Const double Pi = 3.14 in the start of the program, can you assign „3.142‟ to
„Pi‟ later in the program? (i.e. Pi = 3.142)
ii. Write a program to find the sizes of types „char‟, „float‟ and „double‟.

119
Summary
In C, there are four main data types. They are int, float, char and double. We define
variables stating its type followed by the name of the variable. Then values are
assigned to those variables using the assign (=) operator. Constants are C data storage
locations like variables, but once defined constant cannot be changed. There are two
types of constants in C named, literal and symbolic.

Learning Outcomes:
After reading this lesson you should be able to:
Explain preliminary data types
 declare and define variables
 assign values to variables and to manipulate those values
 correctly use constants
 write the size of a variable to the screen.

120
Session 11
C Operators and Expressions

Contents
Introduction, p 121
11.1 Assignment Operator and Arithmetic Operators, p 122
11.2 Relational Operators, p 123
11.3 Logical Operators, p 125
11.4 Increment and Decrement Operators p 127
11.5 Bitwise Operations, p 128
11.6 Precedence of Operators, p 129
Summary, p 130
Learning Outcomes:, p 130

Introduction
In order to work with variables and constants and manipulate data, we need a way to
operate with them. C provides „operators‟ for this purpose and keyboard symbols are
used to denote them. This session is designed to introduce different types of operators
used and the different actions they perform on data.

The most commonly used one is the assignment operator, which mainly deals with
assigning values to variables. In addition, this session outlines arithmetic operators,
which are the common mathematical operations found on a calculator. Logical
Calculations also can be performed using the logical operators. Furthermore, C
provides relational operators mostly to compare different types of values in order to
execute statements. There are special types of operators which are unique to most
programming languages. They are called increment and decrement operators which
helps in incrementing and decrementing a given value.

Each operator is assigned a priority and this is called the „precedence of operators‟
which is one of the most important aspects in working with different types of
operators. An operator is a symbol, which performs a certain action in a program. The
symbols are mostly made of signs that are available in all keyboards. Specific actions
are performed using a certain value or values given to variables or constants which are
called operands.

C provides operators for composing arithmetic, relational, logical, bitwise and


conditional expressions. It also provides operators, which produce useful side effects
such as assignment, increment and decrement.

121
11.1 Assignment Operator and Arithmetic Operators
The assignment operator (=) assigns a value to a variable. Assignment operator helps
you to perform several operations on variables.

 This operator operates in a right-to-left rule:


Example 11.1: a=b; Here „b‟ is assigned to the variable „a‟, which means the
right value is assigned to the left value and never the other way.

 This is useful even in assigning the same value to many variables.


Example 11.2: x = y = z = 7;
This expression is equal to x=7, y=7, z=7.
 Assignment operator in C can also be used as the right operand of another
assignment operation.
Example 11.3: x = 3 + (y=7);
This expression is equal to x= 3 + 7

C has 5 basic arithmetic operators which are given in Table 11- 1.


Table 11- 1 Arithmetic operators in C

Operator SymbolAction Example


Addition + Adds two operands x+y
Subtraction - Subtracts the second operand from the first x-y
operand
Multiplication * Multiplies two operands x*y
Division / Divides the first operand by the second x/y
operand
Modulus % Gives the remainder when the first operand x % y
is divided by the second operand
Operations of addition and subtraction are performed using their respective
mathematical operators and for multiplication and division, computing symbols * and
/ are used.

Modulus operator performs a bit different operation. It gives the remainder of a


division of two values.
 Example 11.1: int value= 10 % 3 result in giving 1 as the answer since 1 is the
remainder from dividing 10 from 3.
100 modulus 9 equals 1
10 modulus 6 equals 4

122
 Example 11.2: In using arithmetic operators, a suitable data type needs to be
chosen in defining variables.

unsigned int difference;


unsigned int num1= 7;
unsigned int num2= 9;
difference = num1- num2;

You would expect -2 as the answer, but -2 cannot be stored in the unsigned int
variable. Just like we have explained earlier unsigned variables do not hold negative
values. Hence this can lead to unexpected, incorrect outcomes.
As a solution „difference‟ can be defined as a signed integer variable.
signed int difference or int difference

 Example 11.3:
int num1= 5;
int num2 = 2;
int division;
division = num1/num2;

You would expect an answer as 2.5 but as „division‟ is defined as an int type variable,
it cannot hold a number with a fraction. Here you get the answer as 2, which is
incorrect. As a solution „division‟ can be defined as a floating point variable.
float division;

 Example 11.4: answer= 3/0;


Above statement is incorrect because it is illegal to divide a number by zero. This
results in a runtime „division-by-zero failure‟ which typically causes the program
to terminate.

Activity 11.1

Working with arithmetic operators


Write a program, which ask the user to input 2 integer values. Then your program should perform
addition, subtraction, multiplication, and division on the values the user entered and display the
results on the screen.

11.2 Relational Operators


C provides 6 relational operators for comparing numeric quantities which are shown
in Table 11- 2.

123
Table 11- 2 Relational operators

Operator Symbol
Action Example
Equal == Is operand 1 equal to operand 2? x==y
Greater than > Is operand 1 greater than operand x>y
2?
Less than < Is operand 1 less than operand 2? x<y
Greater than or equal >= Is operand 1 greater than or equal x >= y
to to operand 2?
Less than or equal to <= Is operand 1 less than or equal to x <= y
operand 2?
Not equal != Is operand 1 not equal to operand x != y
2?
In order to evaluate a comparison between two expressions, relational operators are
being used. The result of a relational operation is a Boolean value that can only be
true or false.

 Example 11.5:
o (4 = = 3) // Boolean value is false as 4 is not equal to 3
o (8 > 2) // Boolean value is true as 8 is greater than 2
o (4 != 9) // Boolean value is true as 4 not equals to 9
o (10 >= 10) // Boolean value is true as 10 is equals to 10
o (11 >= 10) // Here this expression also gives the Boolean value as true
since 11 is greater than 10
o (6 < 6) // Boolean value is false as 6 is not less than to 6
o Greater than or equal to‟ and „Less than or equal to‟ operators have to
be used exactly as shown in the above table. Expressions like => and
=< are invalid.
o Characters are valid operands since they are represented by numeric
values. (e.g., ASCII coding) Hence, „A‟<‟F‟ is a valid expression.
Note: Strings cannot be compared using the comparison operators. C provides
separate functions to compare strings.

A demonstration of the use of the relational operators


/*Using if statements, relational operators, and equality operators */
#include <stdio.h>
/* function main begins program execution */
int main( void )
{
int num1; /* first number to be read from user */
int num2; /* second number to be read from user */

printf( "Enter two integers, and I will tell you\n" );


printf( "the relationships they satisfy: " );

124
scanf( "%d%d", &num1, &num2 ); /* read two integers */
if ( num1 == num2 ) {
printf( "%d is equal to %d\n", num1, num2 );
} /* end if */
if ( num1 != num2 ) {
printf( "%d is not equal to %d\n", num1, num2 );
} /* end if */
if ( num1< num2 ) {
printf( "%d is less than %d\n", num1, num2 );
} /* end if */
}

Output
Enter two integers, and I will tell you
the relationships they satisfy: 3 7
3 is not equal to 7
3 is less than 7
3 is less than or equal to 7

11.3 Logical Operators


Logical operators also evaluate to Boolean value true or false. These are given in
Table 11- 3.
Table 11- 3 Logical operators

Operator Symbol
Action Example
Logical and (AND) &&True only if both exp1 and exp2 exp1 && exp2
are true; false otherwise
Logical or (OR) || True only if both exp1 and exp2 exp1 || exp2
or either exp1 or exp2 is true;
false otherwise
Logical negation ! False if exp1 is true; true if exp1 !exp1
(NOT) is false
The operator && denotes Boolean logical operation AND. Truth table is given in
Table 11- 4.
Table 11- 4 Truth table for AND operation

x y x && y
true true true
true false false
false true false
false false false

125
Example 11.6: ((7 == 7)&&(5 > 7))// Boolean value is false (true&&false =
false)

The operator || denotes Boolean logical operation OR. Truth table is given in Table
11- 5.
Table 11- 5 Truth table for OR

x y x || y
true true true
true false true
false true true
false false false

Example 11.7: ((7 == 7)||(5 > 7)) // Boolean value is true (true || false true)

The negation operator performs the Boolean operation NOT.


Example 11.8:
! (10= =10) // Boolean value is false because the expression at its right
(10 is equal to 10) is true.
! (8<=2) // Boolean value is true because the expression at its right (8 is not less than
2) is false.

11.3.1 Use of logical operators


/* Using if statements, relational operators, and equality operators */

#include <stdio.h>
/* function main begins program execution */
int main( void )
{
int CA; /* CA mark to be read from user */
int finalMark; /* final mark to be read from user */

printf( "Enter your CA marks:” );


scanf(%d,”\n”, CA );
printf( "Enter your final marks:”);
scanf(%d,”\n”,finalMarks);

if((CA>=40) && (final>=40))


printf("You have passed the subject\n");
else
printf("You have not passed the subject\n");
}

126
Output:
In the above program only if both the CA marks and final exam marks are more than
40, it will display the message as passing the subject.

Note: The if and else statements will be discussed in future sessions.

11.4 Increment and Decrement Operators


The increment operator (++) and the decrement operator (--) increase or decrease the
value stored in a variable. These operators are given in Table 11- 6.
Table 11- 6 Increment and Decrement operators

Operator Symbol Action Example


Auto increment ++ Increment occurs before the ++x
(prefix) variable value is used
Auto increment ++ Increment occurs after the x++
(postfix) variable value is used
Auto decrement -- decrement occurs before the --x
(prefix) variable value is used
Auto decrement -- decrement occurs after the x--
(postfix) variable value is used
In prefix form, the operator is applied first and the outcome is then used. In postfix
form, expression is evaluated first and then the operator is applied.

Example 11.9:
x=2;
y=++x; //After a single execution x=3 and y=3.
x=2;
y=x++; //After a single execution y=2 and x=3

In increment/decrement operators, the variable can only be incremented or


decremented by one value. To increment or decrement a value in a variable by a
larger or smaller value, it should be stated as below.

Example 11.10:
x += 3; //this is equal to x=x+3
amount -= 2; //this is equal to amount=amount – 2

*Note: increment and decrement operators work only with integer variables.

127
Use of the increment and decrement operators
/*Pre-incrementing and post-incrementing */
#include <stdio.h>
/* function main begins program execution */
int main( void )
{
int c; /* define variable */

/* demonstrate post-increment */
c = 5; /* assign 5 to c */
printf("%d\n", c ); /* print 5 */
printf("%d\n", c++ ); /* print 5 then post-increment */
printf("%d\n\n", c ); /* print 6 */

/* demonstrate pre-increment */
c = 5; /* assign 5 to c */
printf("%d\n", c ); /* print 5 */
printf("%d\n", ++c ); /* pre-increment then print 6 */
printf("%d\n", c ); /* print 6 */

return 0; /* indicate program ended successfully */


} /* end function main */

11.5 Bitwise Operations


A bitwise operation operates on one or more bit patterns at the level of their individual
bits. Bitwise operations are useful for tasks such as low-level device control when you
are working with microprocessor based interfacing, in error detection and error
correction algorithms, etc.

A bitwise operation is directly supported by CPU. There are many bitwise operators
defined in C.

These are,
bitwise AND (&),
bitwise inclusive OR (|),
bitwise exclusive OR (^),
left shift (<<),
right shift (>>), and
complement (~)

The bitwise operators compare their two operands bit by bit.

128
11.6 Precedence of Operators
In C there is an established order for the priority of each operator. This is called the
precedence of operators. The precedence is established for all the operators which can
appear in C. The priority order is shown in the Table 11- 7.
Table 11- 7 Precedence of operators

Rank Name Operator


1 scope resolution ::
2 member selection, subscripting, ., ->
function calls, postfix increment and decrement (), ++, --
3 sizeof, prefix increment and decrement, sizeof(), ++ ,-- ,^ ,! ,-
complement and not, unary minus and plus, ,+ ,& ,*, new[] ,
address of and dereference, new, delete, casting delete[] ()
4 member selection for pointer .* ->*
5 multiply, divide, modulo * , /, %
6 add, subtract +,-
7 shift <<, >>
8 inequality relational <<= >>=
9 equality, inequality == , !=
10 bitwise AND &
11 bitwise exclusive OR ^
12 bitwise OR |
13 logical AND &&
14 logical OR ||
15 conditional ?:
16 assignment operators = *= /= %=
+= -= <<= >>=
&= |= ^=
17 throw operator throw
18 comma ,
Operator precedence is defined in order to overcome some of the problems in
performing calculations. For example, sometimes it is difficult to decide which
operation to perform first.

Example 11.11: a= (3+5)*7


According to the above table a pair of parentheses () has a higher precedence
than multiplication. Hence expression inside the () should be performed first
(3+5=8) and then the multiplication. The answer will be 56.

129
Activity 11.2

The use of conditional (ternary) operator


Write a program, which asks the user to input 2 integer values. Then your program should identify
the largest value (using the conditional operator) out of the two integers and display it on the
screen.

Summary
 An operator is a symbol, which performs a certain action in a
program. Mainly there are 5 categories of operators namely,
assignment operator, arithmetic operator, logical operator,
relational operator, increment and decrement operator.
 The assignment operator (=) assigns a certain value to a variable.
 There are 5 basic arithmetic operators. They are addition (+),
subtraction
 (-), multiplication (*), division (/) and modulus (%).
 Relational operators are used for comparing numeric quantities.
There are 6 relational operators, which are equal, greater than, less
than, greater than or equal to, less than or equal to and not equal.
 Logical operators in C evaluate to Boolean value true or false.
Three basic logical operators are logical AND (&&), logical OR
(||), logical negation (!).
 The increment operator (++) and the decrement operator (--)
increase or reduce the value stored in a variable.
 In C there is an established order for the priority of each operator.
This is called the precedence of operators.

Learning Outcomes:
After reading this lesson you should be able to:
 manipulate data using C operators
 evaluate expressions using precedence of operators
 apply bitwise operations in programming

130
Session 12
Control Structures in C

Contents
Introduction, p 131
12.1 Conditional Statements, p 131
12.2 Iteration Structures (loops), p 134
12.3 Multiple initializations and increments, p 138
12.4 Nested Control Structures, p 138
Summary, p 139
Learning Outcomes:, p 140

Introduction
When you write a program to solve a problem you may need to branch off to different
parts depending on a condition i.e. take decisions or repeat a code segment. Such
„control structures‟ assist in serving special purposes. In addition they can be nested in
order to produce more complex and powerful programs.
If you can remember, „selection‟ is one of the three basic control constructs in
programming.

12.1 Conditional Statements


The conditional statements are used to make an execution choice in a program based
on a given condition. The if and else statements are the main conditional statements in
C.

12.1.1 The ‘if’ statement


The if statement enables to check for a given condition and it also helps to branch to
different parts of the programme depending on the result. The general format of the if
statement is:
if (condition)
Statement;

The program checks for the condition and when the condition is true, the statement is
executed and when the condition is false, the statement is ignored (not executed) and
the program continues.

131
Example 12.1: if (balance>0)
interest = balance * credit rate;
The if statement can control the execution of multiple statements using a compound
statement, or a block. (A block is a group of two or more statements enclosed in curly
braces) Any number of statements can be included inside this block given as;

if (condition)
{
Statement 1;
Statement 2;
}

Example 12.2:
if (balance>0)
{
interest = balance * credit_rate;
balance = balance + interest;
}

12.1.2 The ‘else’ statement


Additional operations can be specified using the keyword „else‟ as shown below;
if (condition)
{
Statement 1;
}
else
Statement 2;

When the condition in the if statement is evaluated as true, statement 1 is executed.


Otherwise, when the condition is false, the else statement is evaluated and the
statement 2 is executed. The else statement can also have multiple statements to
execute. We can use a block for this purpose as follows;
else
{
Statement 1;
Statement 2;
}

132
12.1.3 The ‘else if’ statement
In C, nested if statements can be used as shown below.
if ( ch>=‟0‟ && ch<=‟9‟ )
type = digit;
else
{
if ( ch>= „A‟ && ch<= „Z‟ )
type = capital_letter;
else
{
if ( ch>= „a‟ && ch<= „z‟ )
type = simple_letter;
else
type = special;
}
}

To simplify the compound statements given above else if statements can be used.
if ( ch>=‟0‟ && ch<=‟9‟ )
type=digit;
else if ( ch>= „A‟ && ch<= „Z‟ )
type = capital_letter;
else if ( ch>= „a‟ && ch<= „z‟ )
type = simple_letter;
else
type = special;

12.1.4 Use of ‘if’ and ‘else’ statements.

#include <stdio.h>

int value1, value2;

void main()
{
// Input two integer values
printf( "Enter integer 1: " ); /* prompt for input of an integer*/
scanf( "%d", &value1 ); /* read value1 for input 1 from user */
printf( "Enter integer 2: " ); /* prompt for input of another integer*/
scanf( "%d", &value2 ); /* read value2 for input 2 from user */

// check values and print their relationship


if (value1 == value2)
printf(“\nValue1 is equal to Value2\n");
else if (value1 > value2)
printf(“\nValue1 is greater than Value2\n)";
else
printf("\nValue1 is smaller than Value2\n");
133
return 0;
}

Output: Enter integer1: 35


Enter integer : 35
Value1 is equal to Value2

Activity 12.1

Examining the else if statement

Write a program which inputs a person‟s height (in meters) and weight (in kilograms) and the
output as one of the messages: underweight, normal or overweight.
Underweight: BMI<18.5
Normal: 18.5<= BMI <=25
Overweight BMI>25
Use the formula given below to calculate a persons BMI value:
BMI (Body Mass Index) = (weight) kg/ (height*height) m

12.2 Iteration Structures (loops)


Iteration structures or loops are used to repeat one or more steps in a program
depending on conditions. In C there are three basic iterations structures. They are the
while loop, do-while loop and the for loop.

12.2.1 The ‘while’ loop


The while loop first checks the given condition and when the condition is true, it
executes the statement or statements and exit the loop when the condition becomes
false.
The general form of the while loop is:
while (condition)
Statement;

The while loop consists of either a single statement or a set of multiple statements.
When there is more than one statement it has to be included inside curly braces which
we call a block as shown below;

while (condition)
{
Statement1,
Statement2;
}

134
Use of „while‟ loop
#include<stdtio.h>
void main()
{
int x = 0;
while (x<3)
{
printf("Before increment:",%d,x\t);
x++;
printf("After increment:" :",%d,x\n);
}
}

Output: The Table 12- 1 illustrates the operations of the while loop

Table 12- 1 operations of a while loop

Iteration Value of x Check for x<3 Increment Value of x


(Before) (After)
First 0 0<3-condition becomes true 0++ 1
Second 1 1<3-condition becomes true 1++ 2
Third 2 2<3-condition becomes true 2++ 3
Forth 3 3<3-condiiton becomes false Exit while loop

12.2.2 The ‘do-while’ statement


The do-while loop and the while loop is similar in nature except for a minor
difference. In the while loop it is possible that the body of it will never be executed, if
the condition becomes false, but using the do-while loop the body of the loop will be
executed at least one time.
Hence in do-while loops the body is executed first and then the condition is checked.
The general format of do-while is:
do
statement
while (condition);

The do-while loop also can have a single statement or multiple statements to execute.

135
Use of „do-while’ statement
1 #include<stdio.h>
2 void main() //will display the entered number until 100 is given as input
3 {
4 unsigned short number;
5 do
6 {
7 printf( "Enter number (0 to 999): ");
8 sacnf(“%d”, & number);
9 printf"(You entered: " :",%d\n, number,”\n");
10 }
11 while ( number != 100 );
12 return 0;
13 }
14

Output:
Enter number (0 to 999): 344
You entered: 344
Enter number (0 to 999): 100
You entered: 100

In the above program, every time the message in line 7 will be displayed for the user
to enter a value and then it will be displayed as „You entered:‟(line 9), followed by the
number the user entered. This continues until the user enters the value 100. Then it
will also be displayed as „You entered: 100‟ and only after displaying the message it
will check for the condition whether 100!=100. Here as the condition becomes false it
will exit the loop and the program will be terminated.

12.2.3 The ‘for’ loop


This is also similar to the while loop and its main function is also to repeat statements,
but the for loop is powerful and flexible to use. In addition, it provides a specific
location for the initialization, condition and for the increase or decrease operator.

The general format of a for loop is:


for (initialization; condition; increase/decrease)
statement;

The most common use of for loops is for situations where a variable is incremented or
decremented with every iteration of the loop.
Use of „for’ loop

136
/*Summation with for */
#include <stdio.h>
/* function main begins program execution */

int main( void )


{
int number; /* number to be added to sum */
int sum = 0; /* initialize sum */

for ( number = 10; number <= 100; number += 10 )


{
sum += number; /* add number to sum */
printf(“Sum is:”%d, sum, “/n”);

} /* end for */
}

Output:
Sum is: 10
Sum is: 20
Sum is: 30
Sum is: 40
Sum is: 50
Sum is: 60
Sum is: 70
Sum is: 80
Sum is: 90
Sum is: 100

The for loop also operates in a similar way to the while loop. The loop first initializes
„number‟ to 10. Then it checks for the condition and if the condition is true it
performs the operations inside the body. Then it increments the value of „number‟ by
10 and then checks the condition (whether number <= 10) and this continues until the
condition becomes false.

Activity 12.2

1. Write a C program to find the smallest alphabet character from entered 5 alphabet
characters.

2. Modify your program to take 10 alphabet characters and find the smallest.

137
12.3 Multiple initializations and increments
In the above example, only a single variable is initialized and incremented in a for
loop, but it is possible to initialized multiple variables and they can be incremented or
decremented accordingly.

Use of multiple initializations and increments


#include<stdio.h>
void main()
{
for (int a=0, b=3; a<3 && b< 10; a++, b--) {
printf("a="%d\t b= %d\t”, a, b);
}

Output:
In the above example „a‟ is incremented and „b‟ is decremented at the same time and
when variable „a‟ becomes 3 the condition becomes false and the program exits from
the „for‟ loop.
a=0 b=3
a=1 b=2
a=2 b=1

12.4 Nested Control Structures


Control structures can be nested to produce more complex programs. Here the loops
can be nested, which means one loop can appear inside another loop. The conditional
statement can also appear inside the loops.

Use of nested loops


The program given below, produce the product of set {1, 2, 3}
#include<stdio.h>
void main()
{
Int x; int y;
for ( x=1;x<=3;++x)
{
for(y=1;y<=3;++y)
printf("(%d,%d)/n”,x, y);
}
return 0;
}

138
Output: (1,1)
(1,2)
(1,3)
(2,1)
(2,2)
(2,3)
(3,1)
(3,2)
(3,3)

Activity 12.2

The use of nested loops

Write a program, which produces the following output. (Hint: Use nested loops)

******
******
******
******
******

Summary
 Conditional statements are used to make an execution choice in a
programme based on a given conditions. There are two main
control structures: if and else.
 The else if statements are used to reduce the complexity of
compound statements.
 The iteration structures help to execute a set of statements
repeatedly. There are three main iteration structures, while loop,
do-while loop and the for loop.
 All the iteration structures first perform the operations in the
initialization, and then evaluate the condition. If the condition is
true, it executes the action statement and the loop. When the
condition becomes false it exits the loop.
 There are three iteration structures in C and they are slightly
different in nature because of their operation and use.
 The while loop first checks the given condition, and when the
condition is true, it executes the statement or statements inside the
block.

139
 The do-while loop first execute the statements and then check
whether the given condition is true. Hence in do-while loops the
statements are being evaluated at least once.
 The for loop is more flexible to use than the other iteration
structures.
 When a loop appears inside another loop we call them nested
control statements and conditional statements can also be included
inside loops.

Learning Outcomes:
After reading this lesson you should be able to:
 branch your programming code based on conditions
 design iteration in programming

140
Session 13
Basic Input Output

Contents
Introduction, p 141
13.1 The getchar() & putchar() Functions, p 142
13.2 The gets() & puts() Functions, p 142
13.3 The scanf() and printf() Functions, p 143
13.4 How characters stored in memory (ASCII), p 144
Summary, p 145
Learning Outcomes:, p 145

Introduction
Programs given as examples in the previous sessions provided very little interaction
with the user. Using the standard input and output library (stdio), which we have
already used, we will be able to interact more with the user by printing messages on
the screen and getting the user's input from the keyboard. This session outlines these
basic input and output operations used in C.

In C, there are special formatting characters which help to increase the readability of a
program and it also assists in producing special effects in the program like making an
alert sound etc. Whitespace in C also helps to increase the readability and comments
helps to properly document a program.

In the previous session, data types in C were introduced stating their data type and
size in bytes. In this session, we will also introduce simple type conversions which
help in converting one data type to another.

Input and output operations are used to interact with the user. C programming
language treats all the devices as files. So, devices such as the display are addressed in
the same way as files and following three files are automatically opened when a
program executes to provide access to the keyboard and screen.

141
Table 13- 1 Devices in C

Standard File File Pointer Device


Standard input stdin Keyboard
Standard Stdout Screen
output
Standard error stderr Screen

13.1 The getchar() & putchar() Functions


The int getchar(void) function reads the next available character from the screen and
returns it as an integer. This function reads only a single character at a time.
The int putchar(int c) function puts the passed character on the screen and returns the
same character. This function puts only a single character at a time.
Use of input/output of a character

#include <stdio.h>
int main( )
{
int c;
printf( "Enter your name :");
c = getchar( );
printf( "\nYou entered: ");
putchar( c );
return 0;
}

Output:
Enter your name : Malinka
You entered: M

13.2 The gets() & puts() Functions


gets(char *s) function reads a line from stdin into the buffer pointed to by s until
either a terminating newline or EOF.
The puts(const char *s) function writes the string s and a trailing newline to stdout.

142
Use of input/output of a string
#include <stdio.h>
int main( )
{
char str[100];
printf( "Enter Your Name :");
gets( str );
printf( "\nYou entered: ");
puts( str );
return 0;
}

Output
Enter your name : Malinka
You entered: Malinka

13.3 The scanf() and printf() Functions


The int scanf(const char *format, ...) function reads input from the standard input
stream stdin and scans that input according to format provided.
The int printf(const char *format, ...) function writes output to the standard output
stream stdout and produces output according to a format provided.

The format can be a simple constant string, or you can specify %s, %d, %c, %f, etc.,
to print or read strings, integer, character or float respectively. There are many other
formatting options available which can be used based on requirements.

Use of formatted input/output


#include <stdio.h>
int main( )
{
char str[100];
int i;
printf( "Enter your name and age :");
scanf("%s %d", str, &i);
printf( "\nYou entered: %s %d ", str, i);
return 0;
}

Enter your name and age : Malinka 28


You entered: Malinka 28

143
Activity 13.1

Modify the program in session 8 activity under 8.2 (calculating the area of a triangle) to ask the
user to enter the height and the base of the triangle.

13.4 How characters stored in memory (ASCII)


When a character is entered in a program, the character itself is not stored. Instead, a
numeric value called the ASCII value of the character is stored. ASCII is abbreviated
from „American Standard Code for Information Interchange‟. It is a character-
encoding standard for electronic communication is used to represent text and special
characters in computers.

A Program demonstrating use of ASCII values

#include <stdio.h>
int main( )
{
int char = 71;
printf( "Character having ASCII value 75 is %c”, chr);
return 0;
}

Character having ASCII value 75 is K


When we display an ASCII value using "%c" text format, the corresponding character
is displayed.

Activity 13.2

Following program is designed to input five characters and find the character with minimum
ASCII value. Suppose you entered D, C, W, B, R. Minimum character is B.
#include<stdio.h>
#include <string.h>
int main()
{
char a[5];
int i=0;
char minchar;
printf("Enter characters->");
scanf("%s",a);
minchar=a[0];
for(i=1;i<=4;i++)

144
{
if(minchar>=a[i])
{
minchar=a[i];
}
}
printf("Minimum character = %c\n",minchar);
}

a) What is the difference between “%s” and “%c” ?


b) What is the purpose of including <string.h> ?

Summary
In this session we first discussed input and output of characters, strings and streams.
We also discussed how formatting options help to make the output more readable.

Learning Outcomes:
After reading this lesson you should be able to:
 develop interactive programs using basic input and output operations.
 use special formatting characters and white space in your programs.

145
Session 14
Functions in C

Contents
Introduction, p 146
14.1 What is a Function?, p 146
14.2 Declaring and Defining a Function, p 147
14.3 The „return‟ statement, p 150
14.4 Calling a function, p 150
14.5 The Execution of a Function, p 151
14.6 Assigning Default Values to Parameters, p 152
14.7 Local and Global Variables p 154
14.8 Arguments Passed by Value and by Reference, p 155
14.9 Special Functions, p 156
14.10 Advantages in Using Functions, p 157
Summary, p 158
Learning Outcomes: p 158

Introduction
As the standard of structured programming, any program is divided into a set of
modules arranged in a hierarchy defining their logical and execution-time
relationships. In a module, control must enter from its one entry point and must leave
the module from its one exit point, and must always be passed back to the invoking
module.

Program comments are used to define the overall program function and to introduce
each module by explaining its function, its data structures, and its relationship to other
modules in the program.

14.1 What is a Function?


A function is a piece code that performs a specific task. Functions are one of the most
important aspects of program design. Using functions, a program can be properly
structured. Some functions are supplied as part of the compiler package but this
session mainly focuses on the functions that the user can create.

When writing a function, the first step is to know what tasks the function needs to
perform. In addition, a function has a specific format and it needs to be followed when
writing them.

146
A function can be called as a sub program which manipulates data and performs a
specific task in a program. Every program has at least a single function. For example
every program contains the function called main().

There are two types of functions:


1. User-defined: The programmer can define his or her own functions.
2. Built-in: These functions are part of the compiler package, which are
supplied by the manufacturer and can be used in writing programs. (main(),
printf(), scanf(), etc)

The general format of a function is:


return_data_type function_name ( parameter1, parameter2, ...)
{ statements ; }

 The ‘return_data_type’ is the data type that is returned by the function.


 The „function_name’ is the name or the unique identifier of the function.
 The „parameters’ consists of a data type followed by the name of the
parameter, (example: int x). A function can have zero or any number of
parameters separated by commas.
 The „statements’ are called the body of the function. It is a block of statements
surrounded by braces { }.

14.2 Declaring and Defining a Function


A function needs to be declared and defined before using it. These concepts will be
covered using the example program given below.
Use of functions

1 #include<stdio.h>
2 int addition (int no_of_bats, int no_of_balls);
3 void main ()
4 {
5 int answer;
6 answer = addition (5,15);
7 printf( "The result is %d”,,answer);
8 }
9
10 int addition (int no_of_bats, int no_of_balls)
11 {
12 int total;
13 total= no_of_bats + no_of_balls;
14 return total;
15 }

Output: The result is 20

147
14.2.1. Declaring a function
There are three ways to declare a function: The declaration includes the function
return type, function name, and parameter list. This is also called the prototype of the
function.

1. Write the prototype into a separate file, and then use the #include
directive to include the function in the program.
Example 14.1: In the program given above, the functions like printf() (line 7) are
included in the „stdio.h‟ file and we include it in our program using #include (line 1).

2. Write the prototype at the beginning of the file (before the main method) in
which the function is used.
Example 14.2: In the above program the prototype of the function is given in line 2:
int addition (int no_of_bats, int no_of_balls);

3. Define the function before it is called by any other function. Here the
definition of the function acts as its own declaration.

Example 14.3: The above program can be written without a prototype


#include<stdio.h>

int addition (int x, int y)


{
//statements
}
void main()
{
//statements
}

In the above program the function can be included before the main() function. In a
situation like this there‟s no need of a prototype, but it is advisable to use a prototype
in programs for many reasons, such as;
If a prototype is not used, the functions need to be included in a particular order
making it difficult to maintain and change the program in the long run.
Sometimes a function may call another function and that function in return can call
the first function (function x calls function y and function y can call function x again)
In this kind of complex situations it is hard to decide which function should be
included first. Hence the function prototype needs to be declared.

14.2.2 Defining a function


The definition of a function includes the header and its body. The header is the
„function return type‟, „function name‟ and „parameter list‟.

Example 14.4: int addition (int no_of_bats, int no_of_balls) (line 10)

148
The function return can be a null value, which means there can be functions, which do
not return any value. These functions are declared using the keyword void.
The main function that is been used so far is a function, which does not return any
value. These functions are mostly used when we want to print a message on the screen.
Here no value needs to be returned in order to print a message. In addition, the
parameter list can be left blank if the function needs no parameters.

Example 14.5:Following function is a user defined function which prints the message
“This is a function!”
void message ()
{
Printf("This is a function!/n");
}

The void keyword can also be used in the function's parameter list to explicitly specify
that the function does not take any actual parameters when it is called.
Example 14.6: The function in example 14.5 could have been declared as:
void message (void)
{
Printf("This is a function!/n");
}

Even though some functions do not return any value, they can contain a parameter or
a list of parameters.
Example 14.7:
void PrintMessage(int messageSelect)
{
if (messageSelect == 0)
printf("Start of Programme.\n");
if (messageSelect == 1)
printf( "End of programme.\n");
}

The body of a function includes the statements (computation steps) inside the curly
braces {} which contains the instructions on how to perform a specific task.

Example 14.8: In the program given line 12 to 14 is the body of the function.
int total;
total= no_of_bats + no_of_balls;
return total;

149
14.3 The ‘return’ statement
In the example given above, in line 14, the return keyword has been used followed by
an expression. This is called the „return statement’. It should be declared inside the
function body. The return statement has a general format.
return expression;

The „expression’ is the value returned by the function. The type of this value should
be same as the return type of the function.

Example 14.9: In the program given above, the return type of the function is an
integer (int addition). Hence the return value „total‟ should also be an integer value.
For a function which the return type is void, expression should also be 0 or empty.
The main function can also be written as given below.

int main (void)


{
printf(“Open University\n”);
return 0;
}

Note: In declaring the prototype of a function, it is not necessary to include the names
of the parameters. The type of the parameter list is also sufficient.
int calculate (int, int);

14.4 Calling a function


Using a function involves calling the function. A function call consists of function
name followed by the call operator brackets „()‟. Inside the call operator brackets a
function arguments appears. The value that is returned by the return statement is the
point where the call occurs.

Example 14.10: addition (4,5) ; (line 6)

The number of arguments should match the number of function parameters.

Example 14.11: The function called „int addition()‟ has only two parameters which is
int no_of_bats and int no_of_balls. In the calling function inside the call operator
brackets „()‟ there should be only two arguments which are 4 and 5.

Not only the number of parameters but also the type of the parameter should match
the function parameters.

150
Example 14.12: Both function parameters no_of_bats and no_of_balls are of type int
(line 10) Hence the argument values also should be of type int. (line 6). It cannot be a
floating point or other type of a value.

14.5 The Execution of a Function


Regardless of whether a function is declared before the main function, or a function
prototype is declared before the main function, the execution of all C programs start
from the main function. Figure 14- 1 illustrates the general executions of a set of
functions. A function can call for more than one time. Function „function1()‟ call in
two times within the main program. It is depicted in
 “a” call from the first “function1() and “a” returned to the first
“function1()” of the main() function and
 “a” call from the second “function1() and “a” returned to the second
“function1()” of the main() function.

Figure 14- 1 Execution of functions

Function “function4()” is called by inside the “function2()”.

Consider the example program we examined first. First it declares the variable called
„answer‟ of type int. Then it branches to the prototype of the function called „addition‟
in line 2.

151
int addition (int no_of_bats, int no_of_balls);

When the function is identified by the program first, the above function prototype tells
the compiler that the program passes the value of two integers to the function so that
the „return value‟ must be assigned to an integer variable. Then the program execution
passes to the function definition which starts from line 10.

The arguments are evaluated and their resulting values are assigned to the
corresponding parameters. (The values 5 and 15 are passed to „int no_of_bats’ and int
no_of_balls respectively) The body of the function is then executed. (Add
no_of_balls and no_of_bats and store 20 in the variable called „total’). Finally if there
is a value to be returned (line 14), it is passed to the caller. (the value 20 is returned to
the variable called „answer’)
answer = addition ( 5, 15 );

After the last statement of the function has been processed (the return statement in
line 14), the execution resumes on the next line after the call to the function (return to
line 6) and prints the answer, “The result is 20”.

Activity 14.1

Creating simple functions


1. Write a function to solve y= 5*x2 + x . Input parameter to the function is x.
Then write a complete C program to input x value by the user and call the function with the x value.
Print the returned y value of the function.

2. Write a program which takes an integer value between 1 and 10 as the input
and calculate its factorial and give the answer as the output.
Use the formula given below:
Factorial(0)=1
Factorial(n)=n*factorial(n-1)

Note: When the user enters a value out of the given range it should display an error message and
the program should again ask the user to input a valid integer.

14.6 Assigning Default Values to Parameters


In the beginning of this session it was mentioned that the number of arguments in a
function call should match the number of function parameters in the given function.

Example 14.13: average (20,1,6)


int average (int a, int b, int c)

A programmer can break the above rule by defining default parameter values in the
function declaration. Using the assignment operator (=), default values can be

152
assigned to the function parameters. Any or all of the function's parameters can be
assigned default values.

Example 14.14: int add (int x, int y=5, int z=8)

When sufficient number of arguments is not supplied for the function, the default
parameter values are being used but if a value is specified, this default value is
ignored and the passed value is used instead.

If any of the parameters do not have a default value, no previous parameters can have
a default value.

Example 14.15: int add (int x, int y, int z)

A default value to „x‟ can be assigned only after assigning default values to both „y‟
and „z‟. A default value to „y‟ can be assigned only after assigning a default value to
„z‟.
Use of default parameters

In the example given below, in line 3, for „b‟ and „c‟ default parameters have been
assigned. In the first function call in line 7, since the value 12 is passed as an
argument to the function, „a‟ is assigned to 8. Since there are no values passed for „b‟
and „c‟, it takes the default values which is b=9 and c=10. Then in the first average
calculation the result becomes 9 (Refer line 15: (8+9+10)/3 = 9).
1 #include<stdio.h>
2 //function prototype
3 int average (int a, int b=9, int c=10);
4 void main ()
5 {
6 //function call and result display
7 printf("First Average %d", average(8));
8 printf("Second Average %d", average(20,4,6));
9 printf("Third Average %d", average(1,4));
10 }
11 //function declaration
12 int average (int a, int b, int c)
13 {
14 int result;
15 result=(a+b+c)/3;
16 return result;
17 }

Output:
First average: 9
Second average: 10
Third average: 5

153
In the second function call in line 8, since all the values have been passed as an
argument the compiler ignores the default values and the answer becomes 9 (Refer
line 15: (20+4+6)/3 = 10).
In the third function call in line 9, values 1 and 4 are assigned to „a‟ and „b‟
respectively and the default value of 10 is assigned to „c‟. Here also the default value
of „b‟ is ignored since a value has been passed by the function call. Hence the answer
is 5 (Refer line 15: (1+4+10)/3 = 5).

Activity 14.2

The use of default parameters

Write a function which calculates a volume of a cube. Assign default parameters only to its width
and length.
Call the function 3 times inside the main method.
1. Pass only one argument (both default parameters will be called)
2. Pass two arguments (only one default parameter will be called)
3. Pass all three arguments

Write a separate function which prints the message “Volume of the cube:”

14.7 Local and Global Variables


Local variables are declared and defined inside the body of the function and can be
used to store values inside the function. These kinds of variables said to have a ‘local
scope‟, which means the scope of local variables is limited to the same block level in
which they are declared.

Variables declared outside the body of any other function is considered as global
variables and can be accessed inside any function in the program. These variables
said to have „global scope’.

However,
 if a function has a variable with the same name as a global variable, the
name refers to the local variable (not the global variable) when used
within the function.

 Un-initialized global variables are automatically initialized to zero.

 Generally, the lifetime of a variable is limited to its scope. Global


variables last for the duration of program execution, while local
variables are created when their scope is entered and destroyed when

154
the program exit its scope. The memory space for global variables is
reserved prior to commencing of the program execution, whereas
memory space for local variables is allocated only for the time that the
variables are being used.

Use of local and global variables


1 #include<stdio.h>
2 void addFunction(); //function prototype
3
4 int x = 4, y = 5; //declaration of global variables
5 void main ()
6 {
7 printf( "Total (inside main function): %d”, x+y, "\n\n";
8 addFunction();
9 }
10 void addFunction()
11 {
12 int y = 20; //declaration of a local variable
13 int total;
14 total=x+y;
15 printf( "Total (inside add function): %d”, total, "\n");
16 }

Output:
Total (inside main function): 9
Total (inside add function): 24

In line 4, two global variables called „x‟ and „y‟ are declared and initialized to 4 and 5
respectively. Inside the function called „addFunction’, a variable called „y‟ is
declared again and initialized to 20. This is a local variable, which is local to the
scope of the „addFunction‟. In line 7, in adding „x‟ and „y‟, the program refers to the
global variables and the answer is 9 (4+5).

In the function call (line 8), „y‟ variable refers to the local variable, which is equal to
10 (refer line 12). Since there is no variable called „x‟, which is defined inside the
function, „x‟ refers to the global variable as they can be accessed inside any function
in the program. Hence in the function call, the answer is 24 (4+20).

14.8 Arguments Passed by Value and by Reference


There are two ways to pass arguments to a function. That is passing arguments by its
value and by its reference.

In considering passing arguments by value during a function call, what is passed to


the function are copies of their values and not the actual variables. Hence changes that
have been made to the function arguments inside the function do not affect the
variables that have been declared outside the function.

155
Example 14.16:
int x=10, y=20;
addition(x,y); //function call

int addition(int value1,int value2)


{
result = value1+value2;
return result;
}

Example 14.16 shows part of a program. During the function call, values 10 and 20
are passed into the function arguments „value1‟ and „value2‟ respectively. If we make
changes to the function arguments („value1‟ and „value2‟) inside the function, it does
not affect the variables „x‟ and „y „which are defined outside the function because „x‟
and „y‟ variables are not passed into the function but only their values are passed.

In passing values as references to a function, ampersand (&) sign is used before the
function arguments that need to be passed as references. When passing by reference,
the variable itself is passed into the function and not the copies of their values. Hence
all the changes that have been made to the function arguments inside the function
straight away affect the variables that have been passed to the function. Consider the
example given below.
Example 14.7:
int x=10, y=20;
counter (x, y);
void counter(int &value1,int &value2)
{
++value1;
++value2;
}

In the example given above, the ampersand (&) mark has been used before the
function arguments („&value1‟ and „&value2‟). It specifies that the arguments need to
be passed into the function by reference instead of by value. Inside the function, both
function arguments „value1‟ and „value2‟ has been incremented. Those increments
affect the variables „x‟ and „y‟ which is defined outside the function.

14.9 Special Functions


There are few special functions in C language like recursive functions and built-in
functions as discussed below.

156
14.9.1 Recursion
Recursion is the ability that the function has, which could call itself. In the function
definition there is a point where the function calls to that very same function and
repeats the same code. In programming this method is useful in many tasks like
sorting and calculating.

14.9.2 String Functions


C language provides more sophisticated built in functions to make problem solving
convenient withut having to be concerned about defining functions. One such
example is „String‟ functions built-in for manipulating strings.

For this purpose the C library has a standard string class. In order to use the functions
provided with it, the standard header file called the „string‟ needs to be included in the
program. Some of the string handling functions are strlen – find length of a string,
strcpy – copy a string, strcmp – compare two strings, strcat – concatenate two strings,
etc.

14.10 Advantages in Using Functions


 Enable reuse of code across multiple programs.
 Reduce the duplication of code in a program (Example: by replicating
useful functionality, such as mathematical functions).
 Decomposing complex problems into simpler pieces (this improves
maintainability and ease of extension of the programme).
 Improve readability of a program.
 Hiding part of the program that does not need to be seen (Information
hiding).

157
Summary
 A function can be called as a sub program which manipulates data and
performs a specific task in a program.
 There are two types of functions. They are user-defined functions and built in
functions.
 There is a general format for a function. This includes function name, return
data type, parameters and a set of statements which is the body of a function.
Some functions do not contain any parameters and every function doesn‟t
return a value.
 Before using functions, they need to be declared and defined. The definition of
a function includes the header and its body.
 There are three ways to declare a function. They are, writing the prototype at
the beginning the file, defining the function before it is called by any other
function and using the #include directive.
 Function call consists of function name followed by the call operator brackets
„()‟.
 The execution of every C program starts from the main function.
 The programmer can define default parameter values in the function
declaration.

Learning Outcomes:
After reading this lesson you should be able to:
 declare and define functions
 pass parameters into functions
 return a value from a function

158
Session 15
Data Structures

Contents
Introduction, p 159
15.1 Abstract Data Types and arrays, p 159
15.2 Declaring and Accessing Arrays, p 160
15.3 Data Structures, p 162
15.4 Important General Characteristics Relating to Data Structures, p 166
Summary, p 167
Learning Outcomes, p 167

Introduction

By now you are very familiar with data types such as integer, which is built into the C
language. Its definition comprises of two parts.
 Firstly, the set of all possible values a variable or a constant of that type may
take
 Secondly, the operations that can be performed on such values (For example
operations such as multiplication, division, assignment, various forms of
comparison, etc).
If we are to write programs that need to use data types that are not defined within the
language, we must define these types ourselves. To make sure that our programs will
do what we want, we should make such definitions rigorous.

Therefore, when we define any data type, we have to describe what values it may hold,
and what operation are available to operate with it. In this session we will discuss how
to define such new data types with possible applications.

15.1 Abstract Data Types and arrays


To work with a language like C, it is essential that the definitions of these user defined
data types are rigorous, so that all compilers work the same. Such definition is often
given with mathematical symbolism and is called an abstract data type. It is only
concerned with the behaviour a user can depend on, not at all with the way integers
are coded in store, or the way that multipliers work.

159
Thus when we define any data type, we will describe what values it may hold and
what operation are available to deal with them.

15.2 Declaring and Accessing Arrays


An array is a group of memory locations of the same type and share the array name.
To refer to a particular location or element in the array, we specify the name of the
array and the position number of the particular element in the array.

Figure 15- 1 shows a char array called myArray. Assume that this array contains 10
elements. Any one of these elements may be referred to by giving the name of the
array followed by the position number of the particular element in square brackets - [].
The first element in every array is the zeroth element. Thus, the first element of
myArra is referred to as myArray [0], the second element of myArray is referred to as
myArray [1], and, in general, the ith element of myArray is referred to as myArray [i
- 1].

Array names, like other variable names, can contain only letters, digits and
underscores. Array names cannot begin with a digit.

Figure 15- 1 Array representation

The position number contained within square brackets is more formally called a
subscript (or index). A subscript must be an integer or an integer expression.

To tell the computer to reserve 10 elements for integer myArray, the definition
Char myArray[10]
is used.

The following definition reserves 100 elements for characters for myArray.
Char myArray[100]

15.2.1 A demonstration of the use of Arrays


The following program shows how to define an array, how to initialize an array and
how to perform some common array manipulations.

160
/* initializing an array */
#include <stdio.h>
/* function main begins program execution */
int main( void )
{
int numberArray[ 10 ]; /* array of 10 integers called numberArray */
int count; /*counter */
/* initialize elements of array called numberArray to 0 */
for ( count = 0; count < 10; count++ )
{
numberArray[count] = 0; /* set element at location i to 0 */
} /* end for */
printf( "%s%13s\n", "Location", "Value" );
/* output contents of numberArray as a table */
for ( count = 0; count < 10; count++ )
{
printf( "%7d%13d\n", count, numberArray[ count ] );
}
return 0; /* indicates successful termination */
} /* end main */

If the array size is omitted from a definition with an initialized list, the number of
elements in the array will be the number of elements in the initialized list.

Activity 15.1

Ten integers should be entered into an array named myFirstArray by the user and then find the
number of zeros stored in myFirstArray.
1) Draw a flow chart indicating begin, end, inputs, iterations and conditional control structures.
2) Write a C program for the flow chart including header files, main function, inputs, outputs,
iterations and conditional control structures. Write the program with a fewest number of lines in the
program.

15.2.2 Multi-dimensional Arrays


In a single array all the elements consists of the same data type so the type needs to be
specified.
The general format of declaring an array is:
data_type array_name [number of array elements];

Example: int marks [100];

161
This idea can be extended to multi dimensional arrays. Here we restrict our attention
to 2-D arrays. A two dimensional array of integers can be declared in C as;
int DataArray [3][4] ;
Column 1 Column 2 Column 3 Column 4
Row 1 [0][0] [0][1] [0][2] [0][3]
Row 2 [1][0] [1][1] [1][2] [1][3]
Row 3 [2][0] [2][1] [2][2] [2][3]

The above array has 3 rows and 4 columns and can hold maximum of 12 elements.
Since Arrays have a fixed size after declaring it, it is important that array size needs to
be specified in advance.

15.3 Data Structures


When considering data structures, we are concerned with the relations between data
elements. The nature of the element is not our concern: we regard them as atoms and
do not look inside them. Of course, the user of a data structure will be concerned with
the elements, which may be complex data structures themselves.

As another example, in a C array of char, the data elements are relatively simple –
characters – although a character has a bit structure.

At the highest-level, we prefer to deal with abstract data structures. This means that
we are not interested in how the structures are to be stored and handled in the
computer, but concerned only with the user‟s view of the structure. The users‟ view
should in fact be shielded from any implementation details. He/she should think of the
structures as a container for his/her data items, together with operations available to
him/her to access the items.

As a simple example we could consider a set. A set hardly qualifies as a data –


structures since it is entirely unstructured. Operations on a set are:
 Add an item (duplicates will be rejected)
 Retrieve an item (and there is no guarantee which will be given)
 Discover whether the set is empty.
 Discover whether a particular item is present.

In addition to the operations on one set, we may decide to include in our abstract
definition operations between sets such as union, intersection difference for example.

Mapping a set in to a computer store presents an unusual problem. The store is


structured, so unless we deliberately introduce randomness, we will usually store the
set as some structure. For example, we can use an array.

162
15.3.1 Definition of the Data Structure
A data structure is a collection of related information nodes (elements, components,
entries, items, members, fields) which may themselves be (internally) structured.
Common data structures include arrays, records, lists, queues, stacks, sets, strings.

As with scalar data (integer, real, char, Boolean) each type of structure has an
associated set of operations.
e.g. Joining and leaving queues.
Element use (access) and change (update) for arrays.
Initialisation, push, pops for stacks.

15.3.2 Enumeration Type


Enumeration is a user defined variable type that enables the user to define values for
the type. Enumerations are declared using the enum key word followed by the
enumeration name. An enumeration value has to be included inside curly braces.

Example 15.1:
enum workingDay {Monday, Tuesday, Wednesday, Thursday, Friday};

Every enumeration has an integer value. The default starts with 0 and the rest will
count up from there. Monday has a value of 0, Tuesday has the value 1, Wednesday
has the value 2 etc.
A value can also be initialized to an enumeration.

Example 15.2:
enum workingDay { Monday=50, Tuesday, Wednesday=88, Thursday, Friday=900 };

Here: Monday=50, Tuesday=51, Wednesday=88, Thursday=89, Friday=900

Note: enumerator variables actually are of type unsigned int.

Demonstration of the use of enumerations


#include<stdio.h>
main()
{
enum cards
{
spades=5,
hearts =0,
clubs=10,
diamonds =0
};
printf("\n Spades value: %d", spades);
printf("\n Hearts value: %d", hearts);

163
printf("\n Clubs value: %d", clubs);
printf("\n Diamonds value %d:", diamonds);
printf("\n ");
}

Output
Spades value 5
Hearts value: 6
Clubs value: 10
Diamonds value: 11

In the above program, when the variable „spades‟ is assigned to 5, the next value is
automatically assigned to 6. When clubs is assigned to 10, Diamonds will be
automatically assigned to 11.

Activity 15.2

Write a program that use „enumeration‟ type to hold values for months of the year.

15.3.3 Structures in C

A structure in C language, is a collection of variables under a single name. These


variables could be of different data types. This data structure is useful for defining
records if we use files, but can be used on its own as well.

Say that you want to store information about a student: his/her name, NIC number,
year of birth, and email address.
For this, you can create different variables; name, NIC number, year of birth, and
email address to store these information separately.
But if you need to store information of more than one student, you will have to create
different variables for each information per student like: name1, NIC number1, year
of birth1, email address1, name2, NIC number2and, year of birth2, email address2 etc.

In such situation it would be better to have a collection of all related information


under a single name „Student structure‟, and use it for every student.

Keyword „struct‟ is used for creating a structure.

164
Syntax of structure
struct structure_name { data_type variable_1; data_type varaiable_2; . .
data_type varaiable_n; };

Example 15.3:
struct Student{char name[55]; char NIC_number[10]; int year_of_birth; char email
_address[15]; };

When a structure is defined, it creates a user-defined type but no storage or memory is


allocated. To allocate memory of a given structure type and work with it, we need to
create variables as shown below.
int main()
{
struct Student student1, student2;
return 0;
}

To access a part of the structure, for example students‟s name, we use the format
student1.name

use of struct in a program


#include <stdio.h>
#include <string.h>

struct Student
{
char name[55];
char NIC_number[10];
int year_of_birth;
char email_address[15];
};

int main()
{
struct Student student1 = {0}; //Initializing to null

strcpy(student1.name, “Anjali Khan”);


strcpy(student1.NIC.number, “2010200555”);
student1.year_of_birth = 2010;
strcpy(student1.email_address, anj2010@gmail.com);

printf(" Name is: %s \n", student1.name);


printf(" NIC number is: %d \n", student1.NIC_number);
printf(" Year of Birth is: %f \n", student1.year_of_birth);
printf(“email address is: %s \n", student1.email_address);
return 0;
}

165
Activity 15.3

Declare a structure type to hold a student‟s StudentID, Name and marks.


Use that structure in a program to enter marks for 10 students and display their information.

15.3.4 The ‘typedef’ Keyword


The typedef keyword enables to create a synonym for an existing data type. A typedef
declaration contains the typedef keyword followed by a name in the position of a
variable name.

Example 15.4: typedef unsigned long int UNLONG

use of ‘typedef’ keyword

The keyword typedef is used to create an alias or a new name for an existing type or a
user defined type. It is an advance feature in C language.
#include<stdio.h>
main()
{
typedef unsigned short int USHORT;
USHORT val1 = 4;
USHORT val2 = 688;
USHORT val3 = 34;
USHORT total = val1+val2+val3;
printf("\n Total of the values : %d", total);
printf("\n ");
}

In the above example total of three values are being calculated. Here, USHORT
creates a synonym for „unsigned short int‟. This has reduced the tedious, repetitious
writing „unsigned short int‟ in rest of the program. This also reduces the user errors
that can happen in writing the same words over again in the programme.

15.4 Important General Characteristics Relating to Data


Structures
The nodes of some data structures are of the same type as each other. These are called
homogeneous data structures.
e.g. arrays, strings, sets

166
If the nodes are of different types then the structures are called heterogeneous
structures
e.g. Structs

In the case of homogeneous structures, associated operations often apply to the each
element of the structure in tern or even potentially, in parallel, whereas such repetition
is not possible in the heterogeneous context. It should be noted that (heterogeneous)
records may be use to build structures such as lists, and trees which are collectively
homogeneous.

Some data structures are built into programming languages, whilst others are not,
depending on the language. C for example has built in arrays, strings, etc. Where
structures are built into a language, the compiler must be designed to map them to the
language in which it is written e.g. machine code. The data structures which are not
built into the programming languages have to be programmed by devising a suitable
storage scheme in term of the structures which are built in implementing the
operations as procedures and functions.

Summary
User defined data types are called Abstract Data Types (ADT)s. Two such examples
are enumeration type and struct.

Typedef keyword is used to create an alias or a new name for an existing type or a
user defined type.

An array is a set of elements, each of which holds the same type of data. These data
elements are stored in consecutive places in the memory and must be declared before
it is used. When declaring arrays there are two things that need to be taken into
consideration. That is:
 The type of data items that are required
 The number of data items required

Some data structures can contain values of only one data type, which are called
homogenous where as some other can contain values of different types.

Learning Outcomes
After studying this session you should be able to,
 briefly explain the concept of a data structure
 define and apply arrays in programs
 apply enumeration data type in programs
 apply struct data type in programs
 use typedef function in programs

167
Session 16
Dynamic Data Structures

Contents
Introduction, p 168
16.1 Data Structure Storage Schemes, p 168
16.2 Pointer Concept in C, p 169
16.3 Linked List, p 172
Summary, p 177
Learning Outcomes, p 177

Introduction
The most important characteristic of any data structure is its capacity for structural
change. Some structures remain structurally fixed throughout their existence. i.e. they
are not permitted to grow or shrink between initial creation and eventual destruction.
These structures are called STATIC structures. Those structures which may be
changed are called DYNAMIC structures. In this session we will discuss how to
define DYNAMIC data structures.

16.1 Data Structure Storage Schemes


There are two basic representation strategies available for mapping data structures to
computer storage. These are sequential (contiguous) storage and the link storage
method. The sequential storage method stores and entire structure in node order in a
fixed size block of consecutive storage locations, whereas the linked storage method
utilises any number of arbitrary located storage fragments (anywhere in store, not
necessarily adjacent). The two representation strategies are introduced below, together
with C‟s pointers.

16.1.1 Sequential representation


The first node is stored in a particular free store location. The second node will be
stored in the next store location. Suppose we need to store an array of characters. We
store the array in the store with the first store location 100. Characters take only one
byte. This situation can be shown in Figure 16- 1.

168
Figure 16- 1 Sequential representation

16.1.2 Linked representation


In this representation (shown in Figure 16- 2), a variable (say start) has the address of
the first node. The first node has the address of the second node and so on. The
following diagram shows the situation.

Figure 16- 2 Linked representation

The value of the linked method is in representing structures whose shape and size may
vary arbitrarily during their lifetime (dynamic structures), particularly when several
structures have to share and area of store. The sequential method is appropriate for
static structures.

It is not practical for a general purpose language to provide a range of data types
covering each possible class of linked data structure. So, C provides the user with a
mechanism called pointers with which he/she can program linked structures and
operations applicable to them.

16.2 Pointer Concept in C


Pointers do not store a value directly just like normal variables store values. Instead, a
pointer stores a reference of another value.

A pointer contains the address of a data construct. Therefore, pointers are of the same
size regardless of what they are pointing to.

16.2.1 Declaring pointers


A pointer must be declared before it is used.
The general format of declaring a pointer is:
data_type *pointer_name;

169
In declaring pointers, the pointer type needs to be declared first (int, char, float etc),
followed by the name of the pointer. Before the pointer name, an asterisk (*) is used
to denote that this is a pointer and not a variable. This asterisk mark is also called the
„value of operator‟.

Example 16.1: int *p1;


The integer type pointer declared above is named, „p1‟

Number of pointers and variables can also be declared at the same time.
Example 16.2: int *p1, *p2, result;

16.2.2 Initializing pointers


A pointer cannot perform any task until it is initialized. Until a pointer holds the
address of a variable, it isn't useful. Here the ampersand (&) operator is used to assign
the address on a variable to the pointer. The ampersand mark is also called the
„address of operator‟.

Example 16.3: int *p1, result;


result =10;
p1 = &result;

In the example given above, first an integer type pointer (*p1) and a variable called
„result‟ are declared ((a) and (b) of Figure 16- 3. Then the variable is assigned the
value 10 and the address of the variable (&result) is assigned to the pointer „p1‟((c)
and (d) of Figure 16- 3. This is further explained using the diagram given below and
using the concepts on how the pointers are arranged in the computer memory.

Figure 16- 3 Declare pointer and result next -assigning result to pointer

Program for declaring pointer, result and assigning result to pointer

#include <stdio.h>
int main( void )

170
{
int result; /* result is an integer */
int *p1; /* p1 is a pointer to an integer */
result=10;
p1 = &result; /* p1 set to address of result */
printf( "The address of result is %p",&result);
printf("\nThe value of p1 is %p",p1 );
printf( "\nThe address of p1 %p\n",&p1 );
return 0; /* indicates successful termination */
}

output
The value of result is 10
The address of result is 0x7ffc46a9fcec
The value of p1 is 0x7ffc46a9fcec
The address of p1 0x7ffc46a9fcf0

Figure 16- 4 Pointer with real addresses

Graphical representation of the above program is shown in Figure 16- 4. Value of the
variable “result” is 10 and its address is 0x7ffc46a9fcec. The value of the pointer “p1”
is 0x7ffc46a9fcec and it is the address of the variable “result”. Address of the pointer
“p1” is 0x7ffc46a9fcf0.

A demonstration of the use of pointers


/* Program using the & and * operators */

#include <stdio.h>

int main( void )


{
int a; /* a is an integer */
int *aPtr; /* aPtr is a pointer to an integer */

a = 7;
aPtr = &a; /* aPtr set to address of a */

171
printf( "The address of a is %p" "\nThe value of aPtr is %p",&a ,aPtr );
printf( "\n\nThe value of a is %d" "\nThe value of aPtr is %d",&a ,aPtr
printf( "\n\nShowing that * and & are complements of "
"each other\n&*aPtr = %p"
"\n*&aPtr = %p\n",&*aPtr ,*&aPtr );

return 0; /* indicates successful termination */


} /* end main */

Output
The address of a is 0012FF7C
The value of aPtr is 0012FF7C

The value of a is 7
The value of *aPtr is 7

Showing that * and & are complements of each other.


&*aPtr = 0012FF7C
*&aPtr = 0012FF7C

16.3 Linked List


For the user, linked list is visible as a linear data structure like an array. However,
unlike arrays elements in a linked list are not stored at contiguous locations; the
elements are linked using pointers. From the earlier section we know that a pointer
type variable contains only the address of a memory location where a value is stored.

Figure 16- 5 Linked list

As shown in Figure 16- 5, a linked list is a set of dynamically allocated nodes,


arranged in such a way that each node contains one value and one pointer. The pointer
always points to the next member of the list. The last node in the list has its pointer as
„NULL‟.

16.3.1 Advantages of using Linked Lists

Though arrays can be used to store linear data of similar types, but arrays have
following limitations.

172
1) The size of the arrays is fixed: So we must know the upper limit on the
number of elements in advance. Also, generally, the allocated memory is equal
to the upper limit irrespective of the usage. In a linked list there is no need to
define the total requirement of nodes required at the beginning. Nodes can be
added as and when needed.

2) Inserting a new element to an already filled array is not possible. In contrast


a linked list can add or delete nodes as required.

However, manipulation of a linked list is not as easy as manipulating an array. You


must think what you are going to achieve and how you are going to achieve before
coding it straight away.

16.3.2 Operations on linked lists


To use a linked list, we should define the operations we need. Few common
operations are: adding an item to the beginning or the end of the list, removing an
item similarly, traversing the list to find a given element etc. When writing programs
for these operations, the best way to start is to write the algorithm first or list down the
steps needed to carry out the task as given in the next section.

Add to the beginning of the list


To add to the beginning of the list,
 First, create a new item and set its value
 Link the new item to point to the head of the list
 Set the head of the list to be our new item

This will effectively create a new head to the list with a new value, and keep the rest
of the list linked to it.

A demonstration of adding a node to a linked list


//define node as pointer type
typedef struct node
{
int val;
struct node * next;
} listNode;

listNode * head = NULL;


head = malloc(sizeof(listNode));
if (head == NULL)
{
return 1;
}
head->val = 1;
head->next = NULL;

173
Traversing a list
Let us write a function that prints out all the items of a list. To do this, we need to
traverse the list from start to the end and also need to use a current pointer that will
keep track of the node we are currently printing.
That is,
1. Print the value of the first node
2. set the current pointer to the next node
3. print the value pointed by the current pointer and set the pointer to the following
node.
4. print again, and repeat the process until we reach the end of the list (the next node
is NULL).

void print_list(listNode * head)


{
listNode * current = head;

while (current != NULL)


{
printf("%d\n", current->val);
current = current->next;
}
}

Activity 16.1

Write a program to create linked list called myList and add 3 integer numbers.

If you master the art of declaring a linked list and traversing a linked list, then you can write
programs for any other operation to do with one. To understand how to define few more functions,
let us declare a list which has a key as well as a data part.

Finding length and removing first element from a list


When declaring the list, define a key and a value both in the „struct‟ for node as
shown in the program below.

To find the length of the list we will have to traverse the whole list counting the nodes.

When remove the first data element from the list we need to change the location of the
next node to be pointed by the head carefully as to not to lose the list.

174
A complete C program to do few operations on a list
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

struct node
{
int value;
int key;
struct node *next;
};

struct node *head = NULL;


struct node *current = NULL;

//insert a key and a value at the first location


void insertFirstNode(int key, int value)
{
struct node *link = (struct node*) malloc(sizeof(struct node)); //create a link
link->key = key;
link->value = value;
link->next = head; //point it to old first node
head = link; //point first to new first node
}

//display the list


void printList()
{
struct node *ptr = head;
printf("\n[ ");

while(ptr != NULL)
{
printf("(%d,%d) ",ptr->key,ptr->value);
ptr = ptr->next;
}
printf(" ]");
}

//delete first item


struct node* deleteFirstNode()
{
struct node *tempLink = head; //save reference to first link
head = head->next; //mark next to first link as first
return tempLink; //return the deleted link
}

//check if list is empty


bool isEmpty()
175
{
return head == NULL;
}

//find length of list


int lengthOfList()
{
int length = 0;
struct node *current;

for(current = head; current != NULL; current = current->next)


{
length++;
}
return length;
}

void main()
{
insertFirstNode(1,5);
insertFirstNode(2,10);
insertFirstNode(3,15);
insertFirstNode(4,100);
insertFirstNode(5,150);

printf("Original List: "); //print the created list


printList();

printf("Length of List: "); //print the created list


lengthOfList();

while(!isEmpty()) {
struct node *temp = deleteFirst();
printf("\nDeleted value:");
printf("(%d,%d) ",temp->key,temp->value);
}

printf("\nList after deleting all items: "); //print list after deleting all values
printList();

176
Activity 16.2

Write a program to search for „a‟ in a linked list which has values „d, e, c, a, h,i‟ .

Hint: To remove a specific item from the list, either by its position or by its value, we will need to go
over all the items, to find out whether we reached the node before the element that we wish to
remove. This is because we need to change the location to where the previous node points to as
well.

You can start by writing down the steps like following:


Iterate to the node before the node you wish to delete
Save the node you wish to delete in a temporary pointer
Set the previous node's next pointer to point to the node after the node you wish to delete
Delete the node using the temporary pointer

Summary

A pointer is a reference whose value refers to another value stored somewhere in the
computer memory. They do not store values directly like normal variables but stores a
reference of another value. Thus, a pointer contains the address of a data construct.

A linked list is a linear data structure that can be created with pointers. To manipulate
a linked list a special set of operations must be defined.

Learning Outcomes
After studying this session you should be able to,
 define Pointer data type in C
 declare, initialize and use pointers in programs
 declare a linked list and perform basic operations such as inserting, deleting
values, printing the list and finding the length

177

You might also like