Post on 02-Apr-2015
Factorial Preparatory Exercise#include <iostream>#include <fstream>#include <iomanip>using namespace std;
double fact(double);int fact(int);
int main(void) { const int n=20;
ofstream my_file("results.txt");
for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i)
<< setw(14) << fact(1.0*i) << endl; } return 0;}
int fact(int x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } return i;}
double fact(double x) { double fact=1; for (int j=1; j<=x; j++) { fact=fact*j; } return fact;}
x int x! double x!
0 1 11 1 12 2 23 6 64 24 245 120 1206 720 7207 5040 50408 40320 403209 362880 36288010 3628800 3.6288e+0611 39916800 3.99168e+0712 479001600 4.79002e+08
13 1932053504 6.22702e+0914 1278945280 8.71783e+1015 2004310016 1.30767e+1216 2004189184 2.09228e+1317 -288522240 3.55687e+1418 -898433024 6.40237e+1519 109641728 1.21645e+1720 -2102132736 2.4329e+18
Dissecting the C++ program
#include <iostream>#include <fstream>#include <iomanip>
using namespace std;
double fact(double);int fact(int);
int main(void) { . . . return 0;}
Include “standard C++ libraries”
• iostream - screen output / keyboard input• fstream - file input / output• iomanip - manipulate output [e.g. setw(n)]
“function prototypes”
• so we can use a function before it is defined• only needs types not variable names
namespace --> a collection of objects
cout , cin, endl, fstream, …
std
using namespace std;
• merges things in “std” into global/main namespace
• …thus avoid doing std::cout etc.
x, y, z, jnsp1
x, y, w, knsp2
. . .
cout << nsp1::x
cout << nsp2::x
Two namespaces --> x’s are different things
Example: fact(6)
ijint fact(int x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } return i;}
The integer factorial function
Dissecting …
const int n=20;
ofstream my_file("results.txt");
for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i)
<< setw(14) << fact(1.0*i) << endl; }
ofstream --> is a classmy_file --> is an object of “class ofstream”
Inside the main() function
- 1 Before loop
2 23 64 245 1206 720
1 1 End of 1st iterartion
Variable “x” inside function is LOCAL copy
although x = 200 now
the “i” in fact(i) is not affected
This variable “ i ” LOCAL.
i.e. the “ i ” in main() is hidden & unaffected
int fact(int x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } x = 200 ;
return i;}
The integer factorial function
Dissecting … function & argument
const int n=20;
ofstream my_file("results.txt");
for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i)
<< setw(14) << fact(1.0*i) << endl; }
Inside the main() function
Passing a reference
The integer factorial function
const int n=20;
ofstream my_file("results.txt");
for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i)
<< setw(14) << fact(1.0*i) << endl; }
Inside the main() function
The “&” makes a difference
Variable “x” inside function is now a local name for the “i” in fact(i)
So now i = 200 after fact(i) returns and the “for loop” in main() will finish early
Allows you to update a variable in main() from another function: e.g. variables of type “ofstream”
int fact(int& x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } x = 200 ;
return i;}
OOP: Classes & Objects
• AIM: to extend C++ by– Defining new types of variables
– New variables may be composed of several existing variables
– Also define actions that can be done on/with the variables
• class description of “new variable type” ; contains…– Data members the variables it is composed of: defines state
– Methods special functions that act on objects of the class
• object a particular variable of the class
objectsclassesthreevector v1 ;
complex z, w ;
double x
double y
double z
threevector
Schematic of a Class
Object 1
Object 2
class
methods
constructors()
accessors()
modifiers()
other()
datamembers
Object 3
print() + – *
threevector()constructors()
square()accessors()
setx()modifiers()
Creating / Initializing an object
• General syntax
class_type object ;
class_type object(initialization data) ;
• Examples using “threevector” objects
threevector v1 ;
v1
x y z0.0 0.0 0.0
threevector u(1.0,2.3,-0.2) ;
u
x y z1.0 2.3 –0.2
(invokes default constructor that in this case sets all components to zero)
(invokes Cartesian constructor)
set_im()
Classes - another example
complex number
complex(a,b)
pow(n) +
complex()
real() conj()
double re
double im
*
datamembers
methods
Using an object
• General syntax
• Examples using “complex number” objects
object.method() ;
result = object.method(arguments) ;
complex z ;z re im
0.0 0.0
complex w(3.0,4.0) ;
z = w.conj() ;
w re im
3.0 4.0
3.0 – 4.0
Using an object (2)
result = object.method(arguments) ;
z.set_im(0.0) ;
• Modifier methodz re im
3.0 – 2.00.0
• Access method
cout << “|w| = “ << w.modulus() << endl ;
|w| = 5.0
(screen output)
• Complex # arithmetic p re im
6.0 4.0complex p = z + w ;
complex q = p / w ;q re im
1.36 – 0.48
Class Definition — C++ Syntax
class complex { private: // Data members // Hidden methods public: // Constructors // Accessible methods
};
File “complex.h”
• Name of the class
Class Definition — C++ Syntax
File “complex.h”
class complex { private: double re, im ;
public: // Constructors & methods
};
• Data members
class complex { private: double re, im ;
public: complex(){...}
double modulus(){...}
complex operator+(complex z) {...} };
• Methods
complex w(3.0,4.0) ;
w re im
3.0 4.0
complex z ;
z re im
0.0 0.0
default constructor
Constructors
complex() { re = 0.0 ; im = 0.0 ; }
In “complex.h”
complex(double a, double b){ re = a ; im = b ;} ;
• They are methods with the same name as class
• What do they do? • Take care of initializing new
objects
• Return the object they create (no return type explicitly needed)
• Example usage;
Constructors — Overloading
In “complex.h”
// “Regular” Constructorcomplex(double a, double b) { ... }
// Polar Constructorcomplex(double r, double phi)
{ re = r * cos(phi) ; im = r * sin(phi) ; }
• Overloading…
Multiple methods with…
— distinguishable pattern of arguments
— same name
“Regular” Constructor
double double
Polar
double double
complex z2(1.0, 0.5) ; Error - Ambiguous
Constructors — Overloading
In “complex.h”
// “Regular” Constructorcomplex(double a, double b) { ... }
// Polar Constructorcomplex(double r, double phi, int dummy) { re = r * cos(phi) ; im = r * sin(phi) ; } ;
• Overloading…
Multiple methods with…
— distinguishable pattern of arguments
— same name
“Regular” Constructor
Polar
double double
double double int
complex z2(1.0, 0.5) ; Okay - regular
complex z3(1.0, 0.5, 0) ; Okay - polar
data member of objectinvoking method nothing returned
return type
Access & Modifier Methods
// Access method double modulus(){ return sqrt(re*re + im*im) ;}
In “complex.h”
// Modifier method void set_im(double i_new){ im = i_new ;}
complex w(3.0,4.0) ;
double r = w.modulus() ;
• Example usage;
complex z ;
w.set_im(-1.0) ;
z.set_im(2.5) ;
• Example usage;
Result r = 5.0
Result w = (3.0, -1.0) z = (0.0, 2.5)
4) Components of object sent into the method as an “argument” e.g. w
5) Can use a method within a method
3) Components of object invoking the method e.g. Z
1) return type NOT type of left hand operand (i.e. thing on left of + )
Operator overloading
• Want to be able to do
p = z + w ;
p = z.operator+(w);
• p = z + w is shorthand for
// Complex addition method complex operator+(complex c){ complex d( re + c.real() , im + c.imag() ) ; return d ; }
In “complex.h”
2) complex d temporary/local object for holding result
• Private access
Cannot be directly accessed from main program
• Public access
Private & Public
class complex { private: double re, im ;
public:
double real() { return re ; } ;
};
complex w(3.0,4.0) ;
cout << w.re << endl ;
Error - won’t compile!
cout << w.real() << endl ;
Okay
Why make Data Members Private?
• Can change internals design of class without affecting use in application
class complex { private: double r, phi ;
public:
double real() { return r*cos(phi) ; } ;
};
• e.g. complex class now stores polar coords
cout << w.real() << endl ;
Works SAME as before