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.