Contents
Syntax in C or C++: ( typename ) expr
Alternate C++ syntax: typename ( expr )
Numeric types are also converted implicitly when needed, particularly when it's a "promotion":
| Implicit type conversion | Explicit type conversion |
|---|---|
int i=5; double x; x= i; |
double x=3.1415; int i; i= (int)x; // C style i= int(x); // C++ style |
Suppose in our bouncing ball program we had more than one ball to track.
We could use a vector or an array for x and another one for v.
We might want to simplify the main loop by making a separate MoveBall() function. The main loop in the code might look like this:
while(1) {
for (int i=0; i<n; i++) {
MoveBall(x[i], v[i], dt); // alters x, v (pass by ref.)
}
DrawAllBalls(x,v,n); // you can pass an array or vector
}
Algorithm outline:
Implementation:
// Print a line showing where balls are:
// at each position, check whether a ball is there,
// and print a '*' or ' ' depending
void DrawAllBalls( vector<double> & x, vector<double> & v, int n)
{
int icolumn; // column index
int iball; // ball index
char c; // character
for (icolumn=0; icolumn<80; icolumn++) {
c= ' '; // space in this column, unless we find a ball
// start of ball-search
for (iball=0; iball<n; iball++) {
if ( (int)(x[iball]) == icolumn ) {
c='*'; // found a ball
break; // early exit from ball-search loop
}
}
// end of ball-search
cout << c; // print ' ' or '*'
}
cout << '\n';
}
The previous algorithm had two nested loops: one over 80 columns, the other over n balls. The ball position check is done as many as 80*n times. Can we be more efficient? Yes, we can.
Algorithm outline:
Now have only nball loop iterations, not 80*nball.
// Print a line showing where balls are
void DrawAllBalls(vector<double>& x, vector<double>& v, int n)
{
string s;
s.resize(80,' '); // set to 80 spaces
int iball; // ball index
for (iball=0; iball<n; iball++) { // start of ball loop
int ix= (int)(x[iball]);
s[ix] = '*';
}
// end of ball loop
cout << s << '\n';
}
Sometimes you can find a more efficient algorithm in terms of CPU by doing something a little different. Often this involves using just a little more memory.
Suppose our bouncing balls had more parameters: two dimensions, radius, color, name of video game character, etc. Then the main loop might look like this:
while(1) {
for (int i=0; i<n; i++) {
MoveBall(x[i],y[i],u[i],v[i],r[i],color[i],name[i],dt);
}
DrawAllBalls(x,y,u,v,r,color,name);
}
It would be nice if it could look like this:
while(1) {
for (int i=0; i<n; i++) {
MoveBall( balls[i], dt );
}
DrawAllBalls( balls );
}
C and C++ let us define our own structures which collect data, possibly of different types, in contiguous memory locations.
| Declaration Syntax | Memory allocation |
|---|---|
struct MyBall_s {
double x;
double y;
double u;
double v;
double r;
int color;
char symbol;
};
struct MyBall_s ball;
|
Relative address contents 0 through 7 x 8 through 15 y 16 through 23 u 24 through 31 v 32 through 39 r 40 through 43 color 44 symbol Total size: 45 bytes |
void MoveBall( struct MyBall_s & ball, double dt )
{
ball.x= ball.u * dt;
ball.y= ball.v * dt;
Bounce(ball.x, ball.u);
Bounce(ball.x, ball.v);
}
void Bounce( double &x, double &v ) {
{
// bounce on wall at 79 or 0.
// Warning: explicit 79 is bad practice!
if ( (x>=79.0 && v>0) || (x<=0.0 && v<0) )
v= -v;
}
Modify bouncing ball to have
Class: further define specification, write algorithm. Instructor: code it, with class catching errors.