c++ - Should I be attempting to return an array, or is there a better solution? -
a problem set people learning c++
write short program simulate ball being dropped off of tower. start, user should asked initial height of tower in meters. assume normal gravity (9.8 m/s2), , ball has no initial velocity. have program output height of ball above ground after 0, 1, 2, 3, 4, , 5 seconds. ball should not go underneath ground (height 0).
before starting c++ had reasonable, self taught, knowledge of java. looking @ problem seems ought split into
- input class
- output class
- calculations class
- physical constants class (recommended question setter)
- controller ('main') class
the input class ask user starting height, passed controller. controller give , number of seconds (5) calculations class, create array of results , return controller. controller hand array of results output class print them console.
i put actual code @ bottom, it's possibly not needed.
you can see problem, attempting return array. i'm not asking how round problem, there workaround here , here. i'm asking, is problem result of bad design? should program structured differently, performance, maintenance or style reasons, such not attempting return array object?
here code (which works apart trying return arrays);
main.cpp
/* * main class, call other classes , passes variables around */ #include <iostream> #include "dropsim.h" using namespace std; int main() { double height = getheight(); int seconds = 5; double* results = calculateresults(height, seconds); outputresults(results); return 0; }
getheight.cpp
/* * asks user height start experiment * si units */ #include <iostream> using namespace std; double getheight() { cout << "what height should experiment start at; "; double height; cin >> height; return height; }
calculateresults.cpp
/* * given initial height , physical constants, position of ball * calculated @ integer number seconds, beginning @ 0 */ #include "constants.h" #include <cmath> #include <iostream> using namespace std; double getposition(double height, double time); double* calculateresults(double height, int seconds) { double positions[seconds + 1]; for(int t = 0; t < seconds + 1; t++) { positions[t] = getposition(height, t); } return positions; } double getposition(double height, double time) { double position = height - 0.5*constants::gravity*pow(static_cast<double>(time), 2); if( position < 0) position = 0; //commented code testing //cout << position << endl; return position; }
outputresults.cpp
/* * takes array of results , prints them in appropriate format */ #include <iostream> #include <string> #include <sstream> using namespace std; void outputresults(double* results){ string outputtext = ""; //the commented code test output method //which working //double results1[] = {1,2,3,4,5}; //int numresults = sizeof(results1)/sizeof(results1[0]); int numresults = sizeof(results)/sizeof(results[0]); //cout << numresults; //= 0 ... oh for(int t = 0; t < numresults; t++) { ostringstream line; line << "after " << t << " seconds height of object " << results[t] << "\r"; outputtext.append(line.str()); } cout << outputtext; }
and couple of headers; dropsim.h
/* * dropsim.h */ #ifndef dropsim_h_ #define dropsim_h_ double getheight(); double* calculateresults(double height, int seconds); void outputresults(double* results); #endif /* dropsim_h_ */
constants.h
/* * contains physical constants relevant simulation. * si units */ #ifndef constants_h_ #define constants_h_ namespace constants { const double gravity(9.81); } #endif /* constants_h_ */
i you're over-engineering big solution little problem, answer specific question:
should program structured differently, performance, maintenance or style reasons, such not attempting return array object?
returning array-like object fine. doesn't mean returning array, nor mean allocating raw memory new
.
and it's not restricted return values either. when you're starting out c++, it's best forget has built-in arrays @ all. of time, should using either std::vector
or std::array
(or linear collection such std::deque
).
built-in arrays should viewed special-purpose item, included compatibility c, not everyday use.
it may, however, worth considering writing computation in same style algorithms in standard library. mean writing code receive iterator destination, , writing output wherever iterator designates.
i'd package height , time set of input parameters, , have function generates output based on those:
struct params { double height; int seconds; }; template <class outit> void calc_pos(params const &p, outit output) { (int i=0; i<p.seconds; i++) { *output = get_position(p.height, i); ++output; } }
this works more along rest of standard library:
std::vector<double> results; calc_pos(inputs, std::back_inserter(results));
you can go few steps further if like--the standard library has quite bit great deal of this. calc_pos
little more invoke function repeatedly successive values time. (for example) use std::iota
generate successive times, use std::transform
generate outputs:
std::vector<int> times(6); std::iota(times.begin(), times.end(), 0); std::vector<double> distances; std::transform(times.begin(), times.end(), compute_distance);
this computes distances
distance dropped after given period of time rather height above ground, given initial height, computing difference between 2 quite trivial:
double initial_height = 5; std::vector<double> heights; std::transform(distances.begin(), distances.end(), std::back_inserter(heights), [=](double v) { return max(initial_height-v, 0); });
at least now, doesn't attempt calculate ball bouncing when hits ground--it assumes ball stops when hits ground.
Comments
Post a Comment