c/c++ coursework module ian reid, trinity 2008ian/teaching/c++/c++lecturenotes.pdf · c/c++...

43
C/C++ Coursework Module Ian Reid, Trinity 2008 The course takes you through a series of exercises designed to familiarise you with design and imple- mentation issues in C++ programming. Objectives: Design and implementation of C++ programs. Functions, classes, recursion, inheritance, graphics, ... Structure: Exercises – learning by example (Software-lab), Mini-lectures (9am, and 12noon or 2pm) Discussions – design in small groups Project – 3D graphical computer game (maybe?) 1

Upload: phungkhanh

Post on 26-Aug-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

C/C++ Coursework Module

Ian Reid, Trinity 2008

The course takes you through a series of exercisesdesigned to familiarise you with design and imple-mentation issues in C++ programming.

Objectives:

Design and implementation of C++ programs.Functions, classes, recursion, inheritance, graphics,. . .

Structure:

Exercises – learning by example (Software-lab),Mini-lectures (9am, and 12noon or 2pm)Discussions – design in small groupsProject – 3D graphical computer game (maybe?)

1

References

• C/C++ course/lecture notes (IDR)

www.robots.ox.ac.uk/˜ian/Teaching/C++

• Lipmann and Lajoie (3rd edition)

• Stroustrup (3rd edition)

• Pohl

2

Introduction

Data structures

Programs

Algorithms

Procedural programming:design focuses on algorithmse.g. matlab, C, Pascal, Fortran

Object oriented programming:design focuses on data structurese.g. C++, Java

3

Interpreted language

Source code

Interpreter.m

• Interpreter: a program that reads source line byline and carries out the action specified by theline of code

• Interpreted language:

– good run-time error handling and identifica-tion

– rapid prototyping

– slow

– e.g matlab, various scripting languages

4

C/C++ compilation

Source code

.c, .C, .cc

Object files

.o

Executable

Linking

Compilation

Example:CC -c prog.C

CC -c main.C

CC prog.o main.o -o myprog

5

A simple program in matlab

%% function to compute sum from 1 to nfunction res = sum(n)

if (n <= 0)res = 0;

elseres = 0;for i=1:n

res = res + i;end

end

n = 0;n = input(’Enter number: ’);result = sum(n);printf(’The sum is %d\n’, result);

6

A simple program in C

#include <iostream.h>

// function to compute sum from 1 to nint sum(int n){

if (n <= 0) return 0;

int tot=0;for (int i=1; i<=n; i++) {

tot += i;}return tot;

}

int main(int argc, char * argv[]){

int n=0;cout << "Enter number: ";cin >> n;int result = sum(n);cout << "The sum is " << result << endl;exit(0);

}

Notes: function, arguments, main, control flow (for, if), input/output,compiler directives and standard libraries

7

Variables

A variable is associated with a memory location forstorage of program data which can be retrieved andpossibly modified during program execution.

C/C++ are strongly typed languages – the type of

variables must be declared before use

Choose variable name to be meaningful, without be-ing overly verbose, e.g.

counter, InputFile, window height

A variable declaration: e.g.int num = 0;

orint num(0);

8

Data types

Atomic types predefined in C/C++:

bool, char, short, int, long,

float, double

Examples:

’c’ 40 ’\n’ ’\0’ [char , 1 byte]18 077 0x18 -313 [int , 4 bytes]3.14159 3.5e+6 -1.0 [float , 4 bytes]

C++ provides mechanisms for building up compounddata structures; in particular classes and arrays

9

Classes

A class is a compound data structure which encap-sulates related data into a single data structure.

class Complex {

public:

double re, im;

};

Members are accessed using the . operator

Complex z, w1, w2;

...

cout << z.re << endl;

w1.re = 2.0 * w2.re;

w1.im = 2.0 * w2.im;

10

Arrays

An array is a data structure containing a numbered(indexed) collection of items of a single data type:

int a[10];

res = a[0] + a[1] + a[4];

Complex zarray[20];

cout << zarray[5].re << endl;

• First index is always 0

• The dimension must be a constant, and is fixedfor the lifetime of the variable

const int size = 3;

float x[size];

orfloat x[] = {0.0, 1.0, 2.0 };

11

Multi-dimensional arrays

e.g. double d[10][5];

has elements

d[0][0] . . . d[0][4]

... ...

d[9][0] . . . d[9][4]

Stored in the order of right-most index varying mostrapidly.

Note that C/C++ provides no inbuilt run-time check-ing of array bounds, so beware – at best the pro-gram will crash (with something like “Segmentationfault”), or worse, nonsense will result and be verydifficult to trace.

12

Methods

In C++ a class encapsulates related data and func-tions. A class member function is sometimes calleda method in the object-oriented programming liter-ature.

class Complex {public:

double re, im;

double Mag() {return sqrt(re * re + im * im);

}double Phase() {

return atan2(im, re);}

};

Methods are also accessed using the . operator

Complex z;...cout << "Magnitude=" << z.Mag() << endl;cout << "Phase=" << z.Phase() << endl;

13

Constructor

Whenever a variable is declared, space is allocatedfor it and it is possibly initialised.

In general this is done by a constructor

In C++ a user defined class can supply its own con-structor. The compiler can supply one by default,but it is useful (required) for automatic initialisationof data members, or if the class requires some dy-namic memory to be allocated.

The constructor is a function with the same nameas the class

Complex(double x=0.0, double y=0.0)

{ re = x; im = y; }

14

Data hiding / Encapsulation

In procedural programming we want the functionsto behave as black boxes with well defined inter-faces. Avoiding side-effects means that we can usethe functions as building blocks to create programs.

In object-oriented programming we take this furtherand a class becomes a black box data structure,which has a public interface to private data.

The outside program can only access the class throughits well defined interface, minimising side-effects.

15

Example

class Complex {public:

Complex(double x=0.0, double y=0.0) {re=x; im=y;

}double Re() { return re; }double Im() { return im; }

double Mag() {return sqrt(re * re + im * im);

}double Phase() {

return atan2(im, re);}

private:double re, im;

};

The outside program can only access the privatemembers through the public methods:

Complex z(2.0, 5.2);

cout << z.Re() << endl;

Re() is an accessor method.

16

Data hiding ctd

By encapsulating the representation of Complex inthis way, the internal representation could changeproviding the interface remains the same

For example, we could change the internal repre-sentation to polar coordinates

class Complex {public:

Complex(double x=0.0; doubley=0.0) {r = sqrt(x * x + y * y);theta = atan2(y,x);

}double Re() { return r * cos(theta); }double Im() { return r * sin(theta); }double Mag() { return r; }double Phase() { return theta; }

private:double r; // magnitudedouble theta; // phase

};

The interface of this class to the program remainsunchanged.

17

Functions and methods

You should know how to program a simple functionto take some values and return a result. We nowdiscuss a number of more advanced function con-cepts:

• Scope

• Function prototype

• Class scoping

• Function call implementation

• Pass-by-value vs pass-by-reference parameters

• Function overloading

• Operators and operator overloading

18

Scope

A variable declared outside all functions is global .It can be accessed by any function.

A variable declared inside a function is local to thefunction.

• It cannot be seen outside the function in whichit is declared.

• If there exists a global variable of the same namethen the local one takes precedence.

• It is redeclared/reallocated every time the func-tion is called, so it does not “remember” its valuefrom the last call.

• Function parameters are effectively local vari-ables.

19

Function prototype

The function prototype provides enough informa-tion to the compiler so that it can check that it isbeing called correctly.

.h file:

float exp(float x);

.cc file:

float exp(float x){

const float precision = 1.0e-6;float term=1.0, res=0.0;int i=0;while (fabs(term)>precision) {

res += term;i++;term = pow(x,i)/factorial(i);

}}

The implementation of the function exp is in the .cc

file, or even in a library somewhere.

The prototype encapsulates the function interfaceand hides the implementation details.

20

Class scoping

Class definitions can become cluttered with a lot ofcode if all methods are defined within them.

Alternatively the class definition can contain a func-tion prototype and the function declared elsewhere.

We need a way of indicating that a given functionimplementation belongs to a particular class. Thisis done using the class scoping operator ::

.h file:

class Complex {public:

double Mag();...

}

.cc file:

double Complex::Mag(){

return sqrt(re * re + im * im);}

21

Function call implementation

global variables

Memory

STACK

DATASEGMENT

SEGMENTCODE

machine code

...

activation record

parameter 1

parameter n

...

return value

return locationlocal variable 1

...

local variable m

...

22

Pass by value/reference

int main(){

int i=5, j=10;swap(i, j);cout << i << j << endl;

}

Pass by value

void swap(int a, int b){

int temp = a;a = b;b = temp;return;

}

Pass by reference

void swap(int& a, int& b){

int temp = a;a = b;b = temp;return;

}

...

return location

temp

location of i

location of j

...

a = value of i

b = value of j

return location

temp

23

Parameter passing: rules and conventions

The defaults in C/C++ are:

atomic types: pass-by-value (i.e. copy)classes: pass-by-value (i.e. copy)arrays: pass-by-reference (i.e. location)

Use pass-by-reference for an atomic type or a classif:

• modifications to the arguments must be preserved

• a large object must be passed – the time and

space costs to allocate and copy a large object onto the

stack are often too great for real applications

If using pass-by-reference for the latter and the datawill not change, then use the const keyword

• void func(int x)

• void func(int &x)

• void func(const int &x)

24

Function overloading

C++ allows several functions to share the same nameto allow for different argument types.

Example:

double x, y;

....

y = exp(x);

Complex w, z;

...

z = exp(w);

The two can be seen to be distinct names if we con-sider the argument types as part of the name. Thesame is true for class member functions.

25

Function overloading ctd

We can define exp for the Complex class as fol-lows:

#include <math.h>

Complex exp(Complex z)

{

r = exp(z.Re());

Complex zout(r * cos(z.Im()),

r * sin(z.Im());

return zout;

}

26

Operators/Expressions

Arithmetic+ * / -

%(mod)

<< >> (shift left, right)

Relational== !=

< > <= >=

Boolean&& || !

They can be combined with the usual rules of prece-dence

The precedence rules can be modified using roundbrackets ( )

27

Operator overloading

An operator in C++ is just a function treated spe-cially – i.e.

a + b

is equivalent to

operator+(a, b)

Operators can be overloaded in the same way asfunctions:

Complex operator+(Complex z1, Complex z2)

{

Complex zout(z1.Re() + z2.Re(),

z1.Im() + z2.Im());

return zout;

}

28

Operator overloading, ctd

Standard C/C++ does no checking on array boundsat run-time and this can result in catastrophic pro-gram crashes (one reason for the dreaded “Seg-mentation Fault” error is trying to access an arraybeyond its size).

We can overload the “[]” operator to create a specialarray class that does does bounds checking:

class MyArray {public:

...float operator[](int i) {

if (i<0 || i>=10) {std::cerr << "Access out of bounds\n";exit(1);

} else {return a[i];

}}...

private:float a[10];

};

MyArray x;

29

Advanced topics

• Inheritance

• Destructors

• Friend functions

• Templates

• Standard Template Library

• Recursive functions

• Lots of others not covered in this course...

30

Inheritance

C++ allows programmers to build hierarchies of classes.

An inherited or derived class is one which has allthe functionality of the its “parent”, but with someextra data or methods.

Example:

class GBall : public Ball {

...

void Draw();

}

A GBall is identical to a Ball (same data and meth-ods) with the addition of a method Draw which knowshow to render a Ball onto a graphical window.

31

Inheritance, ctd

Example

class TextWindow

backspace(), delete()clear()

data: cursor_x, cursor_ymethods:

class GraphicsWindow

background_colour

clear(), fill()

data:

Methods:

data:

methods:

width, heightposx, posyraise(), hide()

class Window

select(), iconify()

data:

Methods:

class InteractiveGraphicsWindow

MouseClick(),MouseDrag()

32

Destructor

When an object ceases to exist (activation record ispopped from the stack), the destructor is called.

Like the constructor, the destructor has a defaultwhich the compiler can supply (this is what we havedone throughout).

The destructor has the same name as the class pre-ceded by a ˜:

˜Complex()

Destructors are useful if memory has been dynam-ically allocated to the object (i.e. allocated at run-time). A destructor should ensure that this memoryis freed up to the program.

33

Recursion

Recursion is the programming analogue of induc-tion:

if

p(0) and p(n) ⇒ p(n + 1)

then

p(n) ∀n

Define a function in terms of:

• itself

• boundary conditions

For example:

Factorial: n! = n(n − 1)!, 0! = 1

34

Example: flood fill

Consider a function to change the colour of a con-stant colour region to a new colour:

const int SIZE=256;

Bitmap im[SIZE][SIZE];

void fill(int x, int y,int old_colour, int new_colour)

{if (x>=0 && x<SIZE && y>=0 && y<SIZE) {

if (im[y][x]==old_colour) {im[y][x] = new_colour;fill(x-1,y,old_colour,new_colour);fill(x+1,y,old_colour,new_colour);fill(x,y-1,old_colour,new_colour);fill(x,y+1,old_colour,new_colour);

}}return;

}

35

Templates

Templating is a mechanism in C++ to create classesin which one or more types are parameterised.

Recall our special array class, and suppose we wantedto store int s instead of float s.

class MyArray {public:

...float operator[](int i) {

if (i<0 || i>=10) {std::cerr << "Access out of bounds\n";return 0.0;

} else {return a[i];

}}...

private:float a[10];

};

36

Templates ctd

template <class Type>class MyArray {

public:...Type operator[](int i) {

if (i<0 || i>=10) {std::cerr << "Access out of bounds\n";return 0.0;

} else {return a[i];

}}...

private:Type a[10];

};

MyArray<int> x;MyArray<double> y;MyArray<Complex> z;

37

Templates ctd

or even...

template <class Type, int N>class MyArray {

public:...Type operator[](int i) {

if (i<0 || i>=N) {std::cerr << "Access out of bounds\n";return 0.0;

} else {return a[i];

}}...

private:Type a[N];

};

MyArray<int,10> x;MyArray<double,20> y;MyArray<Complex,5> z;

38

Standard Template Library (STL)

A number of data structures (container types ) andalgorithms that operate on them are so commonthat standard ways of representing and manipulat-ing them have been developed.

These comprise the Standard Template Library .

Supports:

• stack (FILO structure)

• list (efficient insertion and deletion of elements)

• vector (extendible array)

• etc

39

STL example

std::vector<Type> is an extendible array

• it can increase in size as the program needs itto

• it can be accessed just like an ordinary array(e.g. v[2] )

• it can tell you its current size (v.size() )

• you can add an item to the end without needingto know how big it is (v.push back(x) )

Example:

#include <vector>

int main() {std::vector<int> v;

for (i=0; i<20; i++) v.push_back(i);

for (i=0; i<v.size(); i++)std::cout << v[i] << std::endl;

}

40

STL example, ctd

To create a new STL vector of a size specified atrun-time:

int size;std::vector<Complex> z;

std::cin >> size;z.resize(size);

z[5] = Complex(2.0,3.0);...

or even

std::vector< std::vector<float> > twodim;int width, height;

twodim.resize(height);for (int i=0; i<height; i++)

twodim[i].resize(width);

twodim[2][3] = 10.0;...

41

Notes on style

Write code which makes the meaning of each oper-ation and each data structure clear.

• Use meaningful variable names

• Use comments to supplement the meaning

• Indent code for each block/loop

• Encapsulate groups of statements sensibly infunctions

• Encapsulate related data sensibly in data struc-tures

• Design top down

• Code bottom up

42

Project notes

The course takes you through a series of exercisesdesigned to familiarise you with design and imple-mentation issues in C++ programming. This shouldtake at most two and half to three days, possiblyless.

After this you then have a loose specification for a“labyrinth” 3D graphical computer game. You havethe remainder of the course to set about implement-ing and refining this.

Write down what you hope to achieve before youstart off

Design your data structures before you start coding

Don’t be afraid to discard old ideas in favour of newones during the life-cycle of the development, butkeep old versions

Discuss ideas with the demonstrators...43