You are on page 1of 37

SENG1120/SENG6120

INTRODUCTION TO SOFTWARE
ENGINEERING 2
Lecturer:

Dr. Alexandre Mendes (Callaghan)


- room ES249 ES Building
- phone 4921 6172
- email alexandre.mendes@newcastle.edu.au

Lectures:
Tuesday 3 - 4 pm and Thursday 3 - 5 pm,
room NURSTH
Workshops in ES409 (five possible times).
Assignments:
2 assignments, deadlines in course outline.
LATE ASSIGNMENTS will lose 10% per day or part thereof.
Assessment:

Each of assignments is worth 15%.

Mid-semester exam is worth 20%.

Final exam is worth 50%.

Potential Workshop Times




Lab ES409 has been booked for the


following times:




Tue 5pm-7pm
Thu 11am-1pm
Thu 1pm-3pm
Fri 9am-11am
Fri 11am-1pm

Lab sessions are not compulsory, but


attendance is highly recommended.
Students who dont attend to the labs
and/or do not complete the tasks will NOT
lose marks.

TEXTBOOKS SENG1120/SENG6120


Data Structures & Other Objects Using


C++, 4th edition,Addison Wesley.
Michael Main & Walter Savitch.

This book is available at the Bookstore in


the Union Building.

Teaching Assistants


Three people have agreed to be


teaching assistants. They are:
Dr. Cristian Perfumo
Mr. Trent Houliston
Mr. David Bell

Laboratories commence in
week 2 of semester
 Register yourself in any lab
session


Communication


There are several means by which I


communicate with you:
Lectures you should attend every one
of them;
Laboratory classes you should attend
each of these as well;
Blackboard you should monitor the
course site regularly. On the site you will
find:
 The Course Outline
 Announcements
 Each weeks lecture slide, released week-byweek
 Assignments as they are released
 Any other materials I provide to assist you with
your studies

Programming Language


This course is taught using the


programming language C++
Your previous programming instruction was in
Java, so this represents a change of language

You can install public domain C++ on


your home computer. Options include:
Cygwin (www.cygwin.com) which
implements a Unix emulation environment
for Windows PCs.
Mac users can download the Mac OS X
Developer Tools from the Apple site. These
include the GNU compiler for C++
In ES409, we will use Cygwin and your
assignment must be Cygwin-compatible.

Development
Environment


Examples provided in class will


comply with GNU C++ and are
compiled using the compiler called
g++

All labs and assignments must be runnable in


gnu C++, which means, NONSTARDARD LIBRARIES SHOULD

NOT BE USED!!!!

Development
Environment
*** Assignments will be marked as per above.
If you use an IDE to do your work, ensure
that your submission is compatible with the
tools that will be used to mark it ***
 Computers in ES409 have cygwin and Visual
Studio installed. If you develop your code
using Visual Studio, NetBeans, Eclipse, Borland
C++, etc, just make sure it compiles and runs
under cygwin.
 This is VERY important. When marking, if your
code does not compile and runs, you will
likely lose 50% of the marks straightaway,
because we wont be able to test it.
 Plagiarism:


The University has a strict policy on copyright and


plagiarism (see the Course Outline which includes a
link to the Policy)

What is C++?
A programming language based on
the language C that was
developed by Dennis Richie in 1972.
 C++ was created by Bjarne
Stroustrup in 1979.
 C++ is not C. It includes modern
constructs that provide support for
object-oriented programming
techniques
 C++ had a big influence on James
Goslings development of the Java
programming language.


C++ and Java




C++:
Has as a major design priority
that the same C program should
run as fast when compiled with a
C as a C++ compiler
 So there is no run-time bounds
checking and no garbage collection

Is a compiled language for which


the compiler produces native
code
 Compiled programs are not portable,
and different parts of a program
compiled by different compilers may
not be compatible with each other

C++ and Java




Java:
Implements the most commonlyused C++ techniques when there
are multiple available in C++
Does not implement features that
were open to abuse in C++
Tries to prevent the execution of
incorrect programs
 By increasing error checking by the
compiler
 By having the Virtual Machine (VM)
throw exceptions for run-time faults

Comprises a bytecode compiler and


a VM, resulting in code that can run
on any platform for which a VM is
implemented

C++ and Java




Speed:
Initially, C++ programs ran much
faster than Java programs
Improvements in compiler and
virtual machine technology have
closed the gap
However, the absence of run-time
error checking should result in
equally well written C++ code
running faster than the equivalent
Java code

Some Differences


Some major differences between


C++ and Java are:
Java does automatic garbage collection.
This is not the case for C++, resulting
in the possibilities of memory leaks
and existence of pointers to nonexistent (or worse still not intended)
objects.
Java does array bound checking. C++
does not check array indexes by default,
and this has been used by hackers to
overwrite data values and code, and to
obtain data.
All Java variables are initialised on
creation (zero for primitive types and
null for object references). This is not
the case for C++. Additionally non
void functions are not checked to
ensure they return something.

Some Differences


Some major differences between


C++ and Java are:
Java provides support for multi
threading. C++ does not, though
library routines exist for many
platforms
Java provides an extensive standard
Application Programming Interface
(API). The C++ API is small, comprising
some I/O support, a complex numbers
package and the Standard Template
Library (STL) that provides support for
data structures, collections and generic
algorithms. Other C++ libraries are
not specified by a standard and are
vendor-specific in content and interface

Program Template


A simple C++ program is shown below:


#include <iostream>
using namespace std;
int main() {
cout << Hello << endl;
return 0;
}

The include directive in the first line tells


the compiler to insert code from another
file.

In this case the < > says the filename is a system


file
Use of would indicate a user-defined file
The # symbol indicates that this is a preprocessor directive
 The using directive is like an import in
Java. This directive makes the std classes

available (equivalent to the automatic


availability of java.lang.* in Java)
The standard output stream is cout. The
program directs the message followed by
an end-of-line character (or \n ) to
output
The return informs the OS that all went
well

Compiling & Running a


Program


To compile the previous program,


(assuming it is stored in a file
called test.cpp you would type:
g++ -o test test.cpp

Alternately a Makefile could be used


 make test or simply make, depending on
the Makefile

This would produce a file called


test.exe (in Windows) or
test.out (in Unix)
The program would be run in the
usual way
Though it may be necessary to
provide the path, e.g. ./test

Makefiles
A sample
is
provided on
Blackboard
Makefile

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=test.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=test
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
clean:
rm -rf *.o core

This can be used as is with the command


make after a simple edit that provides the
names of the input and output files
Or you could use it to make another program,
e.g. make add would compile the file add.cpp,
producing the object file add.o and the
program file add.exe
You could also produce only the object file
using make add.o

Note the use of labels. E.g. the command


make clean will remove any .o or core
files produced by previous activities

Primitive Types for C++:


Integers, Floating Point
Numbers & Booleans


Java provides 8 primitive types with


precise sets of possible values spanning all
platforms
C++ has many primitive types with ranges
dependent on the host architecture and
OS
Examples of C++ primitive types include:
The basic integer type int for which machine
representation can be 16, 32 or 64 bits,
dependent on host architecture. The keywords
short and long can be added to int, with
int never being shorter than a short int
(or short) or longer than a long int (or
long). long constants are indicated as, for
example 1000L.
 The modifiers signed and unsigned can also
be added to int and char, extending the range
of possible values in the case of unsigned int,
and forming an 8-bit byte in the case of signed
char

Primitive Types for C++:


Integers, Floating Point
Numbers & Booleans


Java provides 8 primitive types with


precise sets of possible values spanning all
platforms
C++ has many primitive types with ranges
dependent on the host architecture and
OS
Examples of C++ primitive types include:
The floating point types float and double. The
standard does not require constants for
negative and positive infinity as it does for Java
The boolean type is bool which has values true
or false. In old C++ the boolean types were
not specified, and zero was interpreted as false,
non-zero to true. Dodgy code like:
if (i != 0) being replaced by if(i) was the
result!

Primitive Types for C++:


Characters


C++ uses the char type to store


characters.
Most compilers use 8 bits and store
ASCII (c.f. Java, which stores 16-bit
Unicode)
A character constant is enclosed by
single quotes, e.g. a
There are many additional escape
sequences for unprintable characters,
quotes, backslashes, the bell, etc
The standard header file cctype
(#include <cctype>) provides routines
such as isupper, islower, isalpha,
toupper, tolower to determine or
change properties of characters

Software Development


Whether you are a student completing


exercises and assignments, or a software
engineer working on a major software
system, you development process should
include the following phases:

Task specification
Solution design
Implementation of the solution (coding)
Analysis of the solution
Testing and debugging
Maintenance and evolution
Obsolescence
plus continuous DOCUMENTATION

The phases may be performed together,


and sometimes in a different order.
Sometimes you will revisit phases and do
them again.
You are expected to practice these phases
through this course (and beyond)

Sample Problem
Let us use a simple problem to
demonstrate the stages:
 Given an interval set by the user
(e.g. -10, 40), display a table for
converting Celsius temperatures to
Fahrenheit as displayed below:


CONVERSIONS FROM -10.0 to 40.0C


Celsius

Fahrenheit

-10.0C

Display degrees

-9.0C

F in this column

after they

have been

computed

35.0C
36.0C
37.0C
38.0C
39.0C
40.0C

The algorithm


This is a set of instructions for solving the


problem
Typically expressed in pseudocode, a mixture of
English and program code

Designing the algorithm involves


decomposing the problem into sub-tasks
Then treating each sub-task as a problem that
can be broken into sub-tasks

Eventually the sub-tasks become trivial


enough to be easily coded

For example, our problem has the subtasks:


Input the temperature range from the user
Convert a temperature from degrees C to
degrees F
Print the lines of the conversion table

Pseudocode


The problem solution can be described as:


1. Perform tasks that open and set up the output device
(screen, file, etc.)
2. Input the temperature range from the user
3. Display the labels at the top of the table
4. For each line in the table (using variables celsius and
fahrenheit:
a. Set celsius appropriately for the new line
b. The variable fahrenheit = the result of
converting the celsius temperature
c. Print the temperatures together with labels on an
output line

Step 1 provides a good example of


functionality that could be provided using
pre-existing software, i.e. exercising code
reuse
It is common for C++ programmers to build
up collections of related functions to form
packages that are re-used in many programs

Component tasks should be performed by


functions that are truly separate from one
and other
So design of one function can be done
without concern for internal design of the
others
This approach is termed information hiding

Pre- and Post-Conditions








It is the most basic documentation for


interface definition.
When we define a function, we specify
how it performs its task
When we use a function, we are only
concerned with what it does
Documenting the what for a function
is done using pre and post conditions
A pre-condition states conditions that
must be true when the function is
called
Otherwise it is not guaranteed to perform
correctly

A post-condition states what will be


true when the function call has
completed.
Provided the pre-condition was satisfied and the
function is correctly designed and implemented

Example of Pre and Post


Conditions


For our temperature conversion problem we


could state the following:
double celsius_to_fahrenheit(double c);
// Precondition:

c is a celsius

// temperature that is not less than


// absolute zero (-273.15 degrees C)
// Postcondition: The return value is
// the input temperature c converted
// to Fahrenheit degrees

The characters // indicate that the rest of the line


is a comment
The brackets /* followed by */ are also valid

As a first step in designing any function you should


write out its signature (return type, name and
parameter list followed by a semi-colon), then the
pre and post conditions as comments
This may need modification if further development
shows it is insufficient or incorrect

The use of pre and post conditions is extremely


important in team situations
Because it forms a contract between the user of a
function and its writer

The STL and Standard


Namespace


C++ now has compiler requirements


defined in the ANSI/ISO C++ Standard
(American National Standards
Institute/International Organization for
Standardization)
Providing much better portability of C++
source code than was previously the case




This standard includes the STL


(Standard Template Library)
Library facilities can be used after an
include directive has been placed at the
top of the file using the facility
The items in the STL are identified
using names in the standard namespace
or std. Thus
using namespace std;

must follow the include directives

Declared Constants


Declared constants are defined


using the keyword const before the
declaration, e.g.
const double LOWEST_LIMIT = -273.15;

Note the convention that capital letters


are used for the constant names
The value of LOWEST_LIMIT can never
change during program execution


Sometimes code is more readable if


values are used in code, for example
return (9.0/5.0) * c + 32;

reads better than


const double FRACTION_PART = 9.0/5.0;
const int ADDED_PART = 32;

return FRACTION_PART * c + ADDED_PART;

Use your common sense in such


situations!

Checking Preconditions


In many situations it is desirable that the


running code can check that
preconditions hold on entry to a function
This is achieved using assert
If the precondition is not satisfied, a message
can be printed and the program halted, or some
other defined error action can be taken

The appropriate STL facilities must be


made available by
#include <cassert>

then the assertion can be made, e.g.


assert(c >= LOWEST_LIMIT);

After testing and debugging is complete,


assertions can be turned off by placing the
statement
#define NDEBUG

immediately before the programs include


directives

Feedback to the
Operating System


A programs main function should end


with a return statement that informs
the operating system of its exit state
The OS can then take further actions
based on the returned value, e.g. running a
subsequent application or displaying an
error dialogue

Typically the return value 0 (zero)


indicates successful execution
This is represented in cstdlib by the
constant EXIT_SUCCESS
For example:
#include <cstdlib>

return EXIT_SUCCESS;

Exception handling is provided in C++


(as in Java) and is typically used to
handle run-time errors

Testing & Debugging




Testing:
Involves running a program and
observing what it does
Only verifies program behaviour for the
particular input used
 The tester observes correctness of output,
and temporal program performance

Should be implemented in a systematic


and planned way


When choosing test data you


should:
Know what output a correct program
should produce for that data. This may
involve manual calculation.
Include inputs that are most likely to
cause errors

Test Data


Boundary values should be identified.


These are inputs that sit one step away
from a different kind of program
behaviour. E.g. for:
int time_check(int hour);
// Precondition: hour lies in the
// range 0 <= hour <= 23

boundary values are hour equals 0 and


hour equals 23
The boundary values 0, 1 and -1 are included in
many test data. In the case of time, other
possible values may be 11/12, 23/0, or 99/00
(Y2K)


Exercising code involves understanding the


way the program is implemented.
It is usual to also check a value between and
outside each end of the boundary values
Be sure that each line of your code is executed
at least once by your test data
If a section of code is sometimes skipped, be
sure that one or more test inputs causes the
skip to happen

Debugging


When test data reveals erroneous


output, the first step is to
understand why the bug happened.
Then correct the known error(s).
Finally re-run all the test cases.

DO NOT:
Change suspicious code just hoping
things will get better
Assume that even controlled
rectification will not change things that
previously worked properly
 It is a truism that it is more important when
performing maintenance to ensure that what
previously worked continues to work than it
is to ensure the new feature works properly.

Exception handling


Similar to Java, but not as flexible


due to the everything goes nature
of C++.
try {
// Try the program flow
}
catch(Argument)
{
// Catch the exception
}

You can catch any type in C++. It


will just depend on what you
throw.

Exception handling
#include <iostream>
using namespace std;
int main()
{
int StudentAge;
cout << Enter student age: ";
cin >> StudentAge;
try {
if(StudentAge < 0) throw;
cout << "\nStudent Age: " << StudentAge << endl;
}
catch(...)
{
cout << Student age is negative << endl;
return -1;
}
cout << "\n";
return 0;
}

Exception handling


Types of exception:
throw: generic exception; catch()
throw <type>: throws a type




throw 5; catch(int param)


throw error; catch(string param)
throw a; catch(char param)

Handling cin >> exceptions


if (cin.fail()) {throws;}
cin.clear() clears cin so the program
can continue.

Your first code




In collaboration with the person sitting beside you,


write a pseudo-code for the temperature
transformation problem. Include error checking
procedures.

All elements required for the task are included in


this lecture slides.

Think about the documentation

Pre- and post-conditions

A brief explanation about the variables and


constants

Any limitations

1.

Input the temperature range from the user and a


step for displaying intermediate values

2.

Perform all error checking procedures

3.

Display the labels at the top of the table

4.

For each line in the table (start, intermediate and


end temperature values), print the temperature in
Celsius, then calculate its equivalent in Fahrenheit
and print it.

5.

Ask the user if he/she wants to repeat the


operation.

You might also like