C/C++ Coursework Module Ian Reid, Trinity 2008ian/Teaching/C++/c++lecturenotes.pdf · C/C++...
-
Upload
phungkhanh -
Category
Documents
-
view
222 -
download
0
Transcript of C/C++ Coursework Module Ian Reid, Trinity 2008ian/Teaching/C++/c++lecturenotes.pdf · C/C++...
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