Download - Introduction to C++ Prof. David Tanzer [email protected] Copyright © 2003 All Rights Reserved
General Points about C++
• Widely available
• Standardized, highly portable
• Powerful abstractions
• Generates efficient code
• Strongly typed
• Less flexible than interpreter
Compilation Model
• Source code
• Header files
• Compiler
• Object code
• Libraries
• Linker
• Executable
Simple Program
#include <iostream.h>main(){ int x,y; cout << “enter x,y” << endl; cin >> x; cin >> y; cout << “average = “ << (x+y) / 2.0 << end;}
If-Then-Else
int x;
cin >> x;
if (x > 0)
{
cout << “positive input!” << endl;
cout << “value = “ << x;
} else
cout << “error: negative input!” << endl;
While Loop
// estimate the square root of n
int i = 0;
while (i*i < n)
i = i + 1;
cout << “square root is near” << i << endl;
For-Loop
// print the first 99 squares
int i;
for (i = 1; i < 100; i++)
{
cout << “i: “ << i;
cout << “squared: “ << i * i << endl;
}
Loops – General Form
• while (expression) statement;
• do statement while (expression);
• for (init; test; update) statement;
• x = y + z; // simple statement
• {x = 1; y = 2;} // compound statement
Expressions
• x + y, x – y, x * y, x / y, x % y
• x == y, x != y, x < y, x > y, x <= y, x >= y
• ~x, x & y, x | y, x ^ y
• x << nbits, x >> nbits
• !exp, exp && exp, exp || exp
• test_exp ? then_exp : else_exp
Break Statement
while (1)
{
cin >> nextval;
if (nextval< 0)
break;
process(nextval);
}
cout << “error: negative input” << endl;
Continue Statement
while (1)
{
cin >> nextval;
if (nextval< 0)
continue; // skip the bad input
process(nextval);
}
Functions
float avg(float x, float y){ cout << “computing the average...” << endl; return (x + y) / 2.0;}float avg4(float x, float y, float z, float w){ return avg(avg(x,y), avg(z,w));}
Local and Global Scopes
int x = 5;
int y = 6;
float funct(float arg) {
int y = 7; // shadows the global y
cout << x << endl; // prints 5, from global
cout << y << endl; // prints 7, from local
Argument Passing
void avg(float x, float y, float &z)
{ // x,y are passed by value; z by reference
z = (x + y) / 2;
}
...
float outval;
avg(1.3, 2.2, outval); // outval is modified
Function Overloading
float funct(int x) { ... return z;}
float funct(int x, int y) { ... return z;}
...
funct(20); // uses the first definition
funct(20,30);// uses the second
Type Conversion (casting)
int x = 55;
float y1 = (int) x; // explicit conversion
float y2 = x; // implicit conversion
float f = 3.4;
x = (int) f; // now x = 3
int* iptr = &x; // iptr = address of x
void* ptr = (void*) iptr; // typeless pointer
Structures
struct {float x; float y;} vec;
vec.x = 10.0;
vec.y = 20.0;
float mag = magnitude(vec);
struct {float x; float y;} vec2;
vec2 = vec;
Typedef
typedef double real;
real x = 1.1;
typedef struct {float x; float y;} vector;
vector v, w, x;
v = inputVector(“enter v”);
w = inputVector(“enter w”);
outputVector(addvector(v,w));
addvector -- implementation
vector addvector(vector v, vector w)
{
vector result;
result.x = v.x + w.x;
result.y = v.y + w.y;
return result;
}
Arrays
int x[10]; // create storage for 10 ints
x[0] = 111; x[1] = 555;
inputValues(x,10);
int sum = 0;
for (int i = 0; i < 10; i++)
sum = sum + x[i];
vector buffer[10];
Strings
char name[100];
name[0] = ‘A’; name[1] = ‘L’; name[2] = 0;
cout << “name = “ << name << endl;
cin >> “what’s your name?” >> name;
for (int i = 0; name[i] != 0; i++)
;
cout << “# of chars = “ << i << endl;
Pointers
int x;
int* y; // pointer to an integer
x = 5;
y = &x; // now y points to x
cout << “value = “ << *y; // prints 5
(*y)++; // increments x
Pointer Arithmetic
int stringlen(char* charbuf) // array converted to ptr{ int count = 0; while (*charbuf != 0) { charbuf++; count++; } return count;}
Arguments from the O.S.
int main(int argc, char** argv)
{
cout << “nargs = “ << argc << endl;
char* progname = argv[1];
int arg1 = atoi(argv[1]);
cout << “double the input = “ << 2 * arg1;
return 0; // tell the o.s. there was no err
}
Classes
• C-structure plus member functions
• Encapsulation
• Inheritance
• Polymorphism
• Access control
• Modular design
• Software reusability
Encapsulation
class vector { float x, y;public: vector(float xval, float yval) {x=xval; y=yval;} void vector scale(float scaleval) { x *= scaleval; y *= scaleval; }};vector v(10,20); // calls the constructorv.scale(5) // calls the encapsulated funct
Using Object Pointers
class vector { ... vector* scale(float scaleval); ...};vector* vector::scale(float scaleval) { return new vector(x*scaleval, y*scaleval);}vector* v = new vector(10,20);vector* w = v->scale(10);delete v;
A Class for Images
class image { int npoints; vector* points;public: image(File* datafile) { npoints = linecount(datafile); points = new vector[npoints]; for (i = 0; i < npoints; i++) points[i] = parseRow(i,datafile); } ~image() {delete points;}
Image Class Cont’d
void shift(float xoff, float yoff); void scale(float scaleval); void dump(char* outfname);}; // end class void image::shift(float xoff, float yoff){ for (i = 0; i < npoints; i++) points[i].shift(xoff,yoff); }
Using the Image Class
File* f = new File(“/home/dave/input.img”);
image* i = new image(f);
i->scale(3.4);
i->shift(1.3,7.7);
i->dump(“/home/dave/output.img”);
delete i;
Inheritance
• Create a new class which extends another
• Base class, derived class
• Derived inherits members of base
• Example: student is a person
• Derived class is more specific
• Hence may introduce special members
Application of Inheritance
• Want a class for images with a focus point
• Don’t want to disturb or complicate the existing image class
• Solution: derive a class from image
• Derived class will store the focus coords
• Which methods should be inherited?
• Which methods should be overriden?
Class for Images with Focus
class image2: public image {
float xfoc, yfoc;
public:
image2(File* datafile, int xf, int yf) :
xfoc (xf), yfoc (yf), image(datafile) {}
void scale(float scaleval); // reimplement
// we can inherit shift(xoff,yoff)
Overriding a Method
image2::scale(float scaleval)
{
for (int i = 0; i < npoints; i++) {
float deltaX = points[i].getx() – xfoc;
points[i].setx(xfoc + scaleval * deltaX);
... [similarly for Y]
}}
Polymorphism
• Function is polymorphic if the types of its arguments may vary
• Example: length of an array
• Polymorphic functions may be defined in terms of other polymorphic functions– nitems(matrix) := nrows(matrix)*ncols(matrix)
Virtual Functions
• For implementing polymorphism in C++ • Base class contains “virtual functions”
– Not implemented in the base class
– Implementation given in each derived class
• Calls to virtual functions are resolved at runtime• Higher-level polymorphic functions may be built
using calls to virtual functions
A Virtual Base Class
class num {
virtual num* scale(num* x) = 0;
num* power(int exponent) {
num* result = this;
for (int i = 1; i < exponent; i++)
result = result->scale(this);
return result; }
};
Realizations of the Virtual Class
class doubNum : public num {
double val;
public:
doubNum(double v) {val = v;}
num* scale(num* x) { //
doubNum* d = (doubNum*) x; // assumption
return new doubNum(d->val * val); }
Using the Number Class
doubNum* d = new doubNum(1.234);
doubNum* d_cubed = d->power(3);
complexNum* c = new complexNum(3,1.2);
complexNum* c_cubed = c->power(3);
// the SAME power code is executed for both
Extending an Intepreter
• C++ generates fast code• But lacks runtime flexibility of interpreter• Synthesis: write primitives in C++ and link
into interpreter• Writing the interface code is fairly tedious• SWIG can automatically generate:
– Interpreter interface code– Shadow classes